Merge "[automerger skipped] Merge "Merge "Allow some slop on socket time values" into oreo-cts-dev am: 5bb4ad5d54" into oreo-mr1-cts-dev am: fed6186c74 -s ours" into pie-cts-dev
am: d731f01fe6 -s ours
Change-Id: Id0e8690ac47a935f0096d8decffc3986ffe23d90
diff --git a/Android.bp b/Android.bp
index c47c096..e57045f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -3,19 +3,15 @@
"NativeCode.bp",
]
-python_binary_host {
- name: "gen-annotated-java-files-bp",
- main: "annotations/generate_annotated_java_files.py",
- srcs: [
- "annotations/generate_annotated_java_files.py",
+genrule {
+ name: "notices-for-framework-stubs",
+ tool_files: [
+ "NOTICE",
+ "ojluni/NOTICE",
],
- version: {
- py2: {
- enabled: true,
- embedded_launcher: true,
- },
- py3: {
- enabled: false,
- },
- },
+ cmd: "cp -f $(location NOTICE) $(genDir)/NOTICES/libcore-NOTICE && cp -f $(location ojluni/NOTICE) $(genDir)/NOTICES/ojluni-NOTICE",
+ out: [
+ "NOTICES/libcore-NOTICE",
+ "NOTICES/ojluni-NOTICE",
+ ],
}
diff --git a/AndroidTest-core-tests.xml b/AndroidTest-core-tests.xml
new file mode 100644
index 0000000..8d8f7ae
--- /dev/null
+++ b/AndroidTest-core-tests.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<!-- This test config is placed here for use by atest to enable it to determine
+ which tests to run for core-tests.jar (only). It assumes that the majority
+ of tests for libcore are in the CtsLibcoreTestCases module and therefore
+ does not help for tests where that is not the case.
+
+ This file is effectively a copy of the real CtsLibcoreTestCases
+ AndroidTest.xml file and should track the content of that file.
+
+ TODO: b/114773808 to remove this copied config and execute core-tests.jar
+ directly.
+-->
+<configuration description="Config for Libcore test cases">
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/java.io.tmpdir" />
+ <option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/user.home" />
+ <option name="teardown-command" value="rm -rf /data/local/tmp/ctslibcore" />
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <!-- this has just the instrumentation which acts as the tests we want to run -->
+ <option name="test-file-name" value="CtsLibcoreTestCases.apk" />
+ </target_preparer>
+ <test class="com.android.compatibility.testtype.LibcoreTest" >
+ <option name="package" value="android.libcore.cts" />
+ <option name="instrumentation-arg" key="filter"
+ value="com.android.cts.core.runner.ExpectationBasedFilter" />
+ <option name="core-expectation" value="/knownfailures.txt" />
+ <option name="runtime-hint" value="45m"/>
+ <!-- 20x default timeout of 600sec -->
+ <option name="shell-timeout" value="12000000"/>
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+</configuration>
diff --git a/AndroidTest.xml b/AndroidTest.xml
deleted file mode 100644
index 78ed943..0000000
--- a/AndroidTest.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<configuration description="Config for libjavacore-benchmarks">
- <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
- <option name="cleanup" value="true" />
- <option name="push" value="libjavacore-benchmarks->/data/benchmarktest/libjavacore-benchmarks" />
- </target_preparer>
- <option name="test-suite-tag" value="apct" />
- <test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
- <option name="native-benchmark-device-path" value="/data/benchmarktest" />
- <option name="benchmark-module-name" value="libjavacore-benchmarks" />
- </test>
-</configuration>
diff --git a/Docs.mk b/Docs.mk
index 28abc8b..d448537 100644
--- a/Docs.mk
+++ b/Docs.mk
@@ -18,17 +18,6 @@
)
_icu_files := $(addprefix external/icu/, $(_icu_files))
-
-# Get list of targets annotated with annotations from jaif file
-# Remove un-annotated original source file and replace them with annotated targets
-#
-ojluni_annotate_src := $(patsubst libcore/ojluni/src/main/java/%,%, $(annotated_ojluni_files))
-ojluni_annotate_output := $(patsubst %,$(call intermediates-dir-for,JAVA_LIBRARIES,core-oj,,COMMON)/annotated/%, $(ojluni_annotate_src))
-_libcore_files := $(filter-out $(patsubst %, libcore/ojluni/src/main/java/%, $(ojluni_annotate_src)), $(_libcore_files))
-_libcore_generated_files := $(ojluni_annotate_output)
-ojluni_annotate_src:=
-ojluni_annotate_output:=
-
# List of libcore-related javadoc source files
#
# NOTE: Because libcore-related source spans modules (not just libcore!), files names here are
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index 378aca2..e88f8ea 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -16,26 +16,27 @@
// Definitions for building the Java library and associated tests.
//
-// libcore is divided into modules.
+// libcore has some sub-directories that follow a common structure:
+// e.g. dalvik, dom, harmony-tests, json, jsr166-tests, luni, libart, ojluni,
+// support, xml, xmlpull.
//
-// The structure of each module is:
+// The structure of these is generally:
//
// src/
// main/ # To be shipped on every device.
// java/ # Java source for library code.
-// native/ # C++ source for library code.
+// native/ # C/C++ source for library code.
// resources/ # Support files.
// test/ # Built only on demand, for testing.
// java/ # Java source for tests.
-// native/ # C++ source for tests (rare).
+// native/ # C/C++ source for tests (rare).
// resources/ # Support files.
//
-// All subdirectories are optional
+// All subdirectories are optional.
build = [
"openjdk_java_files.bp",
"non_openjdk_java_files.bp",
- "annotated_java_files.bp",
]
// The Java files and their associated resources.
@@ -44,6 +45,49 @@
"ojluni/src/main/resources/",
]
+// The source files that go into core-oj.
+filegroup {
+ name: "core_oj_java_files",
+ srcs: [":openjdk_java_files"],
+}
+
+// OpenJDK source is not annotated with @hide so we need a separate
+// filegroup for just the parts that contribute to the API.
+filegroup {
+ name: "core_oj_api_files",
+ srcs: [":openjdk_javadoc_files"],
+}
+
+// The source files that go into core-libart.
+filegroup {
+ name: "core_libart_java_files",
+ srcs: [
+ ":non_openjdk_java_files",
+ ":android_icu4j_src_files",
+ ],
+}
+
+// Some parts of libart are not annotated with @hide so we need a separate
+// filegroup for just the parts that contribute to the API.
+filegroup {
+ name: "core_libart_api_files",
+ srcs: [
+ ":non_openjdk_javadoc_files",
+ ":android_icu4j_src_files",
+ ],
+}
+
+// The set of files in core that have been marked up with @hide and API-related
+// annotations.
+filegroup {
+ name: "core_api_files",
+ srcs: [
+ ":core_oj_api_files",
+ ":core_libart_api_files",
+ ":core_simple_java_files",
+ ],
+}
+
java_defaults {
name: "libcore_java_defaults",
javacflags: [
@@ -51,10 +95,10 @@
//"-Xlint:-serial,-deprecation,-unchecked",
],
dxflags: ["--core-library"],
- no_standard_libs: true,
errorprone: {
javacflags: [
"-Xep:MissingOverride:OFF", // Ignore missing @Override.
+ "-Xep:ConstantOverflow:WARN", // Known constant overflow in SplittableRandom
],
},
}
@@ -68,15 +112,19 @@
defaults: ["libcore_java_defaults"],
srcs: [
- ":openjdk_java_files",
- ":non_openjdk_java_files",
- ":android_icu4j_src_files",
+ ":core_oj_java_files",
+ ":core_libart_java_files",
+ ":core_simple_java_files",
":openjdk_lambda_stub_files",
],
+
+ no_standard_libs: true,
+ system_modules: "none",
openjdk9: {
srcs: ["luni/src/module/java/module-info.java"],
javacflags: ["--patch-module=java.base=."],
},
+
java_resource_dirs: core_resource_dirs,
java_resources: [":android_icu4j_resources"],
@@ -85,8 +133,6 @@
"tzlookup.xml",
],
- system_modules: "none",
-
installable: false,
}
@@ -98,15 +144,19 @@
java_library {
name: "core-oj",
defaults: ["libcore_java_defaults"],
+ installable: true,
hostdex: true,
- srcs: [":openjdk_java_files"],
+ srcs: [":core_oj_java_files"],
java_resource_dirs: core_resource_dirs,
+
+ no_standard_libs: true,
libs: ["core-all"],
system_modules: "core-all-system-modules",
openjdk9: {
javacflags: ["--patch-module=java.base=."],
},
+
jacoco: {
exclude_filter: [
"java.lang.Class",
@@ -137,19 +187,19 @@
java_library {
name: "core-libart",
defaults: ["libcore_java_defaults"],
+ installable: true,
hostdex: true,
- srcs: [
- ":non_openjdk_java_files",
- ":android_icu4j_src_files",
- ],
+ srcs: [":core_libart_java_files"],
java_resources: [":android_icu4j_resources"],
+ no_standard_libs: true,
libs: ["core-all"],
system_modules: "core-all-system-modules",
openjdk9: {
javacflags: ["--patch-module=java.base=."],
},
+
jacoco: {
exclude_filter: [
"java.lang.DexCache",
@@ -168,6 +218,7 @@
// but these will not be stripped. See b/24535627.
java_library {
name: "core-oj-testdex",
+ installable: true,
static_libs: ["core-oj"],
no_standard_libs: true,
libs: ["core-all"],
@@ -185,6 +236,7 @@
java_library {
name: "core-libart-testdex",
+ installable: true,
static_libs: ["core-libart"],
no_standard_libs: true,
libs: ["core-all"],
@@ -211,6 +263,7 @@
":openjdk_lambda_duplicate_stub_files",
],
+ no_standard_libs: true,
libs: ["core-all"],
system_modules: "core-all-system-modules",
openjdk9: {
@@ -223,12 +276,16 @@
include_srcs: true,
}
+// The libraries that make up core.
java_system_modules {
name: "core-system-modules",
libs: [
"core-oj",
"core-libart",
- "core-lambda-stubs",
+ "core-simple",
+ // This one is not on device but it's needed when javac compiles code
+ // containing lambdas.
+ "core-lambda-stubs"
],
}
@@ -261,7 +318,7 @@
}
// Make the jsr166-tests library.
-java_library_static {
+java_test {
name: "jsr166-tests",
srcs: ["jsr166-tests/src/test/java/**/*.java"],
no_framework_libs: true,
@@ -270,52 +327,197 @@
],
}
-genrule {
- name: "gen-ojluni-jaif-annotated-srcs",
- tools: [
- "gen-annotated-java-files-bp",
- "soong_zip",
- ],
- tool_files: [
- ":insert-annotations-to-source",
- "annotations/ojluni.jaif",
- ],
+// Build a library just containing files from luni/src/test/filesystems for use in tests.
+java_library {
+ name: "filesystemstest",
+ compile_dex: true,
+ srcs: ["luni/src/test/filesystems/src/**/*.java"],
+ java_resource_dirs: ["luni/src/test/filesystems/resources"],
+ no_framework_libs: true,
+ errorprone: {
+ javacflags: ["-Xep:MissingOverride:OFF"],
+ },
+}
+
+// Build a library just containing files from luni/src/test/parameter_metadata for use in tests.
+java_library {
+ name: "parameter-metadata-test",
+ compile_dex: true,
+ srcs: ["luni/src/test/parameter_metadata/src/**/*.java"],
+ no_framework_libs: true,
+ javacflags: ["-parameters"],
+ errorprone: {
+ javacflags: ["-Xep:MissingOverride:OFF"],
+ },
+}
+
+// Make the core-tests library.
+java_test {
+ name: "core-tests",
+ defaults: ["libcore_java_defaults"],
+ hostdex: true,
+ no_framework_libs: true,
srcs: [
- ":annotated_ojluni_files",
+ "dalvik/src/test/java/**/*.java",
+ "dalvik/test-rules/src/test/java/**/*.java",
+ "dom/src/test/java/**/*.java",
+ "harmony-tests/src/test/java/**/*.java",
+ "json/src/test/java/**/*.java",
+ "luni/src/test/java/**/*.java",
+ "xml/src/test/java/**/*.java",
],
- cmd: "($(location gen-annotated-java-files-bp) $(location annotations/ojluni.jaif) > $(genDir)/annotated_java_files.bp.tmp) && " +
- "(diff -u `pwd`/libcore/annotated_java_files.bp $(genDir)/annotated_java_files.bp.tmp || " +
- "(echo -e \"********************\" >&2; " +
- " echo -e \"annotated_java_files.bp needs regenerating. Please run:\" >&2; " +
- " echo -e \"libcore/annotations/generate_annotated_java_files.py libcore/annotations/ojluni.jaif > libcore/annotated_java_files.bp\" >&2; " +
- " echo -e \"********************\" >&2; exit 1) ) && " +
- "(rm $(genDir)/annotated_java_files.bp.tmp) && " +
- "(external/annotation-tools/annotation-file-utilities/scripts/insert-annotations-to-source -d $(genDir) $(location annotations/ojluni.jaif) $(in)) && " +
- "($(location soong_zip) -o $(out) -C $(genDir) -D $(genDir))",
- out: [
- "ojluni_jaif_annotated_srcs.srcjar",
+ exclude_srcs: [
+ "luni/src/test/java/libcore/java/util/zip/Zip64Test.java",
+ "luni/src/test/java/libcore/java/util/zip/Zip64FileTest.java",
+ ],
+
+ java_resource_dirs: [
+ "*/src/test/java",
+ "*/src/test/resources",
+ ],
+ exclude_java_resource_dirs: [
+ "ojluni/src/test/java",
+ "ojluni/src/test/resources",
+ ],
+
+ java_resources: [
+ ":filesystemstest",
+ ":parameter-metadata-test",
+ ],
+
+ libs: [
+ "okhttp",
+ "bouncycastle",
+ ],
+ static_libs: [
+ "archive-patcher",
+ "core-test-rules",
+ "core-tests-support",
+ "junit-params",
+ "mockftpserver",
+ "mockito-target",
+ "mockwebserver",
+ "nist-pkix-tests",
+ "slf4j-jdk14",
+ "sqlite-jdbc",
+ "tzdata-testing",
+ ],
+
+ errorprone: {
+ javacflags: [
+ "-Xep:TryFailThrowable:ERROR",
+ "-Xep:ComparisonOutOfRange:ERROR",
+ ],
+ },
+
+ test_config: "AndroidTest-core-tests.xml",
+}
+
+// Make the core-ojtests library.
+java_test {
+ name: "core-ojtests",
+ defaults: ["libcore_java_defaults"],
+ hostdex: true,
+ no_framework_libs: true,
+
+ srcs: [
+ "ojluni/src/test/java/**/*.java",
+ ],
+ java_resource_dirs: [
+ "ojluni/src/test/java",
+ "ojluni/src/test/resources",
+ ],
+ libs: [
+ "okhttp",
+ "bouncycastle",
+ ],
+ static_libs: ["testng"],
+
+ // ojluni/src/test/java/util/stream/{bootlib,boottest}
+ // contains tests that are in packages from java.base;
+ // By default, OpenJDK 9's javac will only compile such
+ // code if it's declared to also be in java.base at
+ // compile time.
+ //
+ // For now, we use --patch-module to put all sources
+ // and dependencies from this make target into java.base;
+ // other source directories in this make target are in
+ // packages not from java.base; if this becomes a problem
+ // in future, this could be addressed eg. by splitting
+ // boot{lib,test} out into a separate make target,
+ // deleting those tests or moving them to a different
+ // package.
+ patch_module: "java.base",
+}
+
+// Make the core-ojtests-public library. Excludes any private API tests.
+java_test {
+ name: "core-ojtests-public",
+ defaults: ["libcore_java_defaults"],
+ no_framework_libs: true,
+ srcs: [
+ "ojluni/src/test/java/**/*.java",
+ ],
+ // Filter out the following:
+ // 1.) DeserializeMethodTest and SerializedLambdaTest, because they depends on stub classes
+ // and won't actually run, and
+ // 2.) util/stream/boot*. Those directories contain classes in the package java.util.stream;
+ // excluding them means we don't need patch_module: "java.base"
+ exclude_srcs: [
+ "**/DeserializeMethodTest.java",
+ "**/SerializedLambdaTest.java",
+ "ojluni/src/test/java/util/stream/boot*/**/*",
+ ],
+ java_resource_dirs: [
+ "ojluni/src/test/java",
+ "ojluni/src/test/resources",
+ // Include source code as part of JAR
+ "ojluni/src/test/dist",
+ ],
+ libs: [
+ "bouncycastle",
+ "okhttp",
+ "testng",
],
}
-droiddoc {
- name: "core-docs",
+// Make the annotated stubs in ojluni/annotations available to metalava:
+droiddoc_exported_dir {
+ name: "ojluni-annotated-sdk-stubs",
+ path: "ojluni/annotations/sdk",
+}
+
+// A file containing the list of tags that are "known" to us from the OpenJdk
+// source code and so should not cause an error or warning.
+filegroup {
+ name: "known-oj-tags",
srcs: [
- ":openjdk_javadoc_files",
- ":non_openjdk_javadoc_files",
- ":android_icu4j_src_files_for_docs",
- ":gen-ojluni-jaif-annotated-srcs",
- ],
- exclude_srcs: [
- ":annotated_ojluni_files",
- ],
- custom_template: "droiddoc-templates-sdk",
- hdf: [
- "android.whichdoc offline",
- ],
- knowntags: [
"known_oj_tags.txt",
],
- proofread_file: "core-docs-proofread.txt",
- todo_file: "core-docs-todo.html",
- args: "-offlinemode -title \"libcore\"",
+}
+
+// Stubs for the parts of the public SDK API provided by the core libraries.
+droidstubs {
+ name: "core-current-stubs-gen",
+ srcs: [":core_api_files"],
+ installable: false,
+ no_framework_libs: true,
+ args: " --exclude-annotations",
+}
+
+// A library containing the parts of the public SDK API provided by the core libraries.
+// Don't use this directly, use "sdk_version: core_current".
+java_library {
+ name: "core.current.stubs",
+ srcs: [":core-current-stubs-gen"],
+ errorprone: {
+ javacflags: [
+ "-Xep:MissingOverride:OFF",
+ ],
+ },
+ openjdk9: {
+ javacflags: ["--patch-module=java.base=."],
+ },
+ no_standard_libs: true,
+ system_modules: "none",
}
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index 81fb460..f5f9f70 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -13,399 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-#
-# Definitions for building the Java library and associated tests.
-#
-
-#
-# Common definitions for host and target.
-#
-
-# libcore is divided into modules.
-#
-# The structure of each module is:
-#
-# src/
-# main/ # To be shipped on every device.
-# java/ # Java source for library code.
-# native/ # C++ source for library code.
-# resources/ # Support files.
-# test/ # Built only on demand, for testing.
-# java/ # Java source for tests.
-# native/ # C++ source for tests (rare).
-# resources/ # Support files.
-#
-# All subdirectories are optional (hence the "2> /dev/null"s below).
-
-define all-test-java-files-under
-$(foreach dir,$(1),$(patsubst ./%,%,$(shell cd $(LOCAL_PATH) && (find $(dir)/src/test/java -name "*.java" 2> /dev/null) | grep -v -f java_tests_blacklist)))
-endef
-
-define all-core-resource-dirs
-$(shell cd $(LOCAL_PATH) && ls -d */src/$(1)/{java,resources} 2> /dev/null)
-endef
-
-# The Java files and their associated resources.
-core_resource_dirs := \
- luni/src/main/java \
- ojluni/src/main/resources/
-test_resource_dirs := $(filter-out ojluni/%,$(call all-core-resource-dirs,test))
-test_src_files := $(call all-test-java-files-under,dalvik dalvik/test-rules dom harmony-tests json luni xml)
-ojtest_src_files := $(call all-test-java-files-under,ojluni)
-ojtest_resource_dirs := $(filter ojluni/%,$(call all-core-resource-dirs,test))
-
-ifeq ($(EMMA_INSTRUMENT),true)
-ifneq ($(EMMA_INSTRUMENT_STATIC),true)
- nojcore_src_files += $(call all-java-files-under, ../external/emma/core ../external/emma/pregenerated)
- core_resource_dirs += ../external/emma/core/res ../external/emma/pregenerated/res
-endif
-endif
-
-local_javac_flags=-encoding UTF-8
-#local_javac_flags+=-Xlint:all -Xlint:-serial,-deprecation,-unchecked
-local_javac_flags+=-Xmaxwarns 9999999
-
-# For user / userdebug builds, strip the local variable table and the local variable
-# type table. This has no bearing on stack traces, but will leave less information
-# available via JDWP.
-#
-# TODO: Should this be conditioned on a PRODUCT_ flag or should we just turn this
-# on for all builds. Also, name of the flag TBD.
-ifneq (,$(PRODUCT_MINIMIZE_JAVA_DEBUG_INFO))
-ifneq (,$(filter userdebug user,$(TARGET_BUILD_VARIANT)))
-local_javac_flags+= -g:source,lines
-local_jack_flags+= -D jack.dex.debug.vars=false -D jack.dex.debug.vars.synthetic=false
-endif
-endif
-
-#
-# ICU4J related rules.
-#
-# We compile android_icu4j along with core-libart because we're implementing parts of core-libart
-# in terms of android_icu4j.
-android_icu4j_root := ../external/icu/android_icu4j/
-android_icu4j_src_files := $(call all-java-files-under,$(android_icu4j_root)/src/main/java)
-android_icu4j_resource_dirs := $(android_icu4j_root)/resources
-
-#
-# Build jaif-annotated source files for ojluni target .
-#
-ojluni_annotate_dir := $(call intermediates-dir-for,JAVA_LIBRARIES,core-oj,,COMMON)/annotated
-ojluni_annotate_target := $(ojluni_annotate_dir)/timestamp
-ojluni_annotate_jaif := $(LOCAL_PATH)/annotations/ojluni.jaif
-ojluni_annotate_input := $(annotated_ojluni_files)
-ojluni_annotate_output := $(patsubst $(LOCAL_PATH)/ojluni/src/main/java/%, $(ojluni_annotate_dir)/%, $(ojluni_annotate_input))
-
-$(ojluni_annotate_target): PRIVATE_ANNOTATE_TARGET := $(ojluni_annotate_target)
-$(ojluni_annotate_target): PRIVATE_ANNOTATE_DIR := $(ojluni_annotate_dir)
-$(ojluni_annotate_target): PRIVATE_ANNOTATE_JAIF := $(ojluni_annotate_jaif)
-$(ojluni_annotate_target): PRIVATE_ANNOTATE_INPUT := $(ojluni_annotate_input)
-$(ojluni_annotate_target): PRIVATE_ANNOTATE_GENERATE_CMD := $(LOCAL_PATH)/annotations/generate_annotated_java_files.py
-$(ojluni_annotate_target): PRIVATE_ANNOTATE_GENERATE_OUTPUT := $(LOCAL_PATH)/annotated_java_files.bp
-$(ojluni_annotate_target): PRIVATE_INSERT_ANNOTATIONS_TO_SOURCE := external/annotation-tools/annotation-file-utilities/scripts/insert-annotations-to-source
-
-# Diff output of _ojluni_annotate_generate_cmd with what we have, and if generate annotated source.
-$(ojluni_annotate_target): $(ojluni_annotate_input) $(ojluni_annotate_jaif)
- rm -rf $(PRIVATE_ANNOTATE_DIR)
- mkdir -p $(PRIVATE_ANNOTATE_DIR)
- $(PRIVATE_ANNOTATE_GENERATE_CMD) $(PRIVATE_ANNOTATE_JAIF) > $(PRIVATE_ANNOTATE_DIR)/annotated_java_files.bp.tmp
- diff -u $(PRIVATE_ANNOTATE_GENERATE_OUTPUT) $(PRIVATE_ANNOTATE_DIR)/annotated_java_files.bp.tmp || \
- (echo -e "********************" >&2; \
- echo -e "annotated_java_files.bp needs regenerating. Please run:" >&2; \
- echo -e "libcore/annotations/generate_annotated_java_files.py libcore/annotations/ojluni.jaif > libcore/annotated_java_files.bp" >&2; \
- echo -e "********************" >&2; exit 1)
- rm $(PRIVATE_ANNOTATE_DIR)/annotated_java_files.bp.tmp
- $(PRIVATE_INSERT_ANNOTATIONS_TO_SOURCE) -d $(PRIVATE_ANNOTATE_DIR) $(PRIVATE_ANNOTATE_JAIF) $(PRIVATE_ANNOTATE_INPUT)
- touch $@
-$(ojluni_annotate_target): .KATI_IMPLICIT_OUTPUTS := $(ojluni_annotate_output)
-
-ojluni_annotate_dir:=
-ojluni_annotate_target:=
-ojluni_annotate_jaif:=
-ojluni_annotate_input:=
-ojluni_annotate_output:=
-
-#
-# Build for the target (device).
-#
-ifeq ($(LIBCORE_SKIP_TESTS),)
-# Build a library just containing files from luni/src/test/filesystems for use in tests.
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-java-files-under, luni/src/test/filesystems/src)
-LOCAL_JAVA_RESOURCE_DIRS := luni/src/test/filesystems/resources
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_MODULE := filesystemstest
-LOCAL_JAVA_LIBRARIES := core-oj core-libart
-LOCAL_DEX_PREOPT := false
-LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
-include $(BUILD_JAVA_LIBRARY)
-
-filesystemstest_jar := $(intermediates)/$(LOCAL_MODULE).jar
-$(filesystemstest_jar): $(LOCAL_BUILT_MODULE)
- $(call copy-file-to-target)
-
-# Build a library just containing files from luni/src/test/parameter_metadata for use in tests.
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-java-files-under, luni/src/test/parameter_metadata/src)
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_MODULE := parameter-metadata-test
-LOCAL_JAVA_LIBRARIES := core-oj core-libart
-LOCAL_DEX_PREOPT := false
-LOCAL_JAVACFLAGS := -parameters
-LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
-include $(BUILD_JAVA_LIBRARY)
-
-parameter_metadata_test_jar := $(intermediates)/$(LOCAL_MODULE).jar
-$(parameter_metadata_test_jar): $(LOCAL_BUILT_MODULE)
- $(call copy-file-to-target)
-
-endif
-
-ifeq ($(LIBCORE_SKIP_TESTS),)
-# Make the core-tests library.
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(test_src_files)
-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 := $(filesystemstest_jar) $(parameter_metadata_test_jar)
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-oj core-libart okhttp bouncycastle
-LOCAL_STATIC_JAVA_LIBRARIES := \
- archive-patcher \
- core-test-rules \
- core-tests-support \
- junit-params \
- mockftpserver \
- mockito-target \
- mockwebserver \
- nist-pkix-tests \
- slf4j-jdk14 \
- sqlite-jdbc \
- tzdata-testing
-LOCAL_JAVACFLAGS := $(local_javac_flags)
-LOCAL_JACK_FLAGS := $(local_jack_flags)
-LOCAL_ERROR_PRONE_FLAGS := \
- -Xep:TryFailThrowable:ERROR \
- -Xep:ComparisonOutOfRange:ERROR \
- -Xep:MissingOverride:OFF
-LOCAL_MODULE := core-tests
-include $(BUILD_STATIC_JAVA_LIBRARY)
-endif
-
-# Make the core-ojtests library.
-ifeq ($(LIBCORE_SKIP_TESTS),)
- include $(CLEAR_VARS)
- LOCAL_JAVA_RESOURCE_DIRS := $(ojtest_resource_dirs)
- LOCAL_NO_STANDARD_LIBRARIES := true
- LOCAL_JAVA_LIBRARIES := core-oj core-libart okhttp bouncycastle
- LOCAL_STATIC_JAVA_LIBRARIES := testng
- LOCAL_JAVACFLAGS := $(local_javac_flags)
- LOCAL_JACK_FLAGS := $(local_jack_flags)
- LOCAL_DX_FLAGS := --core-library
- LOCAL_MODULE_TAGS := optional
- LOCAL_MODULE := core-ojtests
- # 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.
- LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
- include $(BUILD_JAVA_LIBRARY)
-endif
-
-# Make the core-ojtests-public library. Excludes any private API tests.
-ifeq ($(LIBCORE_SKIP_TESTS),)
- include $(CLEAR_VARS)
- # Filter out the following:
- # 1.) DeserializeMethodTest and SerializedLambdaTest, because they depends on stub classes
- # and won't actually run, and
- # 2.) util/stream/boot*. Those directories contain classes in the package java.util.stream;
- # excluding them means we don't need LOCAL_PATCH_MODULE := java.base
- LOCAL_SRC_FILES := $(filter-out %/DeserializeMethodTest.java %/SerializedLambdaTest.java ojluni/src/test/java/util/stream/boot%,$(ojtest_src_files))
- # Include source code as part of JAR
- LOCAL_JAVA_RESOURCE_DIRS := ojluni/src/test/dist $(ojtest_resource_dirs)
- LOCAL_NO_STANDARD_LIBRARIES := true
- LOCAL_JAVA_LIBRARIES := \
- bouncycastle \
- core-libart \
- core-oj \
- okhttp \
- testng
- LOCAL_JAVACFLAGS := $(local_javac_flags)
- LOCAL_JACK_FLAGS := $(local_jack_flags)
- LOCAL_DX_FLAGS := --core-library
- LOCAL_MODULE_TAGS := optional
- LOCAL_MODULE := core-ojtests-public
- # 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.
- LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
- include $(BUILD_JAVA_LIBRARY)
-endif
-
-#
-# Build for the host.
-#
-
-ifeq ($(HOST_OS),linux)
-
-# Make the core-tests-hostdex library.
-ifeq ($(LIBCORE_SKIP_TESTS),)
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES := $(test_src_files)
- LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
- LOCAL_NO_STANDARD_LIBRARIES := true
- LOCAL_JAVA_LIBRARIES := \
- bouncycastle-hostdex \
- core-libart-hostdex \
- core-oj-hostdex \
- core-tests-support-hostdex \
- junit-hostdex \
- mockito-api-hostdex \
- okhttp-hostdex
- LOCAL_STATIC_JAVA_LIBRARIES := \
- archive-patcher-hostdex \
- core-test-rules-hostdex \
- junit-params-hostdex \
- mockftpserver-hostdex \
- mockwebserver-host \
- nist-pkix-tests-host \
- slf4j-jdk14-hostdex \
- sqlite-jdbc-host \
- tzdata-testing-hostdex
- LOCAL_JAVACFLAGS := $(local_javac_flags)
- LOCAL_MODULE_TAGS := optional
- LOCAL_MODULE := core-tests-hostdex
- LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
- include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
-endif
-
-# Make the core-ojtests-hostdex library.
-ifeq ($(LIBCORE_SKIP_TESTS),)
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES := $(ojtest_src_files)
- LOCAL_NO_STANDARD_LIBRARIES := true
- LOCAL_JAVA_LIBRARIES := \
- bouncycastle-hostdex \
- core-libart-hostdex \
- core-oj-hostdex \
- okhttp-hostdex
- LOCAL_STATIC_JAVA_LIBRARIES := testng-hostdex
- LOCAL_JAVACFLAGS := $(local_javac_flags)
- LOCAL_DX_FLAGS := --core-library
- LOCAL_MODULE_TAGS := optional
- LOCAL_MODULE := core-ojtests-hostdex
- # ojluni/src/test/java/util/stream/{bootlib,boottest}
- # contains tests that are in packages from java.base;
- # By default, OpenJDK 9's javac will only compile such
- # code if it's declared to also be in java.base at
- # compile time.
- #
- # For now, we use --patch-module to put all sources
- # and dependencies from this make target into java.base;
- # other source directories in this make target are in
- # packages not from java.base; if this becomes a proble
- # in future, this could be addressed eg. by splitting
- # boot{lib,test} out into a separate make target,
- # deleting those tests or moving them to a different
- # package.
- LOCAL_PATCH_MODULE := java.base
- LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
- include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
-endif
-
-endif # HOST_OS == linux
-
-#
-# Local droiddoc for faster libcore testing
-#
-#
-# Run with:
-# mm -j32 libcore-docs
-#
-# Main output:
-# ../out/target/common/docs/libcore/reference/packages.html
-#
-# All text for proofreading (or running tools over):
-# ../out/target/common/docs/libcore-proofread.txt
-#
-# TODO list of missing javadoc, etc:
-# ../out/target/common/docs/libcore-docs-todo.html
-#
-# Rerun:
-# rm -rf ../out/target/common/docs/libcore-timestamp && mm -j32 libcore-docs
-#
-include $(CLEAR_VARS)
-
-# for shared defintion of libcore_to_document
-include $(LOCAL_PATH)/Docs.mk
-
-# The libcore_to_document paths are relative to $(TOPDIR). We are in libcore so we must prepend
-# ../ to make LOCAL_SRC_FILES relative to $(LOCAL_PATH).
-LOCAL_SRC_FILES := $(addprefix ../, $(libcore_to_document))
-LOCAL_INTERMEDIATE_SOURCES := \
- $(patsubst $(TARGET_OUT_COMMON_INTERMEDIATES)/%,%,$(libcore_to_document_generated))
-LOCAL_ADDITIONAL_DEPENDENCIES := $(libcore_to_document_generated)
-# rerun doc generation without recompiling the java
-LOCAL_JAVACFLAGS := $(local_javac_flags)
-LOCAL_MODULE_CLASS:=JAVA_LIBRARIES
-
-LOCAL_MODULE := libcore
-
-LOCAL_DROIDDOC_OPTIONS := \
- -offlinemode \
- -title "libcore" \
- -proofread $(OUT_DOCS)/$(LOCAL_MODULE)-proofread.txt \
- -todo ../$(LOCAL_MODULE)-docs-todo.html \
- -knowntags ./libcore/known_oj_tags.txt \
- -hdf android.whichdoc offline
-
-LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=external/doclava/res/assets/templates-sdk
-
-include $(BUILD_DROIDDOC)
-
-# For unbundled build we'll use the prebuilt jar from prebuilts/sdk.
-ifeq (,$(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)))
-
-# Generate the stub source files for core.current.stubs
-# =====================================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(addprefix ../, $(libcore_to_document))
-LOCAL_GENERATED_SOURCES := $(libcore_to_document_generated)
-
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-
-LOCAL_DROIDDOC_OPTIONS:= \
- -stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/core.current.stubs_intermediates/src \
- -nodocs \
-
-LOCAL_UNINSTALLABLE_MODULE := true
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_MODULE := core-current-stubs-gen
-
-include $(BUILD_DROIDDOC)
-
-# Remember the target that will trigger the code generation.
-core_current_gen_stamp := $(full_target)
-
-# Build the core.current.stubs library
-# ====================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := core.current.stubs
-
-LOCAL_SOURCE_FILES_ALL_GENERATED := true
-
-# Make sure to run droiddoc first to generate the stub source files.
-LOCAL_ADDITIONAL_DEPENDENCIES := $(core_current_gen_stamp)
-core_current_gen_stamp :=
-
-# Because javac refuses to compile these stubs with --system=none, ( http://b/72206056#comment31 ),
-# just patch them into java.base at compile time.
-LOCAL_PATCH_MODULE := java.base
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
# Archive a copy of the classes.jar in SDK build.
+full_classes_jar := $(call intermediates-dir-for,JAVA_LIBRARIES,core.current.stubs,,COMMON)/classes.jar
$(call dist-for-goals,sdk win_sdk,$(full_classes_jar):core.current.stubs.jar)
-
-endif # not TARGET_BUILD_APPS not TARGET_BUILD_PDK=true
diff --git a/NativeCode.bp b/NativeCode.bp
index 3780e7d..840b19a 100644
--- a/NativeCode.bp
+++ b/NativeCode.bp
@@ -21,7 +21,6 @@
cc_defaults {
name: "core_native_default_flags",
host_supported: true,
- local_include_dirs: ["include"],
cflags: [
"-Wall",
"-Wextra",
@@ -39,11 +38,11 @@
cc_defaults {
name: "core_native_default_libs",
static_libs: [
- "libbase",
"libfdlibm",
],
shared_libs: [
+ "libbase",
"liblog",
"libnativehelper",
],
@@ -61,6 +60,7 @@
],
shared_libs: [
+ "libbase",
"libcrypto",
"libexpat",
"libicuuc",
@@ -70,7 +70,6 @@
],
static_libs: [
"libziparchive",
- "libbase",
],
target: {
android: {
diff --git a/OWNERS b/OWNERS
index 91f818d..c6b3546 100644
--- a/OWNERS
+++ b/OWNERS
@@ -4,15 +4,15 @@
# People who can approve changes for submission; don't send review emails to them
# unless you know what you're doing.
flooey@google.com
-jsauer@google.com
narayan@google.com
nfuller@google.com
paulduffin@google.com
peteg@google.com
-pszczepaniak@google.com
+prb@google.com
tobiast@google.com
vichang@google.com
# Don't send these folks any review emails for this project.
ngeoffray@google.com
sehr@google.com
+vmarko@google.com
diff --git a/annotated_java_files.bp b/annotated_java_files.bp
deleted file mode 100644
index 77a2c6e..0000000
--- a/annotated_java_files.bp
+++ /dev/null
@@ -1,49 +0,0 @@
-// Do not edit; generated using libcore/annotations/generate_annotated_java_files.py
-filegroup {
- name: "annotated_ojluni_files",
- export_to_make_var: "annotated_ojluni_files",
- srcs: [
- "ojluni/src/main/java/java/io/PrintWriter.java",
- "ojluni/src/main/java/java/lang/Appendable.java",
- "ojluni/src/main/java/java/lang/Boolean.java",
- "ojluni/src/main/java/java/lang/Byte.java",
- "ojluni/src/main/java/java/lang/CharSequence.java",
- "ojluni/src/main/java/java/lang/Character.java",
- "ojluni/src/main/java/java/lang/Class.java",
- "ojluni/src/main/java/java/lang/Double.java",
- "ojluni/src/main/java/java/lang/Enum.java",
- "ojluni/src/main/java/java/lang/Float.java",
- "ojluni/src/main/java/java/lang/Integer.java",
- "ojluni/src/main/java/java/lang/Iterable.java",
- "ojluni/src/main/java/java/lang/Long.java",
- "ojluni/src/main/java/java/lang/Object.java",
- "ojluni/src/main/java/java/lang/String.java",
- "ojluni/src/main/java/java/lang/StringBuffer.java",
- "ojluni/src/main/java/java/lang/StringBuilder.java",
- "ojluni/src/main/java/java/lang/System.java",
- "ojluni/src/main/java/java/lang/Thread.java",
- "ojluni/src/main/java/java/lang/ThreadLocal.java",
- "ojluni/src/main/java/java/lang/reflect/AccessibleObject.java",
- "ojluni/src/main/java/java/lang/reflect/AnnotatedElement.java",
- "ojluni/src/main/java/java/lang/reflect/Array.java",
- "ojluni/src/main/java/java/lang/reflect/Constructor.java",
- "ojluni/src/main/java/java/lang/reflect/Executable.java",
- "ojluni/src/main/java/java/lang/reflect/Field.java",
- "ojluni/src/main/java/java/lang/reflect/GenericArrayType.java",
- "ojluni/src/main/java/java/lang/reflect/GenericDeclaration.java",
- "ojluni/src/main/java/java/lang/reflect/Member.java",
- "ojluni/src/main/java/java/lang/reflect/Method.java",
- "ojluni/src/main/java/java/lang/reflect/Parameter.java",
- "ojluni/src/main/java/java/lang/reflect/ParameterizedType.java",
- "ojluni/src/main/java/java/lang/reflect/Proxy.java",
- "ojluni/src/main/java/java/lang/reflect/Type.java",
- "ojluni/src/main/java/java/lang/reflect/TypeVariable.java",
- "ojluni/src/main/java/java/lang/reflect/WildcardType.java",
- "ojluni/src/main/java/java/util/ArrayList.java",
- "ojluni/src/main/java/java/util/HashMap.java",
- "ojluni/src/main/java/java/util/Iterator.java",
- "ojluni/src/main/java/java/util/List.java",
- "ojluni/src/main/java/java/util/Map.java",
- "ojluni/src/main/java/java/util/Set.java",
- ],
-}
diff --git a/annotations/generate_annotated_java_files.py b/annotations/generate_annotated_java_files.py
deleted file mode 100755
index 2f12eea..0000000
--- a/annotations/generate_annotated_java_files.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env python
-
-"""Generate annotated_java_files.bp from a jaif file."""
-import os
-
-PACKAGE_STRING = 'package '
-CLASS_STRING = 'class '
-SRC_PREFIX = 'ojluni/src/main/java/'
-
-BP_TEMPLATE = '''filegroup {
- name: "annotated_ojluni_files",
- export_to_make_var: "annotated_ojluni_files",
- srcs: [
-%s
- ],
-}'''
-
-srcs_list = set()
-current_package = None
-with open(os.sys.argv[1], 'r') as jaif_file:
- for line in jaif_file:
- if line.startswith(PACKAGE_STRING):
- current_package = line[len(PACKAGE_STRING): line.find(':')]
- if line.startswith(CLASS_STRING) and current_package is not None:
- current_class = line[len(CLASS_STRING): line.find(':')]
-
- # In case of nested classes, discard substring after nested class name separator
- nested_class_separator_index = current_class.find('$')
- if nested_class_separator_index != -1:
- current_class = current_class[:nested_class_separator_index]
-
- srcs_list.add(SRC_PREFIX + current_package.replace('.', '/') + '/' + current_class + '.java')
-
-print '// Do not edit; generated using libcore/annotations/generate_annotated_java_files.py'
-print BP_TEMPLATE % ('\n'.join([' "' + src_entry + '",' for src_entry in sorted(srcs_list)]),)
-os.sys.exit(0)
diff --git a/annotations/ojluni.jaif b/annotations/ojluni.jaif
deleted file mode 100644
index a0bdabe..0000000
--- a/annotations/ojluni.jaif
+++ /dev/null
@@ -1,2862 +0,0 @@
-//
-// 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.
-
-// This file specifies additional annotations that are applied to libcore
-// code before generating android stubs and documentation. This data
-// is human-maintained and is based on jdk annotations shipped in Android
-// Studio.
-
-// If this file is changed, please update libcore/annotated_java_files.bp file by running:
-// libcore/annotations/generate_annotated_java_files.py libcore/annotations/ojluni.jaif > libcore/annotated_java_files.bp
-//
-// For arrray syntax, please see https://checkerframework.org/jsr308/specification/java-annotation-design.html#array-syntax
-// @Nullable String @NonNull[] <- Non-null array of nullable strings can be expressed as:
-//
-// type: @libcore.util.NonNull
-// inner-type 0, 0: @libcore.util.Nullable
-
-package libcore.util:
-annotation @NonNull: @java.lang.annotation.Retention(value=SOURCE) @java.lang.annotation.Target(value={TYPE_USE})
- int from
- int to
-annotation @Nullable: @java.lang.annotation.Retention(value=SOURCE) @java.lang.annotation.Target(value={TYPE_USE})
- int from
- int to
-annotation @NullFromTypeParam: @java.lang.annotation.Retention(value=SOURCE) @java.lang.annotation.Target(value={TYPE_USE})
- int from
- int to
-
-package java.io:
-class PrintWriter:
-
- method <init>(Ljava/io/Writer;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method <init>(Ljava/io/Writer;Z)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method <init>(Ljava/io/OutputStream;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method <init>(Ljava/io/OutputStream;Z)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method <init>(Ljava/lang/String;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method <init>(Ljava/nio/charset/Charset;Ljava/io/File;)V:
- return:
-
- method <init>(Ljava/lang/String;Ljava/lang/String;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.NonNull
-
- method <init>(Ljava/io/File;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method <init>(Ljava/io/File;Ljava/lang/String;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.NonNull
-
- method write([CII)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method write([C)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method write(Ljava/lang/String;II)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method write(Ljava/lang/String;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method print([C)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method print(Ljava/lang/String;)V:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method print(Ljava/lang/Object;)V:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method println(Ljava/lang/String;)V:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method println(Ljava/lang/Object;)V:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method printf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintWriter;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
-
- method printf(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintWriter;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.Nullable
- parameter #1:
- type: @libcore.util.NonNull
- parameter #2:
- type: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
-
- method format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintWriter;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
-
- method format(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintWriter;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.Nullable
- parameter #1:
- type: @libcore.util.NonNull
- parameter #2:
- type: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
-
- method append(Ljava/lang/CharSequence;)Ljava/io/PrintWriter;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.Nullable
-
- method append(Ljava/lang/CharSequence;II)Ljava/io/PrintWriter;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.Nullable
-
- method append(C)Ljava/io/PrintWriter;:
- return: @libcore.util.NonNull
-
- method append(C)Ljava/io/Writer;:
- return: @libcore.util.NonNull
-
- method append(Ljava/lang/CharSequence;II)Ljava/io/Writer;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.Nullable
-
- method append(Ljava/lang/CharSequence;)Ljava/io/Writer;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.Nullable
-
- method append(C)Ljava/lang/Appendable;:
- return: @libcore.util.NonNull
-
- method append(Ljava/lang/CharSequence;II)Ljava/lang/Appendable;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.Nullable
-
- method append(Ljava/lang/CharSequence;)Ljava/lang/Appendable;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.Nullable
-
-package java.lang:
-class Appendable:
- method append(Ljava/lang/CharSequence;)Ljava/lang/Appendable;:
- parameter #0:
- type: @libcore.util.Nullable
- // Is expected to return self
- return: @libcore.util.NonNull
-
- method append(Ljava/lang/CharSequence;II)Ljava/lang/Appendable;:
- parameter #0:
- type: @libcore.util.Nullable
- // Is expected to return self
- return: @libcore.util.NonNull
-
- method append(C)Ljava/lang/Appendable;:
- // Is expected to return self
- return: @libcore.util.NonNull
-
-class Boolean:
- method <init>(Ljava/lang/String;)V:
- // In contrast to other type classes, doesn't NPE on null, but sets value to false
- parameter #0:
- type: @libcore.util.Nullable
-
- method parseBoolean(Ljava/lang/String;)Z:
- // In contrast to other type classes, doesn't NPE on null, but sets value to false
- parameter #0:
- type: @libcore.util.Nullable
-
- method valueOf(Z)Ljava/lang/Boolean;:
- // Always return value
- return: @libcore.util.NonNull
-
- method valueOf(Ljava/lang/String;)Ljava/lang/Boolean;:
- // Null == false
- parameter #0:
- type: @libcore.util.Nullable
- // Always return value
- return: @libcore.util.NonNull
-
- method toString(Z)Ljava/lang/String;:
- // Always return value
- return: @libcore.util.NonNull
-
- method toString()Ljava/lang/String;:
- // Always return value
- return: @libcore.util.NonNull
-
- method equals(Ljava/lang/Object;)Z:
- // Can be null
- parameter #0:
- type: @libcore.util.Nullable
-
- method getBoolean(Ljava/lang/String;)Z:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Returns null in case of failure
- return: @libcore.util.Nullable
-
- method compareTo(Ljava/lang/Boolean;)I:
- // NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
-class Byte:
- method toString(B)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method valueOf(B)Ljava/lang/Byte;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method parseByte(Ljava/lang/String;I)B:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method parseByte(Ljava/lang/String;)B:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method valueOf(Ljava/lang/String;I)Ljava/lang/Byte;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method valueOf(Ljava/lang/String;)Ljava/lang/Byte;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method decode(Ljava/lang/String;)Ljava/lang/Byte;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- return:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method <init>(Ljava/lang/String;)V:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method toString()Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method equals(Ljava/lang/Object;)Z:
- // Can be null
- parameter #0:
- type: @libcore.util.Nullable
-
- method compareTo(Ljava/lang/Byte;)I:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method toHexString(BZ)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
-class Character:
- method valueOf(C)Ljava/lang/Character;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method equals(Ljava/lang/Object;)Z:
- // Can be null
- parameter #0:
- type: @libcore.util.Nullable
-
- method toString()Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toString(C)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method codePointAt(Ljava/lang/CharSequence;I)I:
- // throws NPE
- parameter #0:
- type: @libcore.util.NonNull
-
- method codePointAt([CI)I:
- // throws NPE
- parameter #0:
- type: @libcore.util.NonNull
-
- method codePointAt([CII)I:
- // throws NPE
- parameter #0:
- type: @libcore.util.NonNull
-
- method codePointBefore(Ljava/lang/CharSequence;I)I:
- // throws NPE
- parameter #0:
- type: @libcore.util.NonNull
-
- method codePointBefore([CI)I:
- // throws NPE
- parameter #0:
- type: @libcore.util.NonNull
-
- method codePointBefore([CII)I:
- // throws NPE
- parameter #0:
- type: @libcore.util.NonNull
-
- method toChars(I[CI)I:
- // throws NPE
- parameter #1:
- type: @libcore.util.NonNull
-
- method toChars(I)[C:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method codePointCount(Ljava/lang/CharSequence;II)I:
- // throws NPE
- parameter #0:
- type: @libcore.util.NonNull
-
- method codePointCount([CII)I:
- // throws NPE
- parameter #0:
- type: @libcore.util.NonNull
-
- method offsetByCodePoints(Ljava/lang/CharSequence;II)I:
- // throws NPE
- parameter #0:
- type: @libcore.util.NonNull
-
- method offsetByCodePoints([CIIII)I:
- // throws NPE
- parameter #0:
- type: @libcore.util.NonNull
-
- method compareTo(Ljava/lang/Character;)I:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method getName(I)Ljava/lang/String;:
- // Null is a valid return value
- return: @libcore.util.Nullable
-
-class Character$Subset:
- method <init>(Ljava/lang/String;)V:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method equals(Ljava/lang/Object;)Z:
- // Can be null
- parameter #0:
- type: @libcore.util.Nullable
-
- method hashCode()I:
- return:
-
- method toString()Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
-class Character$UnicodeBlock:
- method of(C)Ljava/lang/Character$UnicodeBlock;:
- // Null is valid return value
- return: @libcore.util.Nullable
-
- method of(I)Ljava/lang/Character$UnicodeBlock;:
- // Null is valid return value
- return: @libcore.util.Nullable
-
- method forName(Ljava/lang/String;)Ljava/lang/Character$UnicodeBlock;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Always returns an instance
- return: @libcore.util.NonNull
-
-class Character$UnicodeScript:
- method of(I)Ljava/lang/Character$UnicodeScript;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method forName(Ljava/lang/String;)Ljava/lang/Character$UnicodeScript;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Always returns an instance
- return: @libcore.util.NonNull
-
-class CharSequence:
- // Always returns a string instance
- method toString()Ljava/lang/String;:
- return: @libcore.util.NonNull
-
-class Enum:
- // Always returns an instance or throws
- method valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;:
- return: @libcore.util.NonNull
-
-class Iterable:
- // Always returns an instance
- method iterator()Ljava/util/Iterator;:
- return: @libcore.util.NonNull
-
-class Integer:
- method toString(II)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toUnsignedString(II)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toHexString(I)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toOctalString(I)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toBinaryString(I)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toString(I)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toUnsignedString(I)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method parseInt(Ljava/lang/String;I)I:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method parseInt(Ljava/lang/String;)I:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method parseUnsignedInt(Ljava/lang/String;I)I:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method parseUnsignedInt(Ljava/lang/String;)I:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method valueOf(Ljava/lang/String;I)Ljava/lang/Integer;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method valueOf(Ljava/lang/String;)Ljava/lang/Integer;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method valueOf(I)Ljava/lang/Integer;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method <init>(Ljava/lang/String;)V:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method toString()Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method equals(Ljava/lang/Object;)Z:
- // Can be null
- parameter #0:
- type: @libcore.util.Nullable
-
- method getInteger(Ljava/lang/String;)Ljava/lang/Integer;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Returns null in case of failure
- return: @libcore.util.Nullable
-
- method getInteger(Ljava/lang/String;I)Ljava/lang/Integer;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Returns null in case of failure
- return: @libcore.util.Nullable
-
- method getInteger(Ljava/lang/String;Ljava/lang/Integer;)Ljava/lang/Integer;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Can be null
- parameter #1:
- type: @libcore.util.Nullable
- // Returns null in case of failure
- return: @libcore.util.Nullable
-
- method decode(Ljava/lang/String;)Ljava/lang/Integer;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- return:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method compareTo(Ljava/lang/Integer;)I:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
-class Float:
- method toString(F)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toHexString(F)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method valueOf(Ljava/lang/String;)Ljava/lang/Float;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method valueOf(F)Ljava/lang/Float;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method parseFloat(Ljava/lang/String;)F:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method <init>(Ljava/lang/String;)V:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method toString()Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method equals(Ljava/lang/Object;)Z:
- // Can be null
- parameter #0:
- type: @libcore.util.Nullable
-
- method compareTo(Ljava/lang/Float;)I:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
-class Double:
- method toString(D)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toHexString(D)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method valueOf(Ljava/lang/String;)Ljava/lang/Double;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method valueOf(D)Ljava/lang/Double;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method parseDouble(Ljava/lang/String;)D:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method <init>(Ljava/lang/String;)V:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method toString()Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method equals(Ljava/lang/Object;)Z:
- // Can be null
- parameter #0:
- type: @libcore.util.Nullable
-
- method compareTo(Ljava/lang/Double;)I:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
-class Long:
- method toString(JI)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toUnsignedString(JI)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toHexString(J)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toOctalString(J)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toBinaryString(J)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toString(J)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method toUnsignedString(J)Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method parseLong(Ljava/lang/String;I)J:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method parseLong(Ljava/lang/String;)J:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method parseUnsignedLong(Ljava/lang/String;I)J:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method parseUnsignedLong(Ljava/lang/String;)J:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method valueOf(Ljava/lang/String;I)Ljava/lang/Long;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method valueOf(Ljava/lang/String;)Ljava/lang/Long;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method valueOf(J)Ljava/lang/Long;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method decode(Ljava/lang/String;)Ljava/lang/Long;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- return:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method <init>(Ljava/lang/String;)V:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method toString()Ljava/lang/String;:
- // Always returns an instance
- return: @libcore.util.NonNull
-
- method equals(Ljava/lang/Object;)Z:
- // Can be null
- parameter #0:
- type: @libcore.util.Nullable
-
- method getLong(Ljava/lang/String;)Ljava/lang/Long;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Returns null in case of failure
- return: @libcore.util.Nullable
-
- method getLong(Ljava/lang/String;J)Ljava/lang/Long;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Returns null in case of failure
- return: @libcore.util.Nullable
-
- method getLong(Ljava/lang/String;Ljava/lang/Long;)Ljava/lang/Long;:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
- // Can be null
- parameter #1:
- type: @libcore.util.Nullable
- // Returns null in case of failure
- return: @libcore.util.Nullable
-
- method compareTo(Ljava/lang/Long;)I:
- // Throws NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
-class String:
- method <init>(Ljava/lang/String;)V:
- parameter #0:
- type: @libcore.util.NonNull
- return:
- method <init>([C)V:
- parameter #0:
- type: @libcore.util.NonNull
- return:
- method <init>([CII)V:
- parameter #0:
- type: @libcore.util.NonNull
- return:
- method <init>([III)V:
- parameter #0:
- type: @libcore.util.NonNull
- return:
- method <init>([BIII)V:
- parameter #0:
- type: @libcore.util.NonNull
- return:
- method <init>([BI)V:
- parameter #0:
- type: @libcore.util.NonNull
- return:
- method <init>([BIILjava/lang/String;)V:
- parameter #0:
- type: @libcore.util.NonNull
- parameter #3:
- type: @libcore.util.NonNull
- return:
- method <init>([BIILjava/nio/charset/Charset;)V:
- parameter #0:
- type: @libcore.util.NonNull
- parameter #3:
- type: @libcore.util.NonNull
- return:
- method <init>([BLjava/lang/String;)V:
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.NonNull
- return:
- method <init>([BLjava/nio/charset/Charset;)V:
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.NonNull
- return:
- method <init>([BII)V:
- parameter #0:
- type: @libcore.util.NonNull
- return:
- method <init>([B)V:
- parameter #0:
- type: @libcore.util.NonNull
- return:
- method <init>(Ljava/lang/StringBuffer;)V:
- parameter #0:
- type: @libcore.util.NonNull
- return:
- method <init>(Ljava/lang/StringBuilder;)V:
- parameter #0:
- type: @libcore.util.NonNull
- return:
- method <init>(II[C)V:
- parameter #2:
- type: @libcore.util.NonNull
- return:
- method getChars(II[CI)V:
- parameter #2:
- type: @libcore.util.NonNull
- return:
-
- // Always returns a string instance
- method toString()Ljava/lang/String;:
- return: @libcore.util.NonNull
-
- method getBytes(II[BI)V:
- parameter #2:
- type: @libcore.util.NonNull
- // Empty array in worst case
- method getBytes(Ljava/lang/String;)[B:
- parameter #0:
- type: @libcore.util.NonNull
- return: @libcore.util.NonNull
- // Empty array in worst case
- method getBytes(Ljava/nio/charset/Charset;)[B:
- parameter #0:
- type: @libcore.util.NonNull
- return: @libcore.util.NonNull
- // Empty array in worst case (or throws)
- method getBytes(Ljava/lang/String;)[B:
- parameter #0:
- type: @libcore.util.NonNull
- return: @libcore.util.NonNull
- // Empty array in worst case
- method getBytes()[B:
- return: @libcore.util.NonNull
- method equals(Ljava/lang/Object;)Z:
- parameter #0:
- type: @libcore.util.Nullable
- // Empty array in worst case
- method toCharArray()[C:
- return: @libcore.util.NonNull
- // Empty char sequence in worst case
- method subSequence(II)Ljava/lang/CharSequence;:
- return: @libcore.util.NonNull
- // Always returns a string instance
- method concat(Ljava/lang/String;)Ljava/lang/String;:
- parameter #0:
- type: @libcore.util.NonNull
- return: @libcore.util.NonNull
- // Always returns a string instance
- method copyValueOf([CII)Ljava/lang/String;:
- parameter #0:
- type: @libcore.util.NonNull
- return: @libcore.util.NonNull
- // Always returns a string instance
- method copyValueOf([C)Ljava/lang/String;:
- parameter #0:
- type: @libcore.util.NonNull
- return: @libcore.util.NonNull
- // Always returns a string instance
- method intern()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns a string instance
- method replace(CC)Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns a string instance
- method substring(I)Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns a string instance
- method substring(II)Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns a string instance
- method toLowerCase(Ljava/util/Locale;)Ljava/lang/String;:
- parameter #0:
- type: @libcore.util.NonNull
- return: @libcore.util.NonNull
- // Always returns a string instance
- method toLowerCase()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns a string instance
- method toUpperCase(Ljava/util/Locale;)Ljava/lang/String;:
- parameter #0:
- type: @libcore.util.NonNull
- return: @libcore.util.NonNull
- // Always returns a string instance
- method toUpperCase()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns a string instance
- method trim()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns a string instance
- method valueOf(Z)Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns a string instance
- method valueOf(C)Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns a string instance
- method valueOf(I)Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns a string instance
- method valueOf(J)Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns a string instance
- method valueOf(F)Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns a string instance
- method valueOf(D)Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns a string instance
- method valueOf(Ljava/lang/Object;)Ljava/lang/String;:
- parameter #0:
- type: @libcore.util.Nullable
- return:@libcore.util.NonNull
- // Always returns a string instance
- method valueOf([C)Ljava/lang/String;:
- parameter #0:
- type: @libcore.util.NonNull
- return: @libcore.util.NonNull
- // Always returns a string instance
- method valueOf([CII)Ljava/lang/String;:
- parameter #0:
- type: @libcore.util.NonNull
- return: @libcore.util.NonNull
- // Always returns a string instance
- method split(Ljava/lang/String;I)[Ljava/lang/String;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.NonNull
- // Always returns a string instance
- method split(Ljava/lang/String;)[Ljava/lang/String;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.NonNull
- // Always returns a string instance
- method join(Ljava/lang/CharSequence;[Ljava/lang/CharSequence;)Ljava/lang/String;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
- // Always returns a string instance
- method join(Ljava/lang/CharSequence;Ljava/lang/Iterable;)Ljava/lang/String;:
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.NonNull
- inner-type 3, 0, 2, 0: @libcore.util.Nullable
- return: @libcore.util.NonNull
- // Always returns a string instance
- method replaceAll(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;:
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.NonNull
- return: @libcore.util.NonNull
- // Always returns a string instance
- method replaceFirst(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;:
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.NonNull
- return: @libcore.util.NonNull
- method replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;:
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.NonNull
- return: @libcore.util.NonNull
- method contentEquals(Ljava/lang/StringBuffer;)Z:
- parameter #0:
- type: @libcore.util.NonNull
- method contentEquals(Ljava/lang/CharSequence;)Z:
- parameter #0:
- type: @libcore.util.NonNull
- method equalsIgnoreCase(Ljava/lang/String;)Z:
- parameter #0:
- type: @libcore.util.Nullable
- method compareTo(Ljava/lang/String;)I:
- parameter #0:
- type: @libcore.util.NonNull
- method compareToIgnoreCase(Ljava/lang/String;)I:
- parameter #0:
- type: @libcore.util.NonNull
- method regionMatches(ILjava/lang/String;II)Z:
- parameter #1:
- type: @libcore.util.NonNull
- method regionMatches(ZILjava/lang/String;II)Z:
- parameter #2:
- type: @libcore.util.NonNull
- method startsWith(Ljava/lang/String;I)Z:
- parameter #0:
- type: @libcore.util.NonNull
- method startsWith(Ljava/lang/String;)Z:
- parameter #0:
- type: @libcore.util.NonNull
- method endsWith(Ljava/lang/String;)Z:
- parameter #0:
- type: @libcore.util.NonNull
- method indexOf(Ljava/lang/String;)I:
- parameter #0:
- type: @libcore.util.NonNull
- method indexOf(Ljava/lang/String;I)I:
- parameter #0:
- type: @libcore.util.NonNull
- method lastIndexOf(Ljava/lang/String;)I:
- parameter #0:
- type: @libcore.util.NonNull
- method lastIndexOf(Ljava/lang/String;I)I:
- parameter #0:
- type: @libcore.util.NonNull
- method matches(Ljava/lang/String;)Z:
- parameter #0:
- type: @libcore.util.NonNull
- method contains(Ljava/lang/CharSequence;)Z:
- parameter #0:
- type: @libcore.util.NonNull
- method format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;:
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
- return: @libcore.util.NonNull
- method format(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;:
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.NonNull
- parameter #2:
- type: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
- return: @libcore.util.NonNull
-
-class System:
- // Ideally, in should be made NonNull - but it IS possible to make this final field
- // a null using setIn(null). It makes sense to leave this field as a platform
- // type for convenience reasons - no one sane should expect this to be null,
- // but it's nice to have kotlin check it.
- field in:
-
- // Same as in "in" field
- field out:
-
- // Same as in "in" field
- field err:
-
-
- method setIn(Ljava/io/InputStream;)V:
- // While it makes little sense, it's possible to set System.in to null.
- parameter #0:
- type: @libcore.util.Nullable
-
- method setOut(Ljava/io/PrintStream;)V:
- // While it makes little sense, it's possible to set System.out to null.
- parameter #0:
- type: @libcore.util.Nullable
-
- method setErr(Ljava/io/PrintStream;)V:
- // While it makes little sense, it's possible to set System.err to null.
- parameter #0:
- type: @libcore.util.Nullable
-
- method console()Ljava/io/Console;:
- // Always returns an instance
- return: @libcore.util.Nullable
-
- method inheritedChannel()Ljava/nio/channels/Channel;:
- // Null if there's no inherited channel
- return: @libcore.util.Nullable
-
- method setSecurityManager(Ljava/lang/SecurityManager;)V:
- // Null is a valid argument.
- parameter #0:
- type: @libcore.util.Nullable
-
- method getSecurityManager()Ljava/lang/SecurityManager;:
- // Null is valid return value.
- return: @libcore.util.Nullable
-
- method arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V:
- // NPE on null src
- parameter #0:
- type: @libcore.util.NonNull
- // NPE on null dst
- parameter #1:
- type: @libcore.util.NonNull
-
- method identityHashCode(Ljava/lang/Object;)I:
- // Null is a valid argument.
- parameter #0:
- type: @libcore.util.Nullable
-
- method getProperties()Ljava/util/Properties;:
- // There's always a properties object
- return: @libcore.util.NonNull
-
- method lineSeparator()Ljava/lang/String;:
- // There's always a line separator string (empty in worst case)
- return: @libcore.util.NonNull
-
- method setProperties(Ljava/util/Properties;)V:
- // Null is a valid argument (will reset to defaults)
- parameter #0:
- type: @libcore.util.Nullable
-
- method getProperty(Ljava/lang/String;)Ljava/lang/String;:
- // Property key can't be null
- parameter #0:
- type: @libcore.util.NonNull
- // Null is valid return value
- return: @libcore.util.Nullable
-
- method getProperty(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;:
- // Property key can't be null
- parameter #0:
- type: @libcore.util.NonNull
- // Property value can be null
- parameter #1:
- type: @libcore.util.Nullable
- // Null is valid return value
- return: @libcore.util.Nullable
-
- method setProperty(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;:
- // Property key can't be null
- parameter #0:
- type: @libcore.util.NonNull
- // Property value can be null
- parameter #1:
- type: @libcore.util.Nullable
- // Null is valid return value
- return: @libcore.util.Nullable
-
- method clearProperty(Ljava/lang/String;)Ljava/lang/String;:
- // Property key can't be null
- parameter #0:
- type: @libcore.util.NonNull
- // Null is valid return value
- return: @libcore.util.Nullable
-
- method getenv(Ljava/lang/String;)Ljava/lang/String;:
- // Name can't be null
- parameter #0:
- type: @libcore.util.NonNull
- // Null is valid return value
- return: @libcore.util.Nullable
-
- method getenv()Ljava/util/Map;:
- // Never null
- return: @libcore.util.NonNull
-
- method load(Ljava/lang/String;)V:
- // Filename can't be null
- parameter #0:
- type: @libcore.util.NonNull
-
- method loadLibrary(Ljava/lang/String;)V:
- // Libname can't be null
- parameter #0:
- type: @libcore.util.NonNull
-
- method mapLibraryName(Ljava/lang/String;)Ljava/lang/String;:
- // Libname can't be null
- parameter #0:
- type: @libcore.util.NonNull
- // Never null
- return: @libcore.util.NonNull
-
-class StringBuffer:
- method <init>(Ljava/lang/String;)V:
- // NPE on null argument
- parameter #0:
- type: @libcore.util.NonNull
-
- method <init>(Ljava/lang/CharSequence;)V:
- // NPE on null argument
- parameter #0:
- type: @libcore.util.NonNull
-
- method getChars(II[CI)V:
- // NPE on null argument
- parameter #2:
- type: @libcore.util.NonNull
-
- method append(Ljava/lang/Object;)Ljava/lang/StringBuffer;:
- // null -> "null"
- parameter #0:
- type: @libcore.util.Nullable
- // returns self
- return: @libcore.util.NonNull
-
- method append(Ljava/lang/String;)Ljava/lang/StringBuffer;:
- // null -> "null"
- parameter #0:
- type: @libcore.util.Nullable
- // returns self
- return: @libcore.util.NonNull
-
- method append(Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;:
- // null -> "null"
- parameter #0:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method append(Ljava/lang/AbstractStringBuilder;)Ljava/lang/StringBuffer;:
- // null -> "null"
- parameter #0:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method append(Ljava/lang/CharSequence;)Ljava/lang/StringBuffer;:
- // null -> "null"
- parameter #0:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method append(Ljava/lang/CharSequence;II)Ljava/lang/StringBuffer;:
- // null -> "null"
- parameter #0:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method append([C)Ljava/lang/StringBuffer;:
- // Null for char[] methods result in NPE
- parameter #0:
- type: @libcore.util.NonNull
- // Returns self
- return: @libcore.util.NonNull
-
- method append([CII)Ljava/lang/StringBuffer;:
- // Null for char[] methods result in NPE
- parameter #0:
- type: @libcore.util.NonNull
- // Returns self
- return: @libcore.util.NonNull
-
- method append(Z)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method append(C)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method append(I)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method appendCodePoint(I)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method append(J)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method append(F)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method append(D)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method delete(II)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method deleteCharAt(I)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method replace(IILjava/lang/String;)Ljava/lang/StringBuffer;:
- // NPE from null
- parameter #2:
- type: @libcore.util.NonNull
- // Returns self
- return: @libcore.util.NonNull
-
- method substring(I)Ljava/lang/String;:
- // Never null
- return: @libcore.util.NonNull
-
- method subSequence(II)Ljava/lang/CharSequence;:
- // Never null
- return: @libcore.util.NonNull
-
- method substring(II)Ljava/lang/String;:
- // Never null
- return: @libcore.util.NonNull
-
- method insert(I[CII)Ljava/lang/StringBuffer;:
- // Null for char[] methods result in NPE
- parameter #1:
- type: @libcore.util.NonNull
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(ILjava/lang/Object;)Ljava/lang/StringBuffer;:
- // null -> "null"
- parameter #1:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(ILjava/lang/String;)Ljava/lang/StringBuffer;:
- // null -> "null"
- parameter #1:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(I[C)Ljava/lang/StringBuffer;:
- // Null for char[] methods result in NPE
- parameter #1:
- type: @libcore.util.NonNull
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(ILjava/lang/CharSequence;)Ljava/lang/StringBuffer;:
- // null -> "null"
- parameter #1:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(ILjava/lang/CharSequence;II)Ljava/lang/StringBuffer;:
- // null -> "null"
- parameter #1:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(IZ)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(IC)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(II)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(IJ)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(IF)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(ID)Ljava/lang/StringBuffer;:
- // Returns self
- return: @libcore.util.NonNull
-
- method indexOf(Ljava/lang/String;)I:
- parameter #0:
- type: @libcore.util.NonNull
-
- method indexOf(Ljava/lang/String;I)I:
- // NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method lastIndexOf(Ljava/lang/String;)I:
- // NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method lastIndexOf(Ljava/lang/String;I)I:
- // NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method reverse()Ljava/lang/StringBuffer;:
- // Never null
- return: @libcore.util.NonNull
-
- method toString()Ljava/lang/String;:
- // Never null
- return: @libcore.util.NonNull
-
-class StringBuilder:
-
- method <init>(Ljava/lang/String;)V:
- // NPE on null argument
- parameter #0:
- type: @libcore.util.NonNull
-
- method <init>(Ljava/lang/CharSequence;)V:
- // NPE on null argument
- parameter #0:
- type: @libcore.util.NonNull
-
- method append(Ljava/lang/Object;)Ljava/lang/StringBuilder;:
- // null -> "null"
- parameter #0:
- type: @libcore.util.Nullable
- // returns self
- return: @libcore.util.NonNull
-
- method append(Ljava/lang/String;)Ljava/lang/StringBuilder;:
- // null -> "null"
- parameter #0:
- type: @libcore.util.Nullable
- // returns self
- return: @libcore.util.NonNull
-
- method append(Ljava/lang/StringBuffer;)Ljava/lang/StringBuilder;:
- // null -> "null"
- parameter #0:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method append(Ljava/lang/CharSequence;)Ljava/lang/StringBuilder;:
- // null -> "null"
- parameter #0:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method append(Ljava/lang/CharSequence;II)Ljava/lang/StringBuilder;:
- // null -> "null"
- parameter #0:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method append([C)Ljava/lang/StringBuilder;:
- // Null for char[] methods result in NPE
- parameter #0:
- type: @libcore.util.NonNull
- // Returns self
- return: @libcore.util.NonNull
-
- method append([CII)Ljava/lang/StringBuilder;:
- // Null for char[] methods result in NPE
- parameter #0:
- type: @libcore.util.NonNull
- // Returns self
- return: @libcore.util.NonNull
-
- method append(Z)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method append(C)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method append(I)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method append(J)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method append(F)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method append(D)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method appendCodePoint(I)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method delete(II)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method deleteCharAt(I)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method replace(IILjava/lang/String;)Ljava/lang/StringBuilder;:
- // NPE from null
- parameter #2:
- type: @libcore.util.NonNull
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(I[CII)Ljava/lang/StringBuilder;:
- // Null for char[] methods result in NPE
- parameter #1:
- type: @libcore.util.NonNull
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(ILjava/lang/Object;)Ljava/lang/StringBuilder;:
- // null -> "null"
- parameter #1:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(ILjava/lang/String;)Ljava/lang/StringBuilder;:
- // null -> "null"
- parameter #1:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(I[C)Ljava/lang/StringBuilder;:
- // Null for char[] methods result in NPE
- parameter #1:
- type: @libcore.util.NonNull
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(ILjava/lang/CharSequence;)Ljava/lang/StringBuilder;:
- // null -> "null"
- parameter #1:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(ILjava/lang/CharSequence;II)Ljava/lang/StringBuilder;:
- // null -> "null"
- parameter #1:
- type: @libcore.util.Nullable
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(IZ)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(IC)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(II)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(IJ)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(IF)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method insert(ID)Ljava/lang/StringBuilder;:
- // Returns self
- return: @libcore.util.NonNull
-
- method indexOf(Ljava/lang/String;)I:
- // NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method indexOf(Ljava/lang/String;I)I:
- // NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method lastIndexOf(Ljava/lang/String;)I:
- // NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method lastIndexOf(Ljava/lang/String;I)I:
- // NPE on null
- parameter #0:
- type: @libcore.util.NonNull
-
- method reverse()Ljava/lang/StringBuilder;:
- // Never null
- return: @libcore.util.NonNull
-
- method toString()Ljava/lang/String;:
- // Never null
- return: @libcore.util.NonNull
-
-class Thread:
- // Always returns a string instance
- method toString()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always return an instance
- method currentThread()Ljava/lang/Thread;:
- return: @libcore.util.NonNull
-
-// It would be nice to use @NullFromTypeParam in ThreadLocal
-// everywhere its <T> is used, buy sadly the code below makes it impossible:
-//
-// ThreadLocal<@NonNull Object> foo = new ThreadLocal<>();
-// assertNull(foo.get())
-//
-// Hence @Nullable T is used heavily
-class ThreadLocal:
- method withInitial(Ljava/util/function/Supplier;)Ljava/lang/ThreadLocal;:
- // NPE on null supplier
- parameter #0:
- type: @libcore.util.NonNull
- // Always returns instance
- return: @libcore.util.NonNull
-
- method initialValue()Ljava/lang/Object;:
- // Returns null by default
- return: @libcore.util.Nullable
-
- method get()Ljava/lang/Object;:
- // May return null
- return: @libcore.util.Nullable
-
- method set(Ljava/lang/Object;)V:
- // Depends on type param
- parameter #0:
- type: @libcore.util.NullFromTypeParam
-
-class Object:
-
- method getClass()Ljava/lang/Class;:
- return: @libcore.util.NonNull
-
- method equals(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method toString()Ljava/lang/String;:
- return: @libcore.util.NonNull
-
-class Class:
-
- method toString()Ljava/lang/String;:
- return: @libcore.util.NonNull
-
- method toGenericString()Ljava/lang/String;:
- return: @libcore.util.NonNull
-
- method forName(Ljava/lang/String;)Ljava/lang/Class;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.NonNull
-
- method forName(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.NonNull
- parameter #2:
- type: @libcore.util.Nullable
-
- method newInstance()Ljava/lang/Object;:
- return: @libcore.util.NonNull
-
- method isInstance(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method isAssignableFrom(Ljava/lang/Class;)Z:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method getName()Ljava/lang/String;:
- return: @libcore.util.NonNull
-
- method getClassLoader()Ljava/lang/ClassLoader;:
- return: @libcore.util.Nullable
-
- method getTypeParameters()[Ljava/lang/reflect/TypeVariable;:
- return: @libcore.util.NonNull
- inner-type 0, 0,3, 0: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
- method getSuperclass()Ljava/lang/Class;:
- return: @libcore.util.Nullable
-
- method getGenericSuperclass()Ljava/lang/reflect/Type;:
- return: @libcore.util.Nullable
-
- method getPackage()Ljava/lang/Package;:
- return: @libcore.util.Nullable
-
- method getInterfaces()[Ljava/lang/Class;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
- method getGenericInterfaces()[Ljava/lang/reflect/Type;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
- method getComponentType()Ljava/lang/Class;:
- return: @libcore.util.Nullable
-
- method getSigners()[Ljava/lang/Object;:
- return: @libcore.util.Nullable
- inner-type 0, 0: @libcore.util.NonNull
-
- method getEnclosingMethod()Ljava/lang/reflect/Method;:
- return: @libcore.util.Nullable
-
- method getEnclosingConstructor()Ljava/lang/reflect/Constructor;:
- return: @libcore.util.Nullable
-
- method getDeclaringClass()Ljava/lang/Class;:
- return: @libcore.util.Nullable
-
- method getEnclosingClass()Ljava/lang/Class;:
- return: @libcore.util.Nullable
-
- method getSimpleName()Ljava/lang/String;:
- return: @libcore.util.NonNull
-
- method getTypeName()Ljava/lang/String;:
- return: @libcore.util.NonNull
-
- method getCanonicalName()Ljava/lang/String;:
- return: @libcore.util.Nullable
-
- method getClasses()[Ljava/lang/Class;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
- method getFields()[Ljava/lang/reflect/Field;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
- method getMethods()[Ljava/lang/reflect/Method;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
- method getConstructors()[Ljava/lang/reflect/Constructor;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
- method getField(Ljava/lang/String;)Ljava/lang/reflect/Field;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.NonNull
-
- method getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.Nullable
- inner-type 0, 0: @libcore.util.NonNull
-
- method getConstructor([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.Nullable
- inner-type 0, 0: @libcore.util.NonNull
-
- method getDeclaredClasses()[Ljava/lang/Class;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
- method getDeclaredFields()[Ljava/lang/reflect/Field;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
- method getDeclaredMethods()[Ljava/lang/reflect/Method;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
- method getDeclaredConstructors()[Ljava/lang/reflect/Constructor;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
- method getDeclaredField(Ljava/lang/String;)Ljava/lang/reflect/Field;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.NonNull
-
- method getDeclaredMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.NonNull
- parameter #1:
- type: @libcore.util.Nullable
- inner-type 0, 0: @libcore.util.NonNull
-
- method getDeclaredConstructor([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;:
- return: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.Nullable
- inner-type 0, 0: @libcore.util.NonNull
-
- method getResourceAsStream(Ljava/lang/String;)Ljava/io/InputStream;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NonNull
-
- method getResource(Ljava/lang/String;)Ljava/net/URL;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NonNull
-
- method getProtectionDomain()Ljava/security/ProtectionDomain;:
- return: @libcore.util.Nullable
-
- method getEnumConstants()[Ljava/lang/Object;:
- return: @libcore.util.Nullable
- inner-type 0, 0: @libcore.util.NonNull
-
- method cast(Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.Nullable
-
- method asSubclass(Ljava/lang/Class;)Ljava/lang/Class;:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method getAnnotation(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NonNull
-
- method isAnnotationPresent(Ljava/lang/Class;)Z:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method getAnnotationsByType(Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- parameter #0:
- type: @libcore.util.NonNull
-
- method getAnnotations()[Ljava/lang/annotation/Annotation;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
- method getDeclaredAnnotation(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NonNull
-
- method getDeclaredAnnotations()[Ljava/lang/annotation/Annotation;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
- method isDeclaredAnnotationPresent(Ljava/lang/Class;)Z:
- return:
-
-package java.lang.reflect:
-
-class AccessibleObject:
- // Empty array in the worst case
- method getAnnotations()[Ljava/lang/annotation/Annotation;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Empty array in the worst case
- method getDeclaredAnnotations()[Ljava/lang/annotation/Annotation;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
-class AnnotatedElement:
- // Empty array in the worst case
- method getAnnotations()[Ljava/lang/annotation/Annotation;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Empty array in the worst case
- method getDeclaredAnnotations()[Ljava/lang/annotation/Annotation;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
-class Array:
- // Returns instance or throws
- method newInstance(Ljava/lang/Class;I)Ljava/lang/Object;:
- return: @libcore.util.NonNull
- // Returns instance or throws
- method newInstance(Ljava/lang/Class;[I)Ljava/lang/Object;:
- return: @libcore.util.NonNull
-
-class Constructor:
- // Always returns an instance
- method toString()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns an instance
- method toGenericString()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns an instance
- method getName()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // There's always a declaring class
- method getDeclaringClass()Ljava/lang/Class;:
- return: @libcore.util.NonNull
- // Empty array in the worst case
- method getParameterTypes()[Ljava/lang/Class;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Returns instance or throws
- method newInstance([Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.NonNull
-
-class Executable:
- // There's always a declaring class
- method getDeclaringClass()Ljava/lang/Class;:
- return: @libcore.util.NonNull
- // Always returns an instance
- method getName()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Empty array in the worst case
- method getParameterTypes()[Ljava/lang/Class;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Empty array in the worst case
- method getTypeParameters()[Ljava/lang/reflect/TypeVariable;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Empty array in the worst case
- method getGenericParameterTypes()[Ljava/lang/reflect/Type;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Empty array in the worst case
- method getParameters()[Ljava/lang/reflect/Parameter;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Empty array in the worst case
- method getExceptionTypes()[Ljava/lang/Class;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Empty array in the worst case
- method getGenericExceptionTypes()[Ljava/lang/reflect/Type;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Always returns an instance
- method toGenericString()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Empty array in the worst case
- method getDeclaredAnnotations()[Ljava/lang/annotation/Annotation;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Empty array in the worst case
- method getParameterAnnotations()[[Ljava/lang/annotation/Annotation;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- inner-type 0, 0, 0, 0: @libcore.util.NonNull
-
-class Field:
- // Always returns an instance
- method getName()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // There's always a type of a field
- method getType()Ljava/lang/Class;:
- return: @libcore.util.NonNull
- // Always returns an instance
- method toString()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns an instance
- method toGenericString()Ljava/lang/String;:
- return: @libcore.util.NonNull
-
-class GenericArrayType:
- // There's always a type for array
- method getGenericComponentType()Ljava/lang/reflect/Type;:
- return: @libcore.util.NonNull
-
-class GenericDeclaration:
- // Empty array in the worst case
- method getTypeParameters()[Ljava/lang/reflect/TypeVariable;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
-class Member:
- method getDeclaringClass()Ljava/lang/Class;:
- return: @libcore.util.NonNull
- // Always returns an instance
- method getName()Ljava/lang/String;:
- return: @libcore.util.NonNull
-
-class Method:
- // There's always a declaring class
- method getDeclaringClass()Ljava/lang/Class;:
- return: @libcore.util.NonNull
- // Empty array in the worst case
- method getTypeParameters()[Ljava/lang/reflect/TypeVariable;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // There's always a return type (such as Void.class)
- method getReturnType()Ljava/lang/Class;:
- return: @libcore.util.NonNull
- // There's always a return type (such as Void.class)
- method getGenericReturnType()Ljava/lang/reflect/Type;:
- return: @libcore.util.NonNull
- // Empty array in the worst case
- method getParameterTypes()[Ljava/lang/Class;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Empty array in the worst case
- method getGenericParameterTypes()[Ljava/lang/reflect/Type;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Empty array in the worst case
- method getExceptionTypes()[Ljava/lang/Class;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Empty array in the worst case
- method getGenericExceptionTypes()[Ljava/lang/reflect/Type;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Always returns an instance
- method toString()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Always returns an instance
- method toGenericString()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // Empty array in the worst case
- method getDeclaredAnnotations()[Ljava/lang/annotation/Annotation;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Empty array in the worst case
- method getParameterAnnotations()[[Ljava/lang/annotation/Annotation;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- inner-type 0, 0, 0, 0: @libcore.util.NonNull
-
-
-class ParameterizedType:
- // Empty array in the worst case
- method getActualTypeArguments()[Ljava/lang/reflect/Type;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Always returns an instance
- method getRawType()Ljava/lang/reflect/Type;:
- return: @libcore.util.NonNull
-
-class Parameter:
- // Always returns an instance
- method toString()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // There's always a declaring executable
- method getDeclaringExecutable()Ljava/lang/reflect/Executable;:
- return: @libcore.util.NonNull
- // Always returns an instance
- method getRealName()Ljava/lang/String;:
- return: @libcore.util.NonNull
- // There's always a type
- method getParameterizedType()Ljava/lang/reflect/Type;:
- return: @libcore.util.NonNull
- // There's always a type
- method getType()Ljava/lang/Class;:
- return: @libcore.util.NonNull
- // Empty array in the worst case
- method getDeclaredAnnotations()[Ljava/lang/annotation/Annotation;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Empty array in the worst case
- method getAnnotations()[Ljava/lang/annotation/Annotation;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
-class Proxy:
- // Always returns an instance (or throws)
- method getProxyClass(Ljava/lang/ClassLoader;[Ljava/lang/Class;)Ljava/lang/Class;:
- return: @libcore.util.NonNull
- // Always returns an instance (or throws)
- method newProxyInstance(Ljava/lang/ClassLoader;[Ljava/lang/Class;Ljava/lang/reflect/InvocationHandler;)Ljava/lang/Object;:
- return: @libcore.util.NonNull
- // Always returns an instance (or throws)
- method getInvocationHandler(Ljava/lang/Object;)Ljava/lang/reflect/InvocationHandler;:
- return: @libcore.util.NonNull
-
-class Type:
- // Always returns an instance
- method getTypeName()Ljava/lang/String;:
- return: @libcore.util.NonNull
-
-class TypeVariable:
- // Empty array in the worst case
- method getBounds()[Ljava/lang/reflect/Type;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Always returns an instance
- method getGenericDeclaration()Ljava/lang/reflect/GenericDeclaration;:
- return: @libcore.util.NonNull
- // Always returns an instance
- method getName()Ljava/lang/String;:
- return: @libcore.util.NonNull
-
-class WildcardType:
- // Empty array in the worst case
- method getUpperBounds()[Ljava/lang/reflect/Type;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
- // Empty array in the worst case
- method getLowerBounds()[Ljava/lang/reflect/Type;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.NonNull
-
-package java.util:
-
-class ArrayList:
-
- method <init>(Ljava/util/Collection;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
- method contains(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method indexOf(Ljava/lang/Object;)I:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method lastIndexOf(Ljava/lang/Object;)I:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method clone()Ljava/lang/Object;:
- return: @libcore.util.NonNull
-
- method toArray()[Ljava/lang/Object;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
-
- method toArray([Ljava/lang/Object;)[Ljava/lang/Object;:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
-
- method get(I)Ljava/lang/Object;:
- return: @libcore.util.NullFromTypeParam
-
- method set(ILjava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NullFromTypeParam
-
- method add(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.NullFromTypeParam
-
- method add(ILjava/lang/Object;)V:
- return:
- parameter #1:
- type: @libcore.util.NullFromTypeParam
-
- method remove(I)Ljava/lang/Object;:
- return: @libcore.util.NullFromTypeParam
-
- method remove(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method addAll(Ljava/util/Collection;)Z:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
- method addAll(ILjava/util/Collection;)Z:
- return:
- parameter #1:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
- method removeAll(Ljava/util/Collection;)Z:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method retainAll(Ljava/util/Collection;)Z:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method listIterator(I)Ljava/util/ListIterator;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method listIterator()Ljava/util/ListIterator;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method iterator()Ljava/util/Iterator;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method subList(II)Ljava/util/List;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method forEach(Ljava/util/function/Consumer;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
- method spliterator()Ljava/util/Spliterator;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method removeIf(Ljava/util/function/Predicate;)Z:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
- method replaceAll(Ljava/util/function/UnaryOperator;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method sort(Ljava/util/Comparator;)V:
- return:
- parameter #0:
- type: @libcore.util.Nullable
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
-class HashMap:
-
- method <init>(Ljava/util/Map;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 1,2, 0: @libcore.util.NullFromTypeParam
-
- method get(Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.Nullable
-
- method containsKey(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NullFromTypeParam
-
- method putAll(Ljava/util/Map;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 1,2, 0: @libcore.util.NullFromTypeParam
-
- method remove(Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.Nullable
-
- method containsValue(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method keySet()Ljava/util/Set;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method values()Ljava/util/Collection;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method entrySet()Ljava/util/Set;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NonNull
- inner-type 3, 0,3, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 0,3, 1: @libcore.util.NullFromTypeParam
-
- method getOrDefault(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.Nullable
- parameter #1:
- type: @libcore.util.Nullable
-
- method putIfAbsent(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NullFromTypeParam
-
- method remove(Ljava/lang/Object;Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
- parameter #1:
- type: @libcore.util.Nullable
-
- method replace(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.Nullable
- parameter #2:
- type: @libcore.util.NullFromTypeParam
-
- method replace(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NullFromTypeParam
-
- method computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 1,2, 0: @libcore.util.Nullable
-
- method computeIfPresent(Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 1,2, 0: @libcore.util.NonNull
- inner-type 3, 2,2, 0: @libcore.util.Nullable
-
- method compute(Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 1,2, 0: @libcore.util.Nullable
- inner-type 3, 2,2, 0: @libcore.util.Nullable
-
- method merge(Ljava/lang/Object;Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NonNull
- parameter #2:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NonNull
- inner-type 3, 1,2, 0: @libcore.util.NonNull
- inner-type 3, 2,2, 0: @libcore.util.Nullable
-
- method forEach(Ljava/util/function/BiConsumer;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 1,2, 0: @libcore.util.NullFromTypeParam
-
- method replaceAll(Ljava/util/function/BiFunction;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 1,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 2,2, 0: @libcore.util.NullFromTypeParam
-
- method clone()Ljava/lang/Object;:
- return: @libcore.util.NonNull
-
-class Iterator:
-
- method next()Ljava/lang/Object;:
- return: @libcore.util.NullFromTypeParam
-
- method forEachRemaining(Ljava/util/function/Consumer;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
-class List:
- method contains(Ljava/lang/Object;)Z:
- // May be null
- parameter #0:
- type: @libcore.util.Nullable
- return:
-
- method iterator()Ljava/util/Iterator;:
- // Javadoc doesn't mention possiblity of a null result
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method toArray()[Ljava/lang/Object;:
- // Never returns null
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
-
- method toArray([Ljava/lang/Object;)[Ljava/lang/Object;:
- // Javadoc mention NPE for param #0
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
- // Never returns null
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
-
- method add(Ljava/lang/Object;)Z:
- // Nullness depends on type parameter nullness
- parameter #0:
- type: @libcore.util.NullFromTypeParam
-
- method remove(Ljava/lang/Object;)Z:
- // param #0 has to allow nulls
- parameter #0:
- type: @libcore.util.Nullable
-
- method containsAll(Ljava/util/Collection;)Z:
- // Javadoc mention NPE for null param #0
- parameter #0:
- type: @libcore.util.NonNull
-
- method addAll(Ljava/util/Collection;)Z:
- // Javadoc mention NPE for null param #0
- parameter #0:
- type: @libcore.util.NonNull
- // boolean addAll(Collection<? extends E> c);
- // Nullness depends on type parameter nullness
- inner-type 3, 0, 2, 0: @libcore.util.NullFromTypeParam
-
- method addAll(ILjava/util/Collection;)Z:
- // Javadoc mention NPE for null param #1
- parameter #1:
- type: @libcore.util.NonNull
- // boolean addAll(int, Collection<? extends E> c);
- inner-type 3, 0, 2, 0: @libcore.util.NullFromTypeParam
-
- method removeAll(Ljava/util/Collection;)Z:
- // Javadoc mention NPE for null param #0
- parameter #0:
- type: @libcore.util.NonNull
-
- method retainAll(Ljava/util/Collection;)Z:
- // Javadoc mention NPE for null param #0
- parameter #0:
- type: @libcore.util.NonNull
-
- method replaceAll(Ljava/util/function/UnaryOperator;)V:
- // Javadoc mention NPE for null param #0
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method sort(Ljava/util/Comparator;)V:
- // Javadoc mention null as valid param #0
- parameter #0:
- type: @libcore.util.Nullable
- inner-type 3, 0, 2, 0: @libcore.util.NullFromTypeParam
-
- method equals(Ljava/lang/Object;)Z:
- // Null is valid argument #0
- parameter #0:
- type: @libcore.util.Nullable
-
- method get(I)Ljava/lang/Object;:
- // Nullness depends on type parameter nullness
- // E get(int index);
- return: @libcore.util.NullFromTypeParam
-
- method set(ILjava/lang/Object;)Ljava/lang/Object;:
- // Nullness depends on type parameter nullness
- // E set(int index, E element);
- parameter #1:
- type: @libcore.util.NullFromTypeParam
- return: @libcore.util.NullFromTypeParam
-
- method add(ILjava/lang/Object;)V:
- // Nullness depends on type parameter nullness
- // void add(int index, E element);
- parameter #1:
- type: @libcore.util.NullFromTypeParam
-
- method remove(I)Ljava/lang/Object;:
- // Nullness depends on type parameter nullness
- // E remove(int index);
- return: @libcore.util.NullFromTypeParam
-
- method indexOf(Ljava/lang/Object;)I:
- // Null is valid argument
- parameter #0:
- type: @libcore.util.Nullable
-
- method lastIndexOf(Ljava/lang/Object;)I:
- // Null is valid argument
- parameter #0:
- type: @libcore.util.Nullable
-
- method listIterator()Ljava/util/ListIterator;:
- // Javadoc doesn't mention possiblity of a null result
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method listIterator(I)Ljava/util/ListIterator;:
- // Javadoc doesn't mention possiblity of a null result
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method subList(II)Ljava/util/List;:
- // Javadoc doesn't mention possiblity of a null result
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method spliterator()Ljava/util/Spliterator;:
- // Javadoc doesn't mention possiblity of a null result
- return: @libcore.util.NonNull
-
-class Map:
-
- method containsKey(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method containsValue(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method get(Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.Nullable
-
- method put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NullFromTypeParam
-
- method remove(Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.Nullable
-
- method putAll(Ljava/util/Map;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 1,2, 0: @libcore.util.NullFromTypeParam
-
- method keySet()Ljava/util/Set;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method values()Ljava/util/Collection;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method entrySet()Ljava/util/Set;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NonNull
- inner-type 3, 0,3, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 0,3, 1: @libcore.util.NullFromTypeParam
-
- method equals(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method getOrDefault(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.Nullable
- parameter #1:
- type: @libcore.util.Nullable
-
- method forEach(Ljava/util/function/BiConsumer;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 1,2, 0: @libcore.util.NullFromTypeParam
-
- method replaceAll(Ljava/util/function/BiFunction;)V:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 1,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 2,2, 0: @libcore.util.NullFromTypeParam
-
- method putIfAbsent(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NullFromTypeParam
-
- method remove(Ljava/lang/Object;Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
- parameter #1:
- type: @libcore.util.Nullable
-
- method replace(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.Nullable
- parameter #2:
- type: @libcore.util.NullFromTypeParam
-
- method replace(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NullFromTypeParam
-
- method computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 1,2, 0: @libcore.util.Nullable
-
- method computeIfPresent(Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 1,2, 0: @libcore.util.NonNull
- inner-type 3, 2,2, 0: @libcore.util.Nullable
-
- method compute(Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 1,2, 0: @libcore.util.Nullable
- inner-type 3, 2,2, 0: @libcore.util.Nullable
-
- method merge(Ljava/lang/Object;Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;:
- return: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NullFromTypeParam
- parameter #1:
- type: @libcore.util.NonNull
- parameter #2:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NonNull
- inner-type 3, 1,2, 0: @libcore.util.NonNull
- inner-type 3, 2,2, 0: @libcore.util.Nullable
-
-class Map$Entry:
-
- method getKey()Ljava/lang/Object;:
- return: @libcore.util.NullFromTypeParam
-
- method getValue()Ljava/lang/Object;:
- return: @libcore.util.NullFromTypeParam
-
- method setValue(Ljava/lang/Object;)Ljava/lang/Object;:
- return: @libcore.util.NullFromTypeParam
- parameter #0:
- type: @libcore.util.NullFromTypeParam
-
- method equals(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method comparingByKey()Ljava/util/Comparator;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NonNull
- inner-type 3, 0,3, 0: @libcore.util.NonNull
- inner-type 3, 0,3, 1: @libcore.util.Nullable
-
- method comparingByValue()Ljava/util/Comparator;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NonNull
- inner-type 3, 0,3, 0: @libcore.util.Nullable
- inner-type 3, 0,3, 1: @libcore.util.NonNull
-
- method comparingByKey(Ljava/util/Comparator;)Ljava/util/Comparator;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NonNull
- inner-type 3, 0,3, 0: @libcore.util.NullFromTypeParam
- inner-type 3, 0,3, 1: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
- method comparingByValue(Ljava/util/Comparator;)Ljava/util/Comparator;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NonNull
- inner-type 3, 0,3, 0: @libcore.util.Nullable
- inner-type 3, 0,3, 1: @libcore.util.NullFromTypeParam
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
-class Set:
-
- method contains(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method iterator()Ljava/util/Iterator;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
-
- method toArray()[Ljava/lang/Object;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
-
- method toArray([Ljava/lang/Object;)[Ljava/lang/Object;:
- return: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 0, 0: @libcore.util.Nullable
-
- method add(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.NullFromTypeParam
-
- method remove(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method containsAll(Ljava/util/Collection;)Z:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method addAll(Ljava/util/Collection;)Z:
- return:
- parameter #0:
- type: @libcore.util.NonNull
- inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
- method retainAll(Ljava/util/Collection;)Z:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method removeAll(Ljava/util/Collection;)Z:
- return:
- parameter #0:
- type: @libcore.util.NonNull
-
- method equals(Ljava/lang/Object;)Z:
- return:
- parameter #0:
- type: @libcore.util.Nullable
-
- method spliterator()Ljava/util/Spliterator;:
- return: @libcore.util.NonNull
- inner-type 3, 0: @libcore.util.NullFromTypeParam
diff --git a/benchmarks/src/benchmarks/DeepArrayOpsBenchmark.java b/benchmarks/src/benchmarks/DeepArrayOpsBenchmark.java
index 1429062..c671da6 100644
--- a/benchmarks/src/benchmarks/DeepArrayOpsBenchmark.java
+++ b/benchmarks/src/benchmarks/DeepArrayOpsBenchmark.java
@@ -16,24 +16,23 @@
package benchmarks;
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
import com.google.caliper.Param;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.util.Arrays;
public class DeepArrayOpsBenchmark {
- @Param({"1", "4", "16", "256", "2048"}) int arrayLength;
+ @Param({"0001", "0004", "0016", "0256", "2048"}) int arrayLength;
private Object[] array;
private Object[] array2;
- private Object[] array3;
- private Object[] array4;
-
- protected void setUp() throws Exception {
- array = new Object[arrayLength * 13];
- array2 = new Object[arrayLength * 13];
- for (int i = 0; i < arrayLength; i += 13) {
+ @BeforeExperiment public void setUp() throws Exception {
+ array = new Object[arrayLength * 14];
+ array2 = new Object[arrayLength * 14];
+ for (int i = 0; i < arrayLength; i += 14) {
array[i] = new IntWrapper(i);
array2[i] = new IntWrapper(i);
@@ -74,16 +73,19 @@
// Subarray types is an interface.
array[i + 12] = new16ElementArray(CharSequence.class, String.class);
array2[i + 12] = new16ElementArray(CharSequence.class, String.class);
+
+ array[i + 13] = null;
+ array2[i + 13] = null;
}
}
- public void timeDeepHashCode(int reps) {
+ @Benchmark public void deepHashCode(int reps) {
for (int i = 0; i < reps; ++i) {
Arrays.deepHashCode(array);
}
}
- public void timeEquals(int reps) {
+ @Benchmark public void deepEquals(int reps) {
for (int i = 0; i < reps; ++i) {
Arrays.deepEquals(array, array2);
}
@@ -143,4 +145,3 @@
}
}
}
-
diff --git a/benchmarks/src/benchmarks/GetSystemPropertyBenchmark.java b/benchmarks/src/benchmarks/GetSystemPropertyBenchmark.java
new file mode 100644
index 0000000..3a93285
--- /dev/null
+++ b/benchmarks/src/benchmarks/GetSystemPropertyBenchmark.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 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 benchmarks;
+
+import java.security.AccessController;
+
+import sun.security.action.GetPropertyAction;
+
+/**
+ * Compares performance of accessing system properties via
+ * legacy security code
+ * {@code AccessController.doPrivileged(new GetPropertyAction(key[, default]))}
+ * vs. direct invocation of {@code System.getProperty(key[, default])}.
+ *
+ * As of 2018-07, libcore carries some patches to perform such short-circuiting,
+ * so it's interesting to know how much better it performs.
+ */
+public class GetSystemPropertyBenchmark {
+
+ public void timeSystem_getProperty_default(int reps) {
+ for (int i = 0; i < reps; i++) {
+ System.getProperty("user.language", "en");
+ }
+ }
+
+ public void timeSystem_getProperty(int reps) {
+ for (int i = 0; i < reps; i++) {
+ System.getProperty("user.region");
+ }
+ }
+
+ public void timeAccessController_getPropertyAction(int reps) {
+ for (int i = 0; i < reps; i++) {
+ AccessController.doPrivileged(
+ new GetPropertyAction("user.language", "en"));
+ }
+ }
+
+ public void timeAccessController_getPropertyAction_default(int reps) {
+ for (int i = 0; i < reps; i++) {
+ AccessController.doPrivileged(
+ new GetPropertyAction("user.region"));
+ }
+ }
+
+}
diff --git a/benchmarks/src/benchmarks/XmlParseBenchmark.java b/benchmarks/src/benchmarks/XmlParseBenchmark.java
index 69ab7a5..1029616 100644
--- a/benchmarks/src/benchmarks/XmlParseBenchmark.java
+++ b/benchmarks/src/benchmarks/XmlParseBenchmark.java
@@ -65,7 +65,8 @@
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
documentBuilder = builderFactory.newDocumentBuilder();
- kxmlConstructor = (Constructor) Class.forName("org.kxml2.io.KXmlParser").getConstructor();
+ kxmlConstructor = (Constructor) Class.forName("com.android.org.kxml2.io.KXmlParser")
+ .getConstructor();
expatConstructor = (Constructor) Class.forName("org.apache.harmony.xml.ExpatPullParser")
.getConstructor();
}
diff --git a/benchmarks/src/benchmarks/XmlSerializeBenchmark.java b/benchmarks/src/benchmarks/XmlSerializeBenchmark.java
index c542e87..a8c51b3 100644
--- a/benchmarks/src/benchmarks/XmlSerializeBenchmark.java
+++ b/benchmarks/src/benchmarks/XmlSerializeBenchmark.java
@@ -81,7 +81,7 @@
@SuppressWarnings("unchecked")
@BeforeExperiment
protected void setUp() throws Exception {
- kxmlConstructor = (Constructor) Class.forName("org.kxml2.io.KXmlSerializer")
+ kxmlConstructor = (Constructor) Class.forName("com.android.org.kxml2.io.KXmlSerializer")
.getConstructor();
fastConstructor = (Constructor) Class.forName("com.android.internal.util.FastXmlSerializer")
.getConstructor();
diff --git a/dalvik/src/main/java/dalvik/annotation/codegen/CovariantReturnType.java b/dalvik/src/main/java/dalvik/annotation/codegen/CovariantReturnType.java
new file mode 100644
index 0000000..f302850
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/annotation/codegen/CovariantReturnType.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.annotation.codegen;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates to the platform toolchain that there is an upcoming public SDK API change for a method.
+ * The API change will add a more specific return type in a subclass for an overridden method.
+ *
+ * <p>When this annotation is present, the toolchain is required to generate on-device bytecode for
+ * an overloaded implementation of the method which is marked as synthetic, returns the more
+ * specific type given in {@link CovariantReturnType#returnType()}, and which delegates to the
+ * method being annotated.
+ *
+ * <p>At some future point in time the public Android API can change so that the public API method
+ * returns the new type. Android platform developers can be sure that all releases after the API
+ * version specified in {@link CovariantReturnType#presentAfter()} have the new method signature on
+ * device and will therefore be compatible with code compiled against the newest public Android API
+ * stubs.
+ *
+ * <p>Once the actual method signature is updated to the new form and this annotation is removed
+ * there will be a synthetic overload for the method with the more general type provided (as normal)
+ * by the Java compiler ensuring compatibility with code compiled against the old stubs.
+ *
+ * <p>When adding this annotation to platform classes the developer should also add CTS tests to
+ * ensure the expected methods are present on all Android devices.
+ *
+ * <p>Notes on scope and limitations:
+ * <ul>
+ * <li>This annotation must have no effect on generated API stubs.</li>
+ * <li>This annotation does not allow the declared exceptions to be made more specific for the
+ * generated synthetic method. This could be added later.</li>
+ * <li>Any type parameters on the annotated method need not be copied.</li>
+ * <li>This annotation is <em>not</em> expected to be treated by the toolchain as inherited. All
+ * layers of platform class hierarchy must specify {@link CovariantReturnType} for all the overloads
+ * that have to be generated. The annotation is marked as repeatable for this reason.</li>
+ * </ul>
+ *
+ * @hide
+ */
+@Repeatable(CovariantReturnType.CovariantReturnTypes.class)
+@Retention(RetentionPolicy.CLASS)
+@Target({ ElementType.METHOD})
+public @interface CovariantReturnType {
+
+ /**
+ * The return type of the synthetic method to generate. Must be a subclass of the return type
+ * of the method being annotated.
+ */
+ Class<?> returnType();
+
+ /**
+ * The last Android API level not to have the generated synthetic method. The annotation can be
+ * removed and the actual return type updated when support for this API level is dropped.
+ */
+ int presentAfter();
+
+ /** @hide */
+ @Retention(RetentionPolicy.CLASS)
+ @Target({ElementType.METHOD})
+ @interface CovariantReturnTypes {
+ CovariantReturnType[] value();
+ }
+}
diff --git a/dalvik/src/main/java/dalvik/system/BlockGuard.java b/dalvik/src/main/java/dalvik/system/BlockGuard.java
index 6426bd8..b0ffecc 100644
--- a/dalvik/src/main/java/dalvik/system/BlockGuard.java
+++ b/dalvik/src/main/java/dalvik/system/BlockGuard.java
@@ -16,23 +16,20 @@
package dalvik.system;
-import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.net.SocketException;
+import libcore.util.NonNull;
+
+import java.util.Objects;
/**
- * Mechanism to let threads set restrictions on what code is allowed
- * to do in their thread.
- *
- * <p>This is meant for applications to prevent certain blocking
- * operations from running on their main event loop (or "UI") threads.
- *
- * <p>Note that this is all best-effort to catch most accidental mistakes
- * and isn't intended to be a perfect mechanism, nor provide any sort of
- * security.
+ * Interface that enables {@code StrictMode} to install callbacks to implement
+ * its policy detection and penalty behavior in {@code libcore} code.
+ * <p>
+ * The framework separately defines {@code StrictMode.ThreadPolicy} and
+ * {@code StrictMode.VmPolicy}, so we mirror that separation here; the former is
+ * designed for per-thread policies, and the latter for process-wide policies.
+ * <p>
+ * Note that this is all best-effort to catch most accidental mistakes and isn't
+ * intended to be a perfect mechanism, nor provide any sort of security.
*
* @hide
*/
@@ -41,14 +38,9 @@
// TODO: refactor class name to something more generic, since its scope is
// growing beyond just blocking/logging.
- public static final int DISALLOW_DISK_WRITE = 0x01;
- public static final int DISALLOW_DISK_READ = 0x02;
- public static final int DISALLOW_NETWORK = 0x04;
- public static final int PASS_RESTRICTIONS_VIA_RPC = 0x08;
- public static final int PENALTY_LOG = 0x10;
- public static final int PENALTY_DIALOG = 0x20;
- public static final int PENALTY_DEATH = 0x40;
-
+ /**
+ * Per-thread interface used to implement {@code StrictMode.ThreadPolicy}.
+ */
public interface Policy {
/**
* Called on disk writes.
@@ -71,6 +63,11 @@
void onUnbufferedIO();
/**
+ * Called on explicit GC request, i.e. Runtime.gc().
+ */
+ void onExplicitGc();
+
+ /**
* Returns the policy bitmask, for shipping over Binder calls
* to remote threads/processes and reinstantiating the policy
* there. The bits in the mask are from the DISALLOW_* and
@@ -79,6 +76,36 @@
int getPolicyMask();
}
+ /**
+ * Per-process interface used to implement {@code StrictMode.VmPolicy}.
+ */
+ public interface VmPolicy {
+ /**
+ * Called by core libraries code when the given path is accessed. This
+ * allows an implementation to alert developers to unexpected path
+ * access, such as trying to access encrypted files before the
+ * encryption key has been installed.
+ * <p>
+ * This only needs to be called once when a path is first accessed by
+ * the process; it doesn't need to be invoked for each subsequent
+ * read/write. (In contrast, we always need to call the per-thread
+ * policy for every read/write, since ownership of an open file can move
+ * between threads.)
+ * <p>
+ * Note that this is all best-effort to catch most accidental mistakes
+ * and isn't intended to be a perfect mechanism, nor provide any sort of
+ * security.
+ *
+ * @param path The path in the local file system that is being accessed
+ * for reading or writing.
+ */
+ void onPathAccess(String path);
+ }
+
+ /**
+ * @deprecated no longer actively used, but kept intact for greylist.
+ */
+ @Deprecated
public static class BlockGuardPolicyException extends RuntimeException {
// bitmask of DISALLOW_*, PENALTY_*, etc flags
private final int mPolicyState;
@@ -117,17 +144,29 @@
}
/**
- * The default, permissive policy that doesn't prevent any operations.
+ * The default, permissive per-thread policy.
*/
public static final Policy LAX_POLICY = new Policy() {
- public void onWriteToDisk() {}
- public void onReadFromDisk() {}
- public void onNetwork() {}
- public void onUnbufferedIO() {}
- public int getPolicyMask() {
- return 0;
- }
- };
+ @Override public String toString() { return "LAX_POLICY"; }
+ @Override public void onWriteToDisk() {}
+ @Override public void onReadFromDisk() {}
+ @Override public void onNetwork() {}
+ @Override public void onUnbufferedIO() {}
+ @Override public void onExplicitGc() {}
+
+ @Override
+ public int getPolicyMask() {
+ return 0;
+ }
+ };
+
+ /**
+ * The default, permissive per-process policy.
+ */
+ public static final VmPolicy LAX_VM_POLICY = new VmPolicy() {
+ @Override public String toString() { return "LAX_VM_POLICY"; }
+ @Override public void onPathAccess(String path) {}
+ };
private static ThreadLocal<Policy> threadPolicy = new ThreadLocal<Policy>() {
@Override protected Policy initialValue() {
@@ -135,27 +174,52 @@
}
};
+ private static volatile VmPolicy vmPolicy = LAX_VM_POLICY;
+
/**
- * Get the current thread's policy.
+ * Get the per-thread policy for the current thread.
*
- * @return the current thread's policy. Never returns null.
- * Will return the LAX_POLICY instance if nothing else is set.
+ * @return the current thread's policy. Will return the {@link #LAX_POLICY}
+ * instance if nothing else is set.
*/
- public static Policy getThreadPolicy() {
+ public static @NonNull Policy getThreadPolicy() {
return threadPolicy.get();
}
/**
- * Sets the current thread's block guard policy.
+ * Sets the per-thread policy for the current thread.
+ * <p>
+ * This should only be called by {@code StrictMode}, since there can only be
+ * one policy active at any given time.
*
- * @param policy policy to set. May not be null. Use the public LAX_POLICY
- * if you want to unset the active policy.
+ * @param policy policy to set. Use the public {@link #LAX_POLICY} if you
+ * want to unset the active policy.
*/
- public static void setThreadPolicy(Policy policy) {
- if (policy == null) {
- throw new NullPointerException("policy == null");
- }
- threadPolicy.set(policy);
+ public static void setThreadPolicy(@NonNull Policy policy) {
+ threadPolicy.set(Objects.requireNonNull(policy));
+ }
+
+ /**
+ * Get the per-process policy for the current process.
+ *
+ * @return the current process's policy. Will return the
+ * {@link #LAX_VM_POLICY} instance if nothing else is set.
+ */
+ public static @NonNull VmPolicy getVmPolicy() {
+ return vmPolicy;
+ }
+
+ /**
+ * Set the per-process policy for the current process.
+ * <p>
+ * This should only be called by {@code StrictMode}, since there can only be
+ * one policy active at any given time.
+ *
+ * @param policy policy to set. Use the public {@link #LAX_VM_POLICY} if you
+ * want to unset the active policy.
+ */
+ public static void setVmPolicy(@NonNull VmPolicy policy) {
+ vmPolicy = Objects.requireNonNull(policy);
}
private BlockGuard() {}
diff --git a/dalvik/src/main/java/dalvik/system/DexFile.java b/dalvik/src/main/java/dalvik/system/DexFile.java
index afedba5..7c1987f 100644
--- a/dalvik/src/main/java/dalvik/system/DexFile.java
+++ b/dalvik/src/main/java/dalvik/system/DexFile.java
@@ -455,16 +455,6 @@
*/
public static final int DEX2OAT_FOR_FILTER = 3;
- /**
- * dex2oat should be run to update the apk/jar because the existing code
- * is not relocated to match the boot image.
- *
- * See {@link #getDexOptNeeded(String, String, String, boolean, boolean)}.
- *
- * @hide
- */
- public static final int DEX2OAT_FOR_RELOCATION = 4;
-
/**
* Calls {@link #getDexOptNeeded(String, String, String, String, String, boolean, boolean)}
diff --git a/dalvik/src/main/java/dalvik/system/RuntimeHooks.java b/dalvik/src/main/java/dalvik/system/RuntimeHooks.java
new file mode 100644
index 0000000..2bfa731
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/system/RuntimeHooks.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.system;
+
+import java.util.Objects;
+import java.util.TimeZone;
+import java.util.function.Supplier;
+
+/**
+ * Provides lifecycle methods and other hooks for an Android runtime "container" to call into the
+ * runtime and core libraries during initialization. For example, from
+ * {@link com.android.internal.os.RuntimeInit}.
+ *
+ * <p>Having a facade class helps to limit the container's knowledge of runtime and core libraries
+ * internal details. All methods assume the container initialization is single threaded.
+ *
+ * @hide
+ */
+public final class RuntimeHooks {
+
+ private static Supplier<String> zoneIdSupplier;
+
+ private RuntimeHooks() {
+ // No need to construct an instance. All methods are static.
+ }
+
+ /**
+ * Sets the {@link Supplier} that is used by {@link TimeZone} to retrieve the current time zone
+ * ID iff the cached default is {@code null}.
+ *
+ * <p>This method also clears the current {@link TimeZone} default ensuring that the supplier
+ * will be used next time {@link TimeZone#getDefault()} is called (unless
+ * {@link TimeZone#setDefault(TimeZone)} is called with a non-null value in the interim).
+ *
+ * <p>Once set the supplier cannot be changed.
+ */
+ public static void setTimeZoneIdSupplier(Supplier<String> zoneIdSupplier) {
+ if (RuntimeHooks.zoneIdSupplier != null) {
+ throw new UnsupportedOperationException("zoneIdSupplier instance already set");
+ }
+ RuntimeHooks.zoneIdSupplier = Objects.requireNonNull(zoneIdSupplier);
+ TimeZone.setDefault(null);
+ }
+
+ /**
+ * Returns the {@link Supplier} that should be used to discover the time zone.
+ */
+ public static Supplier<String> getTimeZoneIdSupplier() {
+ return RuntimeHooks.zoneIdSupplier;
+ }
+
+ /**
+ * Sets an {@link Thread.UncaughtExceptionHandler} that will be called before any
+ * returned by {@link Thread#getUncaughtExceptionHandler()}. To allow the standard
+ * handlers to run, this handler should never terminate this process. Any
+ * throwables thrown by the handler will be ignored by
+ * {@link Thread#dispatchUncaughtException(Throwable)}.
+ */
+ public static void setUncaughtExceptionPreHandler(
+ Thread.UncaughtExceptionHandler uncaughtExceptionHandler) {
+ Thread.setUncaughtExceptionPreHandler(uncaughtExceptionHandler);
+ }
+}
diff --git a/dalvik/src/main/java/dalvik/system/ZygoteHooks.java b/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
index 61c1b95..bd19454 100644
--- a/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
+++ b/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
@@ -16,6 +16,10 @@
package dalvik.system;
+import android.icu.impl.CacheValue;
+import android.icu.text.DecimalFormatSymbols;
+import android.icu.util.ULocale;
+
import java.io.File;
/**
@@ -34,6 +38,46 @@
public static native void startZygoteNoThreadCreation();
/**
+ * Called when the zygote begins preloading classes and data.
+ */
+ public static void onBeginPreload() {
+ // Pin ICU data in memory from this point that would normally be held by soft references.
+ // Without this, any references created immediately below or during class preloading
+ // would be collected when the Zygote GC runs in gcAndFinalize().
+ CacheValue.setStrength(CacheValue.Strength.STRONG);
+
+ // Explicitly exercise code to cache data apps are likely to need.
+ ULocale[] localesToPin = { ULocale.ROOT, ULocale.US, ULocale.getDefault() };
+ for (ULocale uLocale : localesToPin) {
+ new DecimalFormatSymbols(uLocale);
+ }
+ }
+
+ /**
+ * Called when the zygote has completed preloading classes and data.
+ */
+ public static void onEndPreload() {
+ // All cache references created by ICU from this point will be soft.
+ CacheValue.setStrength(CacheValue.Strength.SOFT);
+ }
+
+ /**
+ * Runs several special GCs to try to clean up a few generations of
+ * softly- and final-reachable objects, along with any other garbage.
+ * This is only useful just before a fork().
+ */
+ public static void gcAndFinalize() {
+ final VMRuntime runtime = VMRuntime.getRuntime();
+
+ /* runFinalizationSync() lets finalizers be called in Zygote,
+ * which doesn't have a HeapWorker thread.
+ */
+ System.gc();
+ runtime.runFinalizationSync();
+ System.gc();
+ }
+
+ /**
* Called by the zygote when startup is finished. It marks the point when it is
* conceivable that threads would be started again, e.g., restarting daemons.
*/
@@ -41,8 +85,8 @@
/**
* Called by the zygote prior to every fork. Each call to {@code preFork}
- * is followed by a matching call to {@link #postForkChild(int, String)} on the child
- * process and {@link #postForkCommon()} on both the parent and the child
+ * is followed by a matching call to {@link #postForkChild(int, boolean, boolean, String)} on
+ * the child process and {@link #postForkCommon()} on both the parent and the child
* process. {@code postForkCommon} is called after {@code postForkChild} in
* the child process.
*/
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index 1343edc..e3e36aa 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -1526,15 +1526,6 @@
"com.google.security.wycheproof.RsaEncryptionTest#testGetExceptionsOAEP"
]
},
-/* TODO(flooey): Remove when referenced BoringSSL change is merged */
-{
- description: "Test crashes due to BoringSSL bug fixed in 61dedd68",
- bug: 36636626,
- result: EXEC_FAILED,
- names: [
- "com.google.security.wycheproof.EcdhTest#testModifiedPublicSpec"
- ]
-},
{
description: "Bullhead kernel does not block send when buffer is supposed to have saturated",
bug: 36691333,
diff --git a/expectations/virtualdeviceknownfailures.txt b/expectations/virtualdeviceknownfailures.txt
index 300bfde..66b67e4 100644
--- a/expectations/virtualdeviceknownfailures.txt
+++ b/expectations/virtualdeviceknownfailures.txt
@@ -22,5 +22,13 @@
"org.apache.harmony.tests.java.net.MulticastSocketTest#test_setLoopbackModeSendReceive_IPv4"
],
bug: 35922755
+},
+{
+ description: "Kernels between 4.4 and 4.9 interpret the backlog parameter differently than we
+ expect, causing this test to fail, and our emulators currently use those kernel
+ versions. See b/31960002 for a full discussion and references to the upstream
+ changes.",
+ name: "libcore.javax.net.ServerSocketFactoryTest#testCreateServerSocketWithPortNoBacklog",
+ bug: 73535217
}
]
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java
index f5d4163..477a8e2 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java
@@ -99,7 +99,6 @@
}
thread.interrupt();
- //process.destroy();
try {
Thread.sleep(100);
} catch(InterruptedException ie) {
@@ -107,6 +106,9 @@
}
assertTrue(isThrown);
+ // Destroy process, otherwise it will run until 1000 seconds
+ // have elapsed but we don't need it again for this test.
+ process.destroy();
}
public void testPwd() throws IOException, InterruptedException {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessTest.java
index cf6f89e..49444b4 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessTest.java
@@ -131,6 +131,10 @@
process.exitValue();
fail();
} catch(IllegalThreadStateException expected) {
+ } finally {
+ // Destroy process, otherwise it will run until 3000 seconds
+ // have elapsed but we don't need it again for this test.
+ process.destroy();
}
}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigDecimalTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigDecimalTest.java
index 41ef93e..2e66416 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigDecimalTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigDecimalTest.java
@@ -912,11 +912,9 @@
((notrailingzerotest.stripTrailingZeros()).scale() == 0)
);
- // BEGIN Android-changed: preserve RI compatibility, so BigDecimal.equals (which checks
- // value *and* scale) continues to work. https://issues.apache.org/jira/browse/HARMONY-4623
- /* Zero */
BigDecimal zerotest = new BigDecimal("0.0000");
- assertEquals("stripTrailingZero failed for 0.0000", 4, zerotest.stripTrailingZeros().scale());
+ assertEquals("stripTrailingZero failed for 0.0000", 0,
+ zerotest.stripTrailingZeros().scale());
}
public void testMathContextConstruction() {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigIntegerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigIntegerTest.java
index 337e7c4..b9ee1c6 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigIntegerTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigIntegerTest.java
@@ -301,6 +301,7 @@
/**
* @tests java.math.BigInteger#negate()
*/
+ @SuppressWarnings("ConstantOverflow")
public void test_negate() {
assertTrue("Single negation of zero did not result in zero", zero
.negate().equals(zero));
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteBufferTest.java
index db09af8..756c9c8 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteBufferTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteBufferTest.java
@@ -55,6 +55,32 @@
super.tearDown();
}
+ public void testAllocateDirect() {
+ try {
+ ByteBuffer.allocateDirect(-1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ checkAllocateDirect(0);
+ checkAllocateDirect(1);
+ checkAllocateDirect(2);
+ checkAllocateDirect(1 << 16);
+ checkAllocateDirect(123456);
+ }
+
+ private void checkAllocateDirect(int capacity) {
+ ByteBuffer b = ByteBuffer.allocateDirect(capacity);
+ assertEquals(capacity, b.capacity());
+ assertEquals(0, b.position());
+ assertEquals(capacity, b.limit());
+ assertContentEquals(b, new byte[capacity], 0, capacity);
+ try {
+ b.reset();
+ fail();
+ } catch (InvalidMarkException expected) {
+ }
+ }
+
public void testArray() {
if (buf.hasArray()) {
byte array[] = buf.array();
@@ -2085,21 +2111,21 @@
}
}
- private void assertContentEquals(ByteBuffer buf, byte array[],
+ private static void assertContentEquals(ByteBuffer buf, byte array[],
int offset, int length) {
for (int i = 0; i < length; i++) {
assertEquals(buf.get(i), array[offset + i]);
}
}
- private void assertContentEquals(ByteBuffer buf, ByteBuffer other) {
+ private static void assertContentEquals(ByteBuffer buf, ByteBuffer other) {
assertEquals(buf.capacity(), other.capacity());
for (int i = 0; i < buf.capacity(); i++) {
assertEquals(buf.get(i), other.get(i));
}
}
- private void assertContentLikeTestData1(ByteBuffer buf,
+ private static void assertContentLikeTestData1(ByteBuffer buf,
int startIndex, byte startValue, int length) {
byte value = startValue;
for (int i = 0; i < length; i++) {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DoubleBufferTest.java
index 3c634f3..6ae5eb4 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DoubleBufferTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DoubleBufferTest.java
@@ -208,6 +208,17 @@
.compareTo(dbuffer3));
}
+ public void testCompareTo_positiveAndNegativeZero() {
+ double negativeZero = Double.parseDouble("-0");
+ double positiveZero = Double.parseDouble("+0");
+ DoubleBuffer negativeZeroBuffer = DoubleBuffer.wrap(new double[] { negativeZero });
+ DoubleBuffer positiveZeroBuffer = DoubleBuffer.wrap(new double[] { positiveZero });
+ assertTrue(Double.compare(negativeZero, positiveZero) < 0); // sanity check
+
+ // Unlike Double.compare(), DoubleBuffer.compareTo() considers -0 == +0
+ assertEquals(0, negativeZeroBuffer.compareTo(positiveZeroBuffer));
+ }
+
public void testDuplicate() {
buf.clear();
buf.mark();
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java
index 89ed576..c8c5da9 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java
@@ -378,87 +378,6 @@
}
}
-
- /**
- * java.util.jar.JarFile#getJarEntry(java.lang.String)
- */
- public void testGetJarEntry() throws Exception {
- File file = Support_Resources.copyFile(resources, null, jarName);
- JarFile jarFile = new JarFile(file);
- assertEquals("Error in returned entry", 311, jarFile.getEntry(
- entryName).getSize());
- jarFile.close();
-
- // tests for signed jars
- // test all signed jars in the /Testres/Internal/SignedJars directory
- String jarDirUrl = Support_Resources
- .getResourceURL("/../internalres/signedjars");
- Vector<String> signedJars = new Vector<String>();
- try {
- InputStream is = new URL(jarDirUrl + "/jarlist.txt").openStream();
- while (is.available() > 0) {
- StringBuilder linebuff = new StringBuilder(80); // Typical line
- // length
- done: while (true) {
- int nextByte = is.read();
- switch (nextByte) {
- case -1:
- break done;
- case (byte) '\r':
- if (linebuff.length() == 0) {
- // ignore
- }
- break done;
- case (byte) '\n':
- if (linebuff.length() == 0) {
- // ignore
- }
- break done;
- default:
- linebuff.append((char) nextByte);
- }
- }
- if (linebuff.length() == 0) {
- break;
- }
- String line = linebuff.toString();
- signedJars.add(line);
- }
- is.close();
- } catch (IOException e) {
- // no list of jars found
- }
-
- for (int i = 0; i < signedJars.size(); i++) {
- String jarName = signedJars.get(i);
- try {
- file = Support_Resources.getExternalLocalFile(jarDirUrl
- + "/" + jarName);
- jarFile = new JarFile(file, true);
- boolean foundCerts = false;
- Enumeration<JarEntry> e = jarFile.entries();
- while (e.hasMoreElements()) {
- JarEntry entry = e.nextElement();
- InputStream is = jarFile.getInputStream(entry);
- is.skip(100000);
- is.close();
- Certificate[] certs = entry.getCertificates();
- if (certs != null && certs.length > 0) {
- foundCerts = true;
- break;
- }
- }
- assertTrue(
- "No certificates found during signed jar test for jar \""
- + jarName + "\"", foundCerts);
- jarFile.close();
- } catch (IOException e) {
- fail("Exception during signed jar test for jar \"" + jarName
- + "\": " + e.toString());
- }
- }
- }
-
/**
* java.util.jar.JarFile#getManifest()
*/
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/Matcher2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/Matcher2Test.java
index e84b356..57cc65f 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/Matcher2Test.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/Matcher2Test.java
@@ -4,9 +4,9 @@
* The ASF licenses this file to You 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.
@@ -216,9 +216,6 @@
}
}
- /*
- * Regression test for HARMONY-997
- */
public void testReplacementBackSlash() {
String str = "replace me";
String replacedString = "me";
@@ -227,8 +224,29 @@
Matcher mat = pat.matcher(str);
try {
mat.replaceAll(substitutionString);
- fail("IndexOutOfBoundsException should be thrown");
- } catch (IndexOutOfBoundsException e) {
+ fail("IllegalArgumentException should be thrown");
+ } catch (IllegalArgumentException e) {
}
}
+
+ public void testAppendReplacement_replacementEndsWithBackslash() {
+ Matcher matcher = Pattern.compile("Hello").matcher("Hello, world!");
+ matcher.find();
+ try {
+ matcher.appendReplacement(new StringBuffer(), "replacement\\");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testAppendReplacement_replacementEndsWithDollar() {
+ Matcher matcher = Pattern.compile("Hello").matcher("Hello, world!");
+ matcher.find();
+ try {
+ matcher.appendReplacement(new StringBuffer(), "replacement$");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java
index 98508e1..276617b 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java
@@ -143,6 +143,24 @@
assertEquals("zzzcatzzzdogzzz", mat.replaceFirst("cat"));
}
+ public void testReplaceFirst_null_match() {
+ Matcher matcher = Pattern.compile("Hello").matcher("Hello, world!");
+ try {
+ matcher.replaceFirst(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testReplaceFirst_null_nomatch() {
+ Matcher matcher = Pattern.compile("not found").matcher("Hello, world!");
+ try {
+ matcher.replaceFirst(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
public void testPattern() {
for (String element : testPatterns) {
Pattern test = Pattern.compile(element);
@@ -420,6 +438,38 @@
}
}
+ public void testEnd_groupIndexOutOfBounds() {
+ Matcher matcher = Pattern.compile("(Hello)").matcher("Hello, world!");
+ assertTrue(matcher.find());
+ try {
+ matcher.end(-1 /* out of bounds */);
+ } catch (IndexOutOfBoundsException expected) {
+ assertFalse(expected instanceof ArrayIndexOutOfBoundsException);
+ }
+
+ try {
+ matcher.end(2 /* out of bounds */);
+ } catch (IndexOutOfBoundsException expected) {
+ assertFalse(expected instanceof ArrayIndexOutOfBoundsException);
+ }
+ }
+
+ public void testStart_groupIndexOutOfBounds() {
+ Matcher matcher = Pattern.compile("(Hello)").matcher("Hello, world!");
+ assertTrue(matcher.find());
+ try {
+ matcher.start(-1 /* out of bounds */);
+ } catch (IndexOutOfBoundsException expected) {
+ assertFalse(expected instanceof ArrayIndexOutOfBoundsException);
+ }
+
+ try {
+ matcher.start(2 /* out of bounds */);
+ } catch (IndexOutOfBoundsException expected) {
+ assertFalse(expected instanceof ArrayIndexOutOfBoundsException);
+ }
+ }
+
public void testEnhancedFind() {
String input = "foob";
String pattern = "a*b";
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ModeTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ModeTest.java
index c34cebe..f696dff8 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ModeTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ModeTest.java
@@ -4,9 +4,9 @@
* The ASF licenses this file to You 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.
@@ -27,6 +27,7 @@
*/
@SuppressWarnings("nls")
public class ModeTest extends TestCase {
+
public void testCase() throws PatternSyntaxException {
Pattern p;
Matcher m;
@@ -37,6 +38,7 @@
assertEquals("dog", m.group(1));
assertFalse(m.find());
+
p = Pattern.compile("([a-z]+)[0-9]+", Pattern.CASE_INSENSITIVE);
m = p.matcher("cAt123#doG345");
assertTrue(m.find());
@@ -45,6 +47,7 @@
assertEquals("doG", m.group(1));
assertFalse(m.find());
+
p = Pattern.compile("(?i)([a-z]+)[0-9]+");
m = p.matcher("cAt123#doG345");
assertTrue(m.find());
@@ -67,6 +70,7 @@
m = p.matcher("barfoo");
assertFalse(m.find());
+
p = Pattern.compile("foo$");
m = p.matcher("foobar");
assertFalse(m.find());
@@ -76,6 +80,7 @@
assertTrue(m.start() == 3 && m.end() == 6);
assertFalse(m.find());
+
p = Pattern.compile("^foo([0-9]*)", Pattern.MULTILINE);
m = p.matcher("foo1bar\nfoo2foo3\nbarfoo4");
assertTrue(m.find());
@@ -84,6 +89,7 @@
assertEquals("2", m.group(1));
assertFalse(m.find());
+
p = Pattern.compile("foo([0-9]*)$", Pattern.MULTILINE);
m = p.matcher("foo1bar\nfoo2foo3\nbarfoo4");
assertTrue(m.find());
@@ -92,6 +98,7 @@
assertEquals("4", m.group(1));
assertFalse(m.find());
+
p = Pattern.compile("(?m)^foo([0-9]*)");
m = p.matcher("foo1bar\nfoo2foo3\nbarfoo4");
assertTrue(m.find());
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ReplaceTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ReplaceTest.java
index 1eac3f3..2226df8 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ReplaceTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ReplaceTest.java
@@ -4,9 +4,9 @@
* The ASF licenses this file to You 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.
@@ -28,15 +28,15 @@
public void testSimpleReplace() throws PatternSyntaxException {
String target, pattern, repl;
- target = "foobarfobarfoofo1";
+ target = "foobarfobarfoofo1barfort";
pattern = "fo[^o]";
repl = "xxx";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(target);
- assertEquals("foobarxxxarfoofo1", m.replaceFirst(repl));
- assertEquals("foobarxxxarfooxxx", m.replaceAll(repl));
+ assertEquals("foobarxxxarfoofo1barfort", m.replaceFirst(repl));
+ assertEquals("foobarxxxarfooxxxbarxxxt", m.replaceAll(repl));
}
public void testCaptureReplace() {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/SplitTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/SplitTest.java
index 5a5bc2b..4818106 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/SplitTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/SplitTest.java
@@ -17,13 +17,16 @@
package org.apache.harmony.tests.java.util.regex;
+import java.util.Arrays;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import junit.framework.TestCase;
+import java.util.regex.*;
/**
* TODO Type description
+ *
*/
@SuppressWarnings("nls")
public class SplitTest extends TestCase {
@@ -32,9 +35,52 @@
Pattern p = Pattern.compile("/");
String[] results = p.split("have/you/done/it/right");
String[] expected = new String[] { "have", "you", "done", "it", "right" };
- assertEquals(expected.length, results.length);
+ assertArraysEqual(expected, results);
+ }
+
+ @SuppressWarnings("InvalidPatternSyntax")
+ public void testEmptySplits() {
+ // Trailing empty matches are removed.
+ assertArraysEqual(new String[0], "hello".split("."));
+ assertArraysEqual(new String[] { "1", "2" }, "1:2:".split(":"));
+ // ...including when that results in an empty result.
+ assertArraysEqual(new String[0], ":".split(":"));
+ // ...but not when limit < 0.
+ assertArraysEqual(new String[] { "1", "2", "" }, "1:2:".split(":", -1));
+
+ // Leading empty matches are retained.
+ assertArraysEqual(new String[] { "", "", "o" }, "hello".split(".."));
+
+ // A separator that doesn't occur in the input gets you the input.
+ assertArraysEqual(new String[] { "hello" }, "hello".split("not-present-in-test"));
+ // ...including when the input is the empty string.
+ // (Perl returns an empty list instead.)
+ assertArraysEqual(new String[] { "" }, "".split("not-present-in-test"));
+ assertArraysEqual(new String[] { "" }, "".split("A?"));
+
+ // The limit argument controls the size of the result.
+ // If l == 0, the result is as long as needed, except trailing empty matches are dropped.
+ // If l < 0, the result is as long as needed, and trailing empty matches are retained.
+ // If l > 0, the result contains the first l matches, plus one string containing the remaining input.
+ // Examples without a trailing separator (and hence without a trailing empty match):
+ assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", 0));
+ assertArraysEqual(new String[] { "a,b,c" }, "a,b,c".split(",", 1));
+ assertArraysEqual(new String[] { "a", "b,c" }, "a,b,c".split(",", 2));
+ assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", 3));
+ assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", Integer.MAX_VALUE));
+ // Examples with a trailing separator (and hence possibly with a trailing empty match):
+ assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c,".split(",", 0));
+ assertArraysEqual(new String[] { "a,b,c," }, "a,b,c,".split(",", 1));
+ assertArraysEqual(new String[] { "a", "b,c," }, "a,b,c,".split(",", 2));
+ assertArraysEqual(new String[] { "a", "b", "c," }, "a,b,c,".split(",", 3));
+ assertArraysEqual(new String[] { "a", "b", "c", "" }, "a,b,c,".split(",", Integer.MAX_VALUE));
+ assertArraysEqual(new String[] { "a", "b", "c", "" }, "a,b,c,".split(",", -1));
+ }
+
+ private void assertArraysEqual(String[] expected, String[] actual) {
+ assertEquals(expected.length, actual.length);
for (int i = 0; i < expected.length; i++) {
- assertEquals(results[i], expected[i]);
+ assertEquals(Integer.toString(i), expected[i], actual[i]);
}
}
@@ -131,41 +177,23 @@
public void testSplit2() {
Pattern p = Pattern.compile("");
- String s[];
- s = p.split("a", -1);
- assertEquals(3, s.length);
- assertEquals("", s[0]);
- assertEquals("a", s[1]);
- assertEquals("", s[2]);
+ assertEquals(Arrays.asList("a", ""), Arrays.asList(p.split("a", -1)));
+ assertEquals(Arrays.asList(""), Arrays.asList(p.split("", -1)));
+ assertEquals(Arrays.asList("a", "b", "c", "d", ""), Arrays.asList(p.split("abcd", -1)));
- s = p.split("", -1);
- assertEquals(1, s.length);
- assertEquals("", s[0]);
-
- s = p.split("abcd", -1);
- assertEquals(6, s.length);
- assertEquals("", s[0]);
- assertEquals("a", s[1]);
- assertEquals("b", s[2]);
- assertEquals("c", s[3]);
- assertEquals("d", s[4]);
- assertEquals("", s[5]);
+ // Regression test for Android
+ assertEquals("GOOG,23,500".split("|").length, 11);
}
+
public void testSplitSupplementaryWithEmptyString() {
-
/*
- * See http://www.unicode.org/reports/tr18/#Supplementary_Characters We
- * have to treat text as code points not code units.
+ * See http://www.unicode.org/reports/tr18/#Supplementary_Characters
+ * We have to treat text as code points not code units.
*/
Pattern p = Pattern.compile("");
- String s[];
- s = p.split("a\ud869\uded6b", -1);
- assertEquals(5, s.length);
- assertEquals("", s[0]);
- assertEquals("a", s[1]);
- assertEquals("\ud869\uded6", s[2]);
- assertEquals("b", s[3]);
- assertEquals("", s[4]);
+ String[] s = p.split("a\ud869\uded6b", -1);
+ assertEquals(Arrays.asList("a", "\ud869\uded6", "b", ""), Arrays.asList(s));
}
+
}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterInputStreamTest.java
index 6109762..58cdf52 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterInputStreamTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterInputStreamTest.java
@@ -488,8 +488,8 @@
}
// http://b/26462400
- public void testInflaterInputStreamWithExternalInflater() throws Exception {
- InputStream base = new ByteArrayInputStream(new byte[] { 'h', 'i'});
+ public void testInflaterInputStreamWithExternalInflater_3ArgConstructor() throws Exception {
+ InputStream base = new ByteArrayInputStream(new byte[]{'h', 'i'});
Inflater inf = new Inflater();
InflaterInputStream iis = new InflaterInputStream(base, inf, 512);
@@ -497,17 +497,21 @@
try {
inf.reset();
fail();
- } catch (IllegalStateException espected) {
+ } catch (NullPointerException expected) {
// Expected because the inflater should've been closed when the stream was.
}
+ }
- inf = new Inflater();
- iis = new InflaterInputStream(base, inf);
+ // http://b/26462400
+ public void testInflaterInputStreamWithExternalInflater_2ArgConstructor() throws Exception {
+ InputStream base = new ByteArrayInputStream(new byte[]{'h', 'i'});
+ Inflater inf = new Inflater();
+ InflaterInputStream iis = new InflaterInputStream(base, inf);
iis.close();
try {
inf.reset();
fail();
- } catch (IllegalStateException espected) {
+ } catch (NullPointerException expected) {
// Expected because the inflater should've been closed when the stream was.
}
}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterTest.java
index a15a5cf..5276246 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterTest.java
@@ -53,11 +53,10 @@
inflate.setInput(byteArray);
inflate.end();
- // Note that the RI throws an NPE here instead of an ISE (???).
try {
inflate.reset();
- inflate.setInput(byteArray);
- } catch (IllegalStateException expected) {
+ } catch (NullPointerException expected) {
+ // Expected
}
Inflater i = new Inflater();
@@ -424,11 +423,11 @@
inflate.end();
try {
inflate.inflate(outPutInf, offSet, 1);
- fail("IllegalStateException expected");
+ fail("NullPointerException expected");
} catch (DataFormatException e) {
fail("Invalid input to be decompressed");
- } catch (IllegalStateException e) {
- //expected
+ } catch (NullPointerException expected) {
+ // Expected
}
}
@@ -1002,9 +1001,9 @@
infl1.end();
try {
infl1.setDictionary(dictionary2.getBytes());
- fail("IllegalStateException expected");
- } catch (IllegalStateException ise) {
- //expected
+ fail("NullPointerException expected");
+ } catch (NullPointerException expected) {
+ // Expected
}
}
@@ -1137,41 +1136,38 @@
try {
inflate.getAdler();
- fail("IllegalStateException expected");
- } catch (IllegalStateException expected) {
- //expected
+ fail("NullPointerException expected");
+ } catch (NullPointerException expected) {
+ // Expected
}
try {
inflate.getBytesRead();
fail("NullPointerException expected");
- } catch (IllegalStateException expected) {
} catch (NullPointerException expected) {
- //expected
+ // Expected
}
try {
inflate.getBytesWritten();
fail("NullPointerException expected");
} catch (NullPointerException expected) {
- } catch (IllegalStateException expected) {
- //expected
+ // Expected
}
try {
inflate.getTotalIn();
- fail("IllegalStateException expected");
- } catch (IllegalStateException ise) {
- //expected
+ fail("NullPointerException expected");
+ } catch (NullPointerException expected) {
+ // Expected
}
try {
inflate.getTotalOut();
- fail("IllegalStateException expected");
- } catch (IllegalStateException ise) {
- //expected
+ fail("NullPointerException expected");
+ } catch (NullPointerException expected) {
+ // Expected
}
-
}
}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipInputStreamTest.java
index 49a15bb..e0b3eb2 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipInputStreamTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipInputStreamTest.java
@@ -234,7 +234,7 @@
if (i != entrySize) {
fail("ZipInputStream.available or ZipInputStream.skip does not " +
"working properly. Only skipped " + i +
- " bytes instead of " + entrySize);
+ " bytes instead of " + entrySize + " for entry " + entry.getName());
}
assertEquals(0, zis1.skip(1));
assertEquals(0, zis1.available());
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java
index f8d2847..930fa3f 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java
@@ -25,8 +25,10 @@
import java.nio.channels.Pipe.SourceChannel;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
@@ -62,7 +64,10 @@
assertEquals(-1, e.getPeerPort());
String[] suites = e.getSupportedCipherSuites();
e.setEnabledCipherSuites(suites);
- assertEquals(e.getEnabledCipherSuites().length, suites.length);
+ // By default, the engine only supports TLS 1.2, so the TLS 1.3 cipher suites
+ // shouldn't be enabled.
+ assertEquals(suites.length - StandardNames.CIPHER_SUITES_TLS13.size(),
+ e.getEnabledCipherSuites().length);
}
/**
@@ -99,7 +104,10 @@
assertEquals(e.getPeerPort(), port);
String[] suites = e.getSupportedCipherSuites();
e.setEnabledCipherSuites(suites);
- assertEquals(e.getEnabledCipherSuites().length, suites.length);
+ // By default, the engine only supports TLS 1.2, so the TLS 1.3 cipher suites
+ // shouldn't be enabled.
+ assertEquals(suites.length - StandardNames.CIPHER_SUITES_TLS13.size(),
+ e.getEnabledCipherSuites().length);
e.setUseClientMode(true);
assertTrue(e.getUseClientMode());
}
@@ -176,8 +184,12 @@
sse.setEnabledCipherSuites(st);
String[] res = sse.getEnabledCipherSuites();
assertNotNull("Null array was returned", res);
- assertEquals("Incorrect array length", res.length, st.length);
- assertTrue("Incorrect array was returned", Arrays.equals(res, st));
+ // By default, the engine only supports TLS 1.2, so the TLS 1.3 cipher suites
+ // shouldn't be enabled.
+ List<String> supported = new ArrayList<>(Arrays.asList(st));
+ supported.removeAll(StandardNames.CIPHER_SUITES_TLS13);
+ assertEquals("Incorrect array length", res.length, supported.size());
+ assertEquals("Incorrect array was returned", Arrays.asList(res), supported);
try {
sse.setEnabledCipherSuites(null);
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java
index 117a1a0..247b4e4 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java
@@ -16,6 +16,8 @@
package org.apache.harmony.tests.javax.net.ssl;
+import java.util.ArrayList;
+import java.util.List;
import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
@@ -31,6 +33,7 @@
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
+import libcore.java.security.StandardNames;
public class SSLServerSocketTest extends TestCase {
@@ -226,8 +229,12 @@
sss.setEnabledCipherSuites(sss.getSupportedCipherSuites());
String[] res = sss.getEnabledCipherSuites();
assertNotNull("NULL result", res);
+ // By default, the socket only supports TLS 1.2, so the TLS 1.3 cipher suites
+ // shouldn't be enabled.
+ List<String> supported = new ArrayList<>(Arrays.asList(sss.getSupportedCipherSuites()));
+ supported.removeAll(StandardNames.CIPHER_SUITES_TLS13);
assertEquals("not all supported cipher suites were enabled",
- Arrays.asList(sss.getSupportedCipherSuites()),
+ supported,
Arrays.asList(res));
}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java
index 5712a48..d30ae53a 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java
@@ -23,8 +23,10 @@
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.security.SecureRandom;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
+import java.util.List;
import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.KeyManager;
@@ -371,8 +373,12 @@
ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
String[] res = ssl.getEnabledCipherSuites();
assertNotNull("NULL result", res);
+ // By default, the socket only supports TLS 1.2, so the TLS 1.3 cipher suites
+ // shouldn't be enabled.
+ List<String> supported = new ArrayList<>(Arrays.asList(ssl.getSupportedCipherSuites()));
+ supported.removeAll(StandardNames.CIPHER_SUITES_TLS13);
assertEquals("not all supported cipher suites were enabled",
- Arrays.asList(ssl.getSupportedCipherSuites()),
+ supported,
Arrays.asList(res));
ssl.close();
}
diff --git a/java_tests_blacklist b/java_tests_blacklist
deleted file mode 100644
index fe3ddc2..0000000
--- a/java_tests_blacklist
+++ /dev/null
@@ -1,2 +0,0 @@
-luni/src/test/java/libcore/java/util/zip/Zip64Test.java
-luni/src/test/java/libcore/java/util/zip/Zip64FileTest.java
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java
index c8d3856..818a3b2 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java
@@ -30,56 +30,55 @@
// }
// for testing subclass access
- // android-note: Removed because android doesn't restrict reflection access
- // static class AtomicIntegerFieldUpdaterTestSubclass extends AtomicIntegerFieldUpdaterTest {
- // public void checkPrivateAccess() {
- // try {
- // AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
- // AtomicIntegerFieldUpdater.newUpdater
- // (AtomicIntegerFieldUpdaterTest.class, "privateField");
- // shouldThrow();
- // } catch (RuntimeException success) {
- // assertNotNull(success.getCause());
- // }
- // }
+ static class AtomicIntegerFieldUpdaterTestSubclass extends AtomicIntegerFieldUpdaterTest {
+ public void checkPrivateAccess() {
+ try {
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
+ AtomicIntegerFieldUpdater.newUpdater
+ (AtomicIntegerFieldUpdaterTest.class, "privateField");
+ shouldThrow();
+ } catch (RuntimeException success) {
+ assertNotNull(success.getCause());
+ }
+ }
- // public void checkCompareAndSetProtectedSub() {
- // AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
- // AtomicIntegerFieldUpdater.newUpdater
- // (AtomicIntegerFieldUpdaterTest.class, "protectedField");
- // this.protectedField = 1;
- // assertTrue(a.compareAndSet(this, 1, 2));
- // assertTrue(a.compareAndSet(this, 2, -4));
- // assertEquals(-4, a.get(this));
- // assertFalse(a.compareAndSet(this, -5, 7));
- // assertEquals(-4, a.get(this));
- // assertTrue(a.compareAndSet(this, -4, 7));
- // assertEquals(7, a.get(this));
- // }
- // }
+ public void checkCompareAndSetProtectedSub() {
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
+ AtomicIntegerFieldUpdater.newUpdater
+ (AtomicIntegerFieldUpdaterTest.class, "protectedField");
+ this.protectedField = 1;
+ assertTrue(a.compareAndSet(this, 1, 2));
+ assertTrue(a.compareAndSet(this, 2, -4));
+ assertEquals(-4, a.get(this));
+ assertFalse(a.compareAndSet(this, -5, 7));
+ assertEquals(-4, a.get(this));
+ assertTrue(a.compareAndSet(this, -4, 7));
+ assertEquals(7, a.get(this));
+ }
+ }
- // static class UnrelatedClass {
- // public void checkPackageAccess(AtomicIntegerFieldUpdaterTest obj) {
- // obj.x = 72;
- // AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
- // AtomicIntegerFieldUpdater.newUpdater
- // (AtomicIntegerFieldUpdaterTest.class, "x");
- // assertEquals(72, a.get(obj));
- // assertTrue(a.compareAndSet(obj, 72, 73));
- // assertEquals(73, a.get(obj));
- // }
+ static class UnrelatedClass {
+ public void checkPackageAccess(AtomicIntegerFieldUpdaterTest obj) {
+ obj.x = 72;
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
+ AtomicIntegerFieldUpdater.newUpdater
+ (AtomicIntegerFieldUpdaterTest.class, "x");
+ assertEquals(72, a.get(obj));
+ assertTrue(a.compareAndSet(obj, 72, 73));
+ assertEquals(73, a.get(obj));
+ }
- // public void checkPrivateAccess(AtomicIntegerFieldUpdaterTest obj) {
- // try {
- // AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
- // AtomicIntegerFieldUpdater.newUpdater
- // (AtomicIntegerFieldUpdaterTest.class, "privateField");
- // throw new AssertionError("should throw");
- // } catch (RuntimeException success) {
- // assertNotNull(success.getCause());
- // }
- // }
- // }
+ public void checkPrivateAccess(AtomicIntegerFieldUpdaterTest obj) {
+ try {
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
+ AtomicIntegerFieldUpdater.newUpdater
+ (AtomicIntegerFieldUpdaterTest.class, "privateField");
+ throw new AssertionError("should throw");
+ } catch (RuntimeException success) {
+ assertNotNull(success.getCause());
+ }
+ }
+ }
AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> updaterFor(String fieldName) {
return AtomicIntegerFieldUpdater.newUpdater
@@ -121,22 +120,20 @@
/**
* construction using private field from subclass throws RuntimeException
*/
- // android-note: Removed because android doesn't restrict reflection access
- // public void testPrivateFieldInSubclass() {
- // AtomicIntegerFieldUpdaterTestSubclass s =
- // new AtomicIntegerFieldUpdaterTestSubclass();
- // s.checkPrivateAccess();
- // }
+ public void testPrivateFieldInSubclass() {
+ AtomicIntegerFieldUpdaterTestSubclass s =
+ new AtomicIntegerFieldUpdaterTestSubclass();
+ s.checkPrivateAccess();
+ }
/**
* construction from unrelated class; package access is allowed,
* private access is not
*/
- // android-note: Removed because android doesn't restrict reflection access
- // public void testUnrelatedClassAccess() {
- // new UnrelatedClass().checkPackageAccess(this);
- // new UnrelatedClass().checkPrivateAccess(this);
- // }
+ public void testUnrelatedClassAccess() {
+ new UnrelatedClass().checkPackageAccess(this);
+ new UnrelatedClass().checkPrivateAccess(this);
+ }
/**
* get returns the last value set or assigned
@@ -203,12 +200,11 @@
* compareAndSet succeeds in changing protected field value if
* equal to expected else fails
*/
- // android-note: Removed because android doesn't restrict reflection access
- // public void testCompareAndSetProtectedInSubclass() {
- // AtomicIntegerFieldUpdaterTestSubclass s =
- // new AtomicIntegerFieldUpdaterTestSubclass();
- // s.checkCompareAndSetProtectedSub();
- // }
+ public void testCompareAndSetProtectedInSubclass() {
+ AtomicIntegerFieldUpdaterTestSubclass s =
+ new AtomicIntegerFieldUpdaterTestSubclass();
+ s.checkCompareAndSetProtectedSub();
+ }
/**
* compareAndSet in one thread enables another waiting for value
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java
index d46280b..69b97bc 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java
@@ -30,56 +30,55 @@
// }
// for testing subclass access
- // android-note: Removed because android doesn't restrict reflection access
- // static class AtomicLongFieldUpdaterTestSubclass extends AtomicLongFieldUpdaterTest {
- // public void checkPrivateAccess() {
- // try {
- // AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
- // AtomicLongFieldUpdater.newUpdater
- // (AtomicLongFieldUpdaterTest.class, "privateField");
- // shouldThrow();
- // } catch (RuntimeException success) {
- // assertNotNull(success.getCause());
- // }
- // }
+ static class AtomicLongFieldUpdaterTestSubclass extends AtomicLongFieldUpdaterTest {
+ public void checkPrivateAccess() {
+ try {
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
+ AtomicLongFieldUpdater.newUpdater
+ (AtomicLongFieldUpdaterTest.class, "privateField");
+ shouldThrow();
+ } catch (RuntimeException success) {
+ assertNotNull(success.getCause());
+ }
+ }
- // public void checkCompareAndSetProtectedSub() {
- // AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
- // AtomicLongFieldUpdater.newUpdater
- // (AtomicLongFieldUpdaterTest.class, "protectedField");
- // this.protectedField = 1;
- // assertTrue(a.compareAndSet(this, 1, 2));
- // assertTrue(a.compareAndSet(this, 2, -4));
- // assertEquals(-4, a.get(this));
- // assertFalse(a.compareAndSet(this, -5, 7));
- // assertEquals(-4, a.get(this));
- // assertTrue(a.compareAndSet(this, -4, 7));
- // assertEquals(7, a.get(this));
- // }
- // }
+ public void checkCompareAndSetProtectedSub() {
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
+ AtomicLongFieldUpdater.newUpdater
+ (AtomicLongFieldUpdaterTest.class, "protectedField");
+ this.protectedField = 1;
+ assertTrue(a.compareAndSet(this, 1, 2));
+ assertTrue(a.compareAndSet(this, 2, -4));
+ assertEquals(-4, a.get(this));
+ assertFalse(a.compareAndSet(this, -5, 7));
+ assertEquals(-4, a.get(this));
+ assertTrue(a.compareAndSet(this, -4, 7));
+ assertEquals(7, a.get(this));
+ }
+ }
- // static class UnrelatedClass {
- // public void checkPackageAccess(AtomicLongFieldUpdaterTest obj) {
- // obj.x = 72L;
- // AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
- // AtomicLongFieldUpdater.newUpdater
- // (AtomicLongFieldUpdaterTest.class, "x");
- // assertEquals(72L, a.get(obj));
- // assertTrue(a.compareAndSet(obj, 72L, 73L));
- // assertEquals(73L, a.get(obj));
- // }
+ static class UnrelatedClass {
+ public void checkPackageAccess(AtomicLongFieldUpdaterTest obj) {
+ obj.x = 72L;
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
+ AtomicLongFieldUpdater.newUpdater
+ (AtomicLongFieldUpdaterTest.class, "x");
+ assertEquals(72L, a.get(obj));
+ assertTrue(a.compareAndSet(obj, 72L, 73L));
+ assertEquals(73L, a.get(obj));
+ }
- // public void checkPrivateAccess(AtomicLongFieldUpdaterTest obj) {
- // try {
- // AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
- // AtomicLongFieldUpdater.newUpdater
- // (AtomicLongFieldUpdaterTest.class, "privateField");
- // throw new AssertionError("should throw");
- // } catch (RuntimeException success) {
- // assertNotNull(success.getCause());
- // }
- // }
- // }
+ public void checkPrivateAccess(AtomicLongFieldUpdaterTest obj) {
+ try {
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
+ AtomicLongFieldUpdater.newUpdater
+ (AtomicLongFieldUpdaterTest.class, "privateField");
+ throw new AssertionError("should throw");
+ } catch (RuntimeException success) {
+ assertNotNull(success.getCause());
+ }
+ }
+ }
AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> updaterFor(String fieldName) {
return AtomicLongFieldUpdater.newUpdater
@@ -121,22 +120,20 @@
/**
* construction using private field from subclass throws RuntimeException
*/
- // android-note: Removed because android doesn't restrict reflection access
- // public void testPrivateFieldInSubclass() {
- // AtomicLongFieldUpdaterTestSubclass s =
- // new AtomicLongFieldUpdaterTestSubclass();
- // s.checkPrivateAccess();
- // }
+ public void testPrivateFieldInSubclass() {
+ AtomicLongFieldUpdaterTestSubclass s =
+ new AtomicLongFieldUpdaterTestSubclass();
+ s.checkPrivateAccess();
+ }
/**
* construction from unrelated class; package access is allowed,
* private access is not
*/
- // android-note: Removed because android doesn't restrict reflection access
- // public void testUnrelatedClassAccess() {
- // new UnrelatedClass().checkPackageAccess(this);
- // new UnrelatedClass().checkPrivateAccess(this);
- // }
+ public void testUnrelatedClassAccess() {
+ new UnrelatedClass().checkPackageAccess(this);
+ new UnrelatedClass().checkPrivateAccess(this);
+ }
/**
* get returns the last value set or assigned
@@ -203,12 +200,11 @@
* compareAndSet succeeds in changing protected field value if
* equal to expected else fails
*/
- // android-note: Removed because android doesn't restrict reflection access
- // public void testCompareAndSetProtectedInSubclass() {
- // AtomicLongFieldUpdaterTestSubclass s =
- // new AtomicLongFieldUpdaterTestSubclass();
- // s.checkCompareAndSetProtectedSub();
- // }
+ public void testCompareAndSetProtectedInSubclass() {
+ AtomicLongFieldUpdaterTestSubclass s =
+ new AtomicLongFieldUpdaterTestSubclass();
+ s.checkCompareAndSetProtectedSub();
+ }
/**
* compareAndSet in one thread enables another waiting for value
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java
index 9b2e9a9..a662e11 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java
@@ -32,56 +32,55 @@
// }
// for testing subclass access
- // android-note: Removed because android doesn't restrict reflection access
- // static class AtomicReferenceFieldUpdaterTestSubclass extends AtomicReferenceFieldUpdaterTest {
- // public void checkPrivateAccess() {
- // try {
- // AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
- // AtomicReferenceFieldUpdater.newUpdater
- // (AtomicReferenceFieldUpdaterTest.class, Integer.class, "privateField");
- // shouldThrow();
- // } catch (RuntimeException success) {
- // assertNotNull(success.getCause());
- // }
- // }
+ static class AtomicReferenceFieldUpdaterTestSubclass extends AtomicReferenceFieldUpdaterTest {
+ public void checkPrivateAccess() {
+ try {
+ AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
+ AtomicReferenceFieldUpdater.newUpdater
+ (AtomicReferenceFieldUpdaterTest.class, Integer.class, "privateField");
+ shouldThrow();
+ } catch (RuntimeException success) {
+ assertNotNull(success.getCause());
+ }
+ }
- // public void checkCompareAndSetProtectedSub() {
- // AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
- // AtomicReferenceFieldUpdater.newUpdater
- // (AtomicReferenceFieldUpdaterTest.class, Integer.class, "protectedField");
- // this.protectedField = one;
- // assertTrue(a.compareAndSet(this, one, two));
- // assertTrue(a.compareAndSet(this, two, m4));
- // assertSame(m4, a.get(this));
- // assertFalse(a.compareAndSet(this, m5, seven));
- // assertFalse(seven == a.get(this));
- // assertTrue(a.compareAndSet(this, m4, seven));
- // assertSame(seven, a.get(this));
- // }
- // }
+ public void checkCompareAndSetProtectedSub() {
+ AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
+ AtomicReferenceFieldUpdater.newUpdater
+ (AtomicReferenceFieldUpdaterTest.class, Integer.class, "protectedField");
+ this.protectedField = one;
+ assertTrue(a.compareAndSet(this, one, two));
+ assertTrue(a.compareAndSet(this, two, m4));
+ assertSame(m4, a.get(this));
+ assertFalse(a.compareAndSet(this, m5, seven));
+ assertFalse(seven == a.get(this));
+ assertTrue(a.compareAndSet(this, m4, seven));
+ assertSame(seven, a.get(this));
+ }
+ }
- // static class UnrelatedClass {
- // public void checkPackageAccess(AtomicReferenceFieldUpdaterTest obj) {
- // obj.x = one;
- // AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
- // AtomicReferenceFieldUpdater.newUpdater
- // (AtomicReferenceFieldUpdaterTest.class, Integer.class, "x");
- // assertSame(one, a.get(obj));
- // assertTrue(a.compareAndSet(obj, one, two));
- // assertSame(two, a.get(obj));
- // }
+ static class UnrelatedClass {
+ public void checkPackageAccess(AtomicReferenceFieldUpdaterTest obj) {
+ obj.x = one;
+ AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
+ AtomicReferenceFieldUpdater.newUpdater
+ (AtomicReferenceFieldUpdaterTest.class, Integer.class, "x");
+ assertSame(one, a.get(obj));
+ assertTrue(a.compareAndSet(obj, one, two));
+ assertSame(two, a.get(obj));
+ }
- // public void checkPrivateAccess(AtomicReferenceFieldUpdaterTest obj) {
- // try {
- // AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
- // AtomicReferenceFieldUpdater.newUpdater
- // (AtomicReferenceFieldUpdaterTest.class, Integer.class, "privateField");
- // throw new AssertionError("should throw");
- // } catch (RuntimeException success) {
- // assertNotNull(success.getCause());
- // }
- // }
- // }
+ public void checkPrivateAccess(AtomicReferenceFieldUpdaterTest obj) {
+ try {
+ AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
+ AtomicReferenceFieldUpdater.newUpdater
+ (AtomicReferenceFieldUpdaterTest.class, Integer.class, "privateField");
+ throw new AssertionError("should throw");
+ } catch (RuntimeException success) {
+ assertNotNull(success.getCause());
+ }
+ }
+ }
static AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> updaterFor(String fieldName) {
return AtomicReferenceFieldUpdater.newUpdater
@@ -133,22 +132,20 @@
/**
* construction using private field from subclass throws RuntimeException
*/
- // android-note: Removed because android doesn't restrict reflection access
- // public void testPrivateFieldInSubclass() {
- // AtomicReferenceFieldUpdaterTestSubclass s =
- // new AtomicReferenceFieldUpdaterTestSubclass();
- // s.checkPrivateAccess();
- // }
+ public void testPrivateFieldInSubclass() {
+ AtomicReferenceFieldUpdaterTestSubclass s =
+ new AtomicReferenceFieldUpdaterTestSubclass();
+ s.checkPrivateAccess();
+ }
/**
* construction from unrelated class; package access is allowed,
* private access is not
*/
- // android-note: Removed because android doesn't restrict reflection access
- // public void testUnrelatedClassAccess() {
- // new UnrelatedClass().checkPackageAccess(this);
- // new UnrelatedClass().checkPrivateAccess(this);
- // }
+ public void testUnrelatedClassAccess() {
+ new UnrelatedClass().checkPackageAccess(this);
+ new UnrelatedClass().checkPrivateAccess(this);
+ }
/**
* get returns the last value set or assigned
diff --git a/libart/src/main/java/dalvik/system/VMStack.java b/libart/src/main/java/dalvik/system/VMStack.java
index ca29579..3729bf3 100644
--- a/libart/src/main/java/dalvik/system/VMStack.java
+++ b/libart/src/main/java/dalvik/system/VMStack.java
@@ -30,15 +30,21 @@
*
* @return the requested class loader, or {@code null} if this is the
* bootstrap class loader.
+ * @deprecated Use {@code ClassLoader.getClassLoader(sun.reflect.Reflection.getCallerClass())}.
+ * Note that that can return {@link BootClassLoader} on Android where the RI
+ * would have returned null.
*/
@FastNative
+ @Deprecated
native public static ClassLoader getCallingClassLoader();
/**
* Returns the class of the caller's caller.
*
* @return the requested class, or {@code null}.
+ * @deprecated Use {@link sun.reflect.Reflection#getCallerClass()}.
*/
+ @Deprecated
public static Class<?> getStackClass1() {
return getStackClass2();
}
diff --git a/libart/src/main/java/java/lang/StringFactory.java b/libart/src/main/java/java/lang/StringFactory.java
index 1866562..6ef664b 100644
--- a/libart/src/main/java/java/lang/StringFactory.java
+++ b/libart/src/main/java/java/lang/StringFactory.java
@@ -237,17 +237,10 @@
} else {
CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount));
length = cb.length();
- if (length > 0) {
- // We could use cb.array() directly, but that would mean we'd have to trust
- // the CharsetDecoder doesn't hang on to the CharBuffer and mutate it later,
- // which would break String's immutability guarantee. It would also tend to
- // mean that we'd be wasting memory because CharsetDecoder doesn't trim the
- // array. So we copy.
- value = new char[length];
- System.arraycopy(cb.array(), 0, value, 0, length);
- } else {
- value = EmptyArray.CHAR;
- }
+ // The call to newStringFromChars below will copy length bytes out of value, so it does
+ // not matter that cb.array().length may be > cb.length() or that a Charset could keep a
+ // reference to the CharBuffer it returns and later mutate it.
+ value = cb.array();
}
return newStringFromChars(value, 0, length);
}
diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java
index 6301ff9..bc738b7 100644
--- a/luni/src/main/java/android/system/Os.java
+++ b/luni/src/main/java/android/system/Os.java
@@ -51,14 +51,16 @@
*/
public static boolean access(String path, int mode) throws ErrnoException { return Libcore.os.access(path, mode); }
- /** @hide */ public static InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { return Libcore.os.android_getaddrinfo(node, hints, netId); }
+ /** @hide */
+ public static InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { return Libcore.os.android_getaddrinfo(node, hints, netId); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/bind.2.html">bind(2)</a>.
*/
public static void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { Libcore.os.bind(fd, address, port); }
- /** @hide */ public static void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { Libcore.os.bind(fd, address); }
+ /** @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>.
@@ -99,7 +101,8 @@
*/
public static void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { Libcore.os.connect(fd, address, port); }
- /** @hide */ public static void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { Libcore.os.connect(fd, address); }
+ /** @hide */
+ public static void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { Libcore.os.connect(fd, address); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/dup.2.html">dup(2)</a>.
@@ -136,9 +139,14 @@
*/
public static void fchown(FileDescriptor fd, int uid, int gid) throws ErrnoException { Libcore.os.fchown(fd, uid, gid); }
- /** @hide */ public static int fcntlFlock(FileDescriptor fd, int cmd, StructFlock arg) throws ErrnoException, InterruptedIOException { return Libcore.os.fcntlFlock(fd, cmd, arg); }
- /** @hide */ public static int fcntlInt(FileDescriptor fd, int cmd, int arg) throws ErrnoException { return Libcore.os.fcntlInt(fd, cmd, arg); }
- /** @hide */ public static int fcntlVoid(FileDescriptor fd, int cmd) throws ErrnoException { return Libcore.os.fcntlVoid(fd, cmd); }
+ /** @hide */
+ public static int fcntlFlock(FileDescriptor fd, int cmd, StructFlock arg) throws ErrnoException, InterruptedIOException { return Libcore.os.fcntlFlock(fd, cmd, arg); }
+
+ /** @hide */
+ public static int fcntlInt(FileDescriptor fd, int cmd, int arg) throws ErrnoException { return Libcore.os.fcntlInt(fd, cmd, arg); }
+
+ /** @hide */
+ public static int fcntlVoid(FileDescriptor fd, int cmd) throws ErrnoException { return Libcore.os.fcntlVoid(fd, cmd); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/fdatasync.2.html">fdatasync(2)</a>.
@@ -192,10 +200,12 @@
/**
* See <a href="http://man7.org/linux/man-pages/man3/getifaddrs.3.html">getifaddrs(3)</a>.
+ * @hide
*/
- /** @hide */ public static StructIfaddrs[] getifaddrs() throws ErrnoException { return Libcore.os.getifaddrs(); }
+ public static StructIfaddrs[] getifaddrs() throws ErrnoException { return Libcore.os.getifaddrs(); }
- /** @hide */ public static String getnameinfo(InetAddress address, int flags) throws GaiException { return Libcore.os.getnameinfo(address, flags); }
+ /** @hide */
+ public static String getnameinfo(InetAddress address, int flags) throws GaiException { return Libcore.os.getnameinfo(address, flags); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/getpeername.2.html">getpeername(2)</a>.
@@ -204,8 +214,9 @@
/**
* See <a href="http://man7.org/linux/man-pages/man2/getpgid.2.html">getpgid(2)</a>.
+ * @hide
*/
- /** @hide */ public static int getpgid(int pid) throws ErrnoException { return Libcore.os.getpgid(pid); }
+ public static int getpgid(int pid) throws ErrnoException { return Libcore.os.getpgid(pid); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/getpid.2.html">getpid(2)</a>.
@@ -217,23 +228,37 @@
*/
public static int getppid() { return Libcore.os.getppid(); }
- /** @hide */ public static StructPasswd getpwnam(String name) throws ErrnoException { return Libcore.os.getpwnam(name); }
+ /** @hide */
+ public static StructPasswd getpwnam(String name) throws ErrnoException { return Libcore.os.getpwnam(name); }
- /** @hide */ public static StructPasswd getpwuid(int uid) throws ErrnoException { return Libcore.os.getpwuid(uid); }
+ /** @hide */
+ public static StructPasswd getpwuid(int uid) throws ErrnoException { return Libcore.os.getpwuid(uid); }
- /** @hide */ public static StructRlimit getrlimit(int resource) throws ErrnoException { return Libcore.os.getrlimit(resource); }
+ /** @hide */
+ public static StructRlimit getrlimit(int resource) throws ErrnoException { return Libcore.os.getrlimit(resource); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/getsockname.2.html">getsockname(2)</a>.
*/
public static SocketAddress getsockname(FileDescriptor fd) throws ErrnoException { return Libcore.os.getsockname(fd); }
- /** @hide */ public static int getsockoptByte(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptByte(fd, level, option); }
- /** @hide */ public static InetAddress getsockoptInAddr(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptInAddr(fd, level, option); }
- /** @hide */ public static int getsockoptInt(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptInt(fd, level, option); }
- /** @hide */ public static StructLinger getsockoptLinger(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptLinger(fd, level, option); }
- /** @hide */ public static StructTimeval getsockoptTimeval(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptTimeval(fd, level, option); }
- /** @hide */ public static StructUcred getsockoptUcred(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptUcred(fd, level, option); }
+ /** @hide */
+ public static int getsockoptByte(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptByte(fd, level, option); }
+
+ /** @hide */
+ public static InetAddress getsockoptInAddr(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptInAddr(fd, level, option); }
+
+ /** @hide */
+ public static int getsockoptInt(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptInt(fd, level, option); }
+
+ /** @hide */
+ public static StructLinger getsockoptLinger(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptLinger(fd, level, option); }
+
+ /** @hide */
+ public static StructTimeval getsockoptTimeval(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptTimeval(fd, level, option); }
+
+ /** @hide */
+ public static StructUcred getsockoptUcred(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptUcred(fd, level, option); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/gettid.2.html">gettid(2)</a>.
@@ -265,10 +290,12 @@
*/
public static InetAddress inet_pton(int family, String address) { return Libcore.os.inet_pton(family, address); }
- /** @hide */ public static InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException { return Libcore.os.ioctlInetAddress(fd, cmd, interfaceName); }
+ /** @hide */
+ public static InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException { return Libcore.os.ioctlInetAddress(fd, cmd, interfaceName); }
- /** @hide */ public static int ioctlInt(FileDescriptor fd, int cmd, Int32Ref arg) throws ErrnoException {
+ /** @hide */
+ public static int ioctlInt(FileDescriptor fd, int cmd, Int32Ref arg) throws ErrnoException {
return Libcore.os.ioctlInt(fd, cmd, arg);
}
@@ -362,7 +389,8 @@
*/
public static FileDescriptor[] pipe() throws ErrnoException { return Libcore.os.pipe2(0); }
- /** @hide */ public static FileDescriptor[] pipe2(int flags) throws ErrnoException { return Libcore.os.pipe2(flags); }
+ /** @hide */
+ public static FileDescriptor[] pipe2(int flags) throws ErrnoException { return Libcore.os.pipe2(flags); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/poll.2.html">poll(2)</a>.
@@ -420,8 +448,9 @@
/**
* See <a href="http://man7.org/linux/man-pages/man3/realpath.3.html">realpath(3)</a>.
+ * @hide
*/
- /** @hide */ public static String realpath(String path) throws ErrnoException { return Libcore.os.realpath(path); }
+ public static String realpath(String path) throws ErrnoException { return Libcore.os.realpath(path); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/readv.2.html">readv(2)</a>.
@@ -472,8 +501,9 @@
/**
* See <a href="http://man7.org/linux/man-pages/man2/sendto.2.html">sendto(2)</a>.
+ * @hide
*/
- /** @hide */ public static int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, SocketAddress address) throws ErrnoException, SocketException { return Libcore.os.sendto(fd, bytes, byteOffset, byteCount, flags, address); }
+ public static int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, SocketAddress address) throws ErrnoException, SocketException { return Libcore.os.sendto(fd, bytes, byteOffset, byteCount, flags, address); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/setegid.2.html">setegid(2)</a>.
@@ -497,36 +527,49 @@
/**
* See <a href="http://man7.org/linux/man-pages/man2/setpgid.2.html">setpgid(2)</a>.
+ * @hide
*/
- /** @hide */ public static void setpgid(int pid, int pgid) throws ErrnoException { Libcore.os.setpgid(pid, pgid); }
+ public static void setpgid(int pid, int pgid) throws ErrnoException { Libcore.os.setpgid(pid, pgid); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/setregid.2.html">setregid(2)</a>.
+ * @hide
*/
- /** @hide */ public static void setregid(int rgid, int egid) throws ErrnoException { Libcore.os.setregid(rgid, egid); }
+ public static void setregid(int rgid, int egid) throws ErrnoException { Libcore.os.setregid(rgid, egid); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/setreuid.2.html">setreuid(2)</a>.
+ * @hide
*/
- /** @hide */ public static void setreuid(int ruid, int euid) throws ErrnoException { Libcore.os.setreuid(ruid, euid); }
+ public static void setreuid(int ruid, int euid) throws ErrnoException { Libcore.os.setreuid(ruid, euid); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/setsid.2.html">setsid(2)</a>.
*/
public static int setsid() throws ErrnoException { return Libcore.os.setsid(); }
- /** @hide */ public static void setsockoptByte(FileDescriptor fd, int level, int option, int value) throws ErrnoException { Libcore.os.setsockoptByte(fd, level, option, value); }
- /** @hide */ public static void setsockoptIfreq(FileDescriptor fd, int level, int option, String value) throws ErrnoException { Libcore.os.setsockoptIfreq(fd, level, option, value); }
+ /** @hide */
+ public static void setsockoptByte(FileDescriptor fd, int level, int option, int value) throws ErrnoException { Libcore.os.setsockoptByte(fd, level, option, value); }
+
+ /** @hide */
+ public static void setsockoptIfreq(FileDescriptor fd, int level, int option, String value) throws ErrnoException { Libcore.os.setsockoptIfreq(fd, level, option, value); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/setsockopt.2.html">setsockopt(2)</a>.
*/
public static void setsockoptInt(FileDescriptor fd, int level, int option, int value) throws ErrnoException { Libcore.os.setsockoptInt(fd, level, option, value); }
- /** @hide */ public static void setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value) throws ErrnoException { Libcore.os.setsockoptIpMreqn(fd, level, option, value); }
- /** @hide */ public static void setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value) throws ErrnoException { Libcore.os.setsockoptGroupReq(fd, level, option, value); }
- /** @hide */ public static void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException { Libcore.os.setsockoptLinger(fd, level, option, value); }
- /** @hide */ public static void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException { Libcore.os.setsockoptTimeval(fd, level, option, value); }
+ /** @hide */
+ public static void setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value) throws ErrnoException { Libcore.os.setsockoptIpMreqn(fd, level, option, value); }
+
+ /** @hide */
+ public static void setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value) throws ErrnoException { Libcore.os.setsockoptGroupReq(fd, level, option, value); }
+
+ /** @hide */
+ public static void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException { Libcore.os.setsockoptLinger(fd, level, option, value); }
+
+ /** @hide */
+ public static void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException { Libcore.os.setsockoptTimeval(fd, level, option, value); }
/**
* See <a href="http://man7.org/linux/man-pages/man2/setuid.2.html">setuid(2)</a>.
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 1b8c2ff..7ede6a7 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -109,8 +109,10 @@
public static final int AF_INET = placeholder();
public static final int AF_INET6 = placeholder();
- /** @hide */ public static final int AF_NETLINK = placeholder();
- /** @hide */ public static final int AF_PACKET = placeholder();
+ /** @hide */
+ public static final int AF_NETLINK = placeholder();
+ /** @hide */
+ public static final int AF_PACKET = placeholder();
public static final int AF_UNIX = placeholder();
public static final int AF_UNSPEC = placeholder();
public static final int AI_ADDRCONFIG = placeholder();
@@ -120,8 +122,10 @@
public static final int AI_NUMERICSERV = placeholder();
public static final int AI_PASSIVE = placeholder();
public static final int AI_V4MAPPED = placeholder();
- /** @hide */ public static final int ARPHRD_ETHER = placeholder();
- /** @hide */ public static final int ARPHRD_LOOPBACK = placeholder();
+ /** @hide */
+ public static final int ARPHRD_ETHER = placeholder();
+ /** @hide */
+ public static final int ARPHRD_LOOPBACK = placeholder();
public static final int CAP_AUDIT_CONTROL = placeholder();
public static final int CAP_AUDIT_WRITE = placeholder();
public static final int CAP_BLOCK_SUSPEND = placeholder();
@@ -221,7 +225,8 @@
public static final int ENOLINK = placeholder();
public static final int ENOMEM = placeholder();
public static final int ENOMSG = placeholder();
- /** @hide */ public static final int ENONET = placeholder();
+ /** @hide */
+ public static final int ENONET = placeholder();
public static final int ENOPROTOOPT = placeholder();
public static final int ENOSPC = placeholder();
public static final int ENOSR = placeholder();
@@ -246,14 +251,19 @@
public static final int ESPIPE = placeholder();
public static final int ESRCH = placeholder();
public static final int ESTALE = placeholder();
- /** @hide */ public static final int ETH_P_ALL = placeholder();
- /** @hide */ public static final int ETH_P_ARP = placeholder();
- /** @hide */ public static final int ETH_P_IP = placeholder();
- /** @hide */ public static final int ETH_P_IPV6 = placeholder();
+ /** @hide */
+ public static final int ETH_P_ALL = placeholder();
+ /** @hide */
+ public static final int ETH_P_ARP = placeholder();
+ /** @hide */
+ public static final int ETH_P_IP = placeholder();
+ /** @hide */
+ public static final int ETH_P_IPV6 = placeholder();
public static final int ETIME = placeholder();
public static final int ETIMEDOUT = placeholder();
public static final int ETXTBSY = placeholder();
- /** @hide */ public static final int EUSERS = placeholder();
+ /** @hide */
+ public static final int EUSERS = placeholder();
// On Linux, EWOULDBLOCK == EAGAIN. Use EAGAIN instead, to reduce confusion.
public static final int EXDEV = placeholder();
public static final int EXIT_FAILURE = placeholder();
@@ -278,10 +288,14 @@
public static final int F_SETOWN = placeholder();
public static final int F_UNLCK = placeholder();
public static final int F_WRLCK = placeholder();
- /** @hide */ public static final int ICMP_ECHO = placeholder();
- /** @hide */ public static final int ICMP_ECHOREPLY = placeholder();
- /** @hide */ public static final int ICMP6_ECHO_REQUEST = placeholder();
- /** @hide */ public static final int ICMP6_ECHO_REPLY = placeholder();
+ /** @hide */
+ public static final int ICMP_ECHO = placeholder();
+ /** @hide */
+ public static final int ICMP_ECHOREPLY = placeholder();
+ /** @hide */
+ public static final int ICMP6_ECHO_REQUEST = placeholder();
+ /** @hide */
+ public static final int ICMP6_ECHO_REPLY = placeholder();
public static final int IFA_F_DADFAILED = placeholder();
public static final int IFA_F_DEPRECATED = placeholder();
public static final int IFA_F_HOMEADDRESS = placeholder();
@@ -327,16 +341,20 @@
public static final int IPV6_TCLASS = placeholder();
public static final int IPV6_UNICAST_HOPS = placeholder();
public static final int IPV6_V6ONLY = placeholder();
- /** @hide */ public static final int IP_MULTICAST_ALL = placeholder();
+ /** @hide */
+ public static final int IP_MULTICAST_ALL = placeholder();
public static final int IP_MULTICAST_IF = placeholder();
public static final int IP_MULTICAST_LOOP = placeholder();
public static final int IP_MULTICAST_TTL = placeholder();
- /** @hide */ public static final int IP_RECVTOS = placeholder();
+ /** @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();
+ /** @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();
+ /** @hide */
+ public static final int MAP_POPULATE = placeholder();
public static final int MAP_PRIVATE = placeholder();
public static final int MAP_SHARED = placeholder();
public static final int MCAST_JOIN_GROUP = placeholder();
@@ -357,8 +375,15 @@
public static final int MS_ASYNC = placeholder();
public static final int MS_INVALIDATE = placeholder();
public static final int MS_SYNC = placeholder();
- /** @hide */ public static final int NETLINK_NETFILTER = placeholder();
- /** @hide */ public static final int NETLINK_ROUTE = placeholder();
+ /** @hide */
+ public static final int NETLINK_NETFILTER = placeholder();
+ /** @hide */
+ public static final int NETLINK_ROUTE = placeholder();
+ /**
+ * SELinux enforces that only system_server and netd may use this netlink socket type.
+ * @hide
+ */
+ public static final int NETLINK_INET_DIAG = placeholder();
public static final int NI_DGRAM = placeholder();
public static final int NI_NAMEREQD = placeholder();
public static final int NI_NOFQDN = placeholder();
@@ -368,7 +393,8 @@
public static final int O_APPEND = placeholder();
public static final int O_CLOEXEC = placeholder();
public static final int O_CREAT = placeholder();
- /** @hide */ public static final int O_DIRECT = placeholder();
+ /** @hide */
+ public static final int O_DIRECT = placeholder();
public static final int O_EXCL = placeholder();
public static final int O_NOCTTY = placeholder();
public static final int O_NOFOLLOW = placeholder();
@@ -389,8 +415,10 @@
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();
+ /** @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();
@@ -399,25 +427,39 @@
public static final int PROT_READ = placeholder();
public static final int PROT_WRITE = placeholder();
public static final int R_OK = placeholder();
- /** @hide */ public static final int RLIMIT_NOFILE = placeholder();
+ /** @hide */
+ public static final int RLIMIT_NOFILE = placeholder();
public static final int RT_SCOPE_HOST = placeholder();
public static final int RT_SCOPE_LINK = placeholder();
public static final int RT_SCOPE_NOWHERE = placeholder();
public static final int RT_SCOPE_SITE = placeholder();
public static final int RT_SCOPE_UNIVERSE = placeholder();
- /** @hide */ public static final int RTMGRP_IPV4_IFADDR = placeholder();
- /** @hide */ public static final int RTMGRP_IPV4_MROUTE = placeholder();
- /** @hide */ public static final int RTMGRP_IPV4_ROUTE = placeholder();
- /** @hide */ public static final int RTMGRP_IPV4_RULE = placeholder();
- /** @hide */ public static final int RTMGRP_IPV6_IFADDR = placeholder();
- /** @hide */ public static final int RTMGRP_IPV6_IFINFO = placeholder();
- /** @hide */ public static final int RTMGRP_IPV6_MROUTE = placeholder();
- /** @hide */ public static final int RTMGRP_IPV6_PREFIX = placeholder();
- /** @hide */ public static final int RTMGRP_IPV6_ROUTE = placeholder();
- /** @hide */ public static final int RTMGRP_LINK = placeholder();
- /** @hide */ public static final int RTMGRP_NEIGH = placeholder();
- /** @hide */ public static final int RTMGRP_NOTIFY = placeholder();
- /** @hide */ public static final int RTMGRP_TC = placeholder();
+ /** @hide */
+ public static final int RTMGRP_IPV4_IFADDR = placeholder();
+ /** @hide */
+ public static final int RTMGRP_IPV4_MROUTE = placeholder();
+ /** @hide */
+ public static final int RTMGRP_IPV4_ROUTE = placeholder();
+ /** @hide */
+ public static final int RTMGRP_IPV4_RULE = placeholder();
+ /** @hide */
+ public static final int RTMGRP_IPV6_IFADDR = placeholder();
+ /** @hide */
+ public static final int RTMGRP_IPV6_IFINFO = placeholder();
+ /** @hide */
+ public static final int RTMGRP_IPV6_MROUTE = placeholder();
+ /** @hide */
+ public static final int RTMGRP_IPV6_PREFIX = placeholder();
+ /** @hide */
+ public static final int RTMGRP_IPV6_ROUTE = placeholder();
+ /** @hide */
+ public static final int RTMGRP_LINK = placeholder();
+ /** @hide */
+ public static final int RTMGRP_NEIGH = placeholder();
+ /** @hide */
+ public static final int RTMGRP_NOTIFY = placeholder();
+ /** @hide */
+ public static final int RTMGRP_TC = placeholder();
public static final int SEEK_CUR = placeholder();
public static final int SEEK_END = placeholder();
public static final int SEEK_SET = placeholder();
@@ -469,7 +511,8 @@
public static final int SO_BINDTODEVICE = placeholder();
public static final int SO_BROADCAST = placeholder();
public static final int SO_DEBUG = placeholder();
- /** @hide */ public static final int SO_DOMAIN = placeholder();
+ /** @hide */
+ public static final int SO_DOMAIN = placeholder();
public static final int SO_DONTROUTE = placeholder();
public static final int SO_ERROR = placeholder();
public static final int SO_KEEPALIVE = placeholder();
@@ -477,7 +520,8 @@
public static final int SO_OOBINLINE = placeholder();
public static final int SO_PASSCRED = placeholder();
public static final int SO_PEERCRED = placeholder();
- /** @hide */ public static final int SO_PROTOCOL = placeholder();
+ /** @hide */
+ public static final int SO_PROTOCOL = placeholder();
public static final int SO_RCVBUF = placeholder();
public static final int SO_RCVLOWAT = placeholder();
public static final int SO_RCVTIMEO = placeholder();
@@ -486,9 +530,12 @@
public static final int SO_SNDLOWAT = placeholder();
public static final int SO_SNDTIMEO = placeholder();
public static final int SO_TYPE = placeholder();
- /** @hide */ public static final int SPLICE_F_MOVE = placeholder();
- /** @hide */ public static final int SPLICE_F_NONBLOCK = placeholder();
- /** @hide */ public static final int SPLICE_F_MORE = placeholder();
+ /** @hide */
+ public static final int SPLICE_F_MOVE = placeholder();
+ /** @hide */
+ public static final int SPLICE_F_NONBLOCK = placeholder();
+ /** @hide */
+ public static final int SPLICE_F_MORE = placeholder();
public static final int STDERR_FILENO = placeholder();
public static final int STDIN_FILENO = placeholder();
public static final int STDOUT_FILENO = placeholder();
@@ -526,11 +573,16 @@
public static final int S_IXUSR = placeholder();
public static final int TCP_NODELAY = placeholder();
public static final int TCP_USER_TIMEOUT = placeholder();
- /** @hide */ public static final int TIOCOUTQ = placeholder();
- /** @hide */ public static final int UDP_ENCAP = placeholder();
- /** @hide */ public static final int UDP_ENCAP_ESPINUDP_NON_IKE = placeholder();
- /** @hide */ public static final int UDP_ENCAP_ESPINUDP = placeholder();
- /** @hide */ public static final int UNIX_PATH_MAX = placeholder();
+ /** @hide */
+ public static final int TIOCOUTQ = placeholder();
+ /** @hide */
+ public static final int UDP_ENCAP = placeholder();
+ /** @hide */
+ public static final int UDP_ENCAP_ESPINUDP_NON_IKE = placeholder();
+ /** @hide */
+ public static final int UDP_ENCAP_ESPINUDP = placeholder();
+ /** @hide */
+ public static final int UNIX_PATH_MAX = placeholder();
public static final int WCONTINUED = placeholder();
public static final int WEXITED = placeholder();
public static final int WNOHANG = placeholder();
@@ -538,8 +590,10 @@
public static final int WSTOPPED = placeholder();
public static final int WUNTRACED = placeholder();
public static final int W_OK = placeholder();
- /** @hide */ public static final int XATTR_CREATE = placeholder();
- /** @hide */ public static final int XATTR_REPLACE = placeholder();
+ /** @hide */
+ public static final int XATTR_CREATE = placeholder();
+ /** @hide */
+ public static final int XATTR_REPLACE = placeholder();
public static final int X_OK = placeholder();
public static final int _SC_2_CHAR_TERM = placeholder();
public static final int _SC_2_C_BIND = placeholder();
diff --git a/luni/src/main/java/java/math/BigDecimal.java b/luni/src/main/java/java/math/BigDecimal.java
index d03b66f..6ba251b 100644
--- a/luni/src/main/java/java/math/BigDecimal.java
+++ b/luni/src/main/java/java/math/BigDecimal.java
@@ -2034,9 +2034,7 @@
long newScale = scale;
if (isZero()) {
- // Preserve RI compatibility, so BigDecimal.equals (which checks
- // value *and* scale) continues to work.
- return this;
+ return new BigDecimal(BigInteger.ZERO, 0);
}
BigInteger strippedBI = getUnscaledValue();
BigInteger[] quotAndRem;
diff --git a/luni/src/main/java/libcore/api/CorePlatformApi.java b/luni/src/main/java/libcore/api/CorePlatformApi.java
new file mode 100644
index 0000000..09837a0
--- /dev/null
+++ b/luni/src/main/java/libcore/api/CorePlatformApi.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 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.api;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates an API is part of a contract provided by the "core" set of
+ * libraries to select parts of the Android software stack.
+ *
+ * <p>This annotation should only appear on either (a) classes that are hidden by <pre>@hide</pre>
+ * javadoc tags or equivalent annotations, or (b) members of such classes. It is for use with
+ * metalava's {@code --show-single-annotation} option and so must be applied at the class level and
+ * applied again each member that is to be made part of the API. Members that are not part of the
+ * API do not have to be explicitly hidden.
+ *
+ * @hide
+ */
+@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface CorePlatformApi {
+}
diff --git a/luni/src/main/java/libcore/api/IntraCoreApi.java b/luni/src/main/java/libcore/api/IntraCoreApi.java
new file mode 100644
index 0000000..87cfcff
--- /dev/null
+++ b/luni/src/main/java/libcore/api/IntraCoreApi.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2018 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.api;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates an API is part of a contract within the "core" set of libraries, some of which may
+ * be mmodules.
+ *
+ * <p>This annotation should only appear on either (a) classes that are hidden by <pre>@hide</pre>
+ * javadoc tags or equivalent annotations, or (b) members of such classes. It is for use with
+ * metalava's {@code --show-single-annotation} option and so must be applied at the class level and
+ * applied again each member that is to be made part of the API. Members that are not part of the
+ * API do not have to be explicitly hidden.
+ *
+ * @hide
+ */
+@IntraCoreApi // @IntraCoreApi is itself part of the intra-core API
+@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface IntraCoreApi {
+}
diff --git a/luni/src/main/java/libcore/icu/LocaleData.java b/luni/src/main/java/libcore/icu/LocaleData.java
index 154ea68..45f4b29 100644
--- a/luni/src/main/java/libcore/icu/LocaleData.java
+++ b/luni/src/main/java/libcore/icu/LocaleData.java
@@ -16,9 +16,14 @@
package libcore.icu;
+import android.icu.impl.ICUData;
+import android.icu.impl.ICUResourceBundle;
+import android.icu.text.NumberingSystem;
+import android.icu.util.UResourceBundle;
import java.text.DateFormat;
import java.util.HashMap;
import java.util.Locale;
+import java.util.MissingResourceException;
import libcore.util.Objects;
/**
@@ -200,6 +205,9 @@
throw new AssertionError("couldn't initialize LocaleData for locale " + locale);
}
+ // Libcore localizes pattern separator while ICU doesn't. http://b/112080617
+ initializePatternSeparator(localeData, locale);
+
// Get the SHORT and MEDIUM 12- and 24-hour time format strings.
localeData.timeFormat_hm = ICU.getBestDateTimePattern("hm", locale);
localeData.timeFormat_Hm = ICU.getBestDateTimePattern("Hm", locale);
@@ -226,4 +234,45 @@
}
return localeData;
}
+
+ // Libcore localizes pattern separator while ICU doesn't. http://b/112080617
+ private static void initializePatternSeparator(LocaleData localeData, Locale locale) {
+ NumberingSystem ns = NumberingSystem.getInstance(locale);
+ // A numbering system could be numeric or algorithmic. DecimalFormat can only use
+ // a numeric and decimal-based (radix == 10) system. Fallback to a Latin, a known numeric
+ // and decimal-based if the default numbering system isn't. All locales should have data
+ // for Latin numbering system after locale data fallback. See Numbering system section
+ // in Unicode Technical Standard #35 for more details.
+ String nsName = ns != null && ns.getRadix() == 10 && !ns.isAlgorithmic()
+ ? ns.getName() : "latn";
+ ICUResourceBundle rb = (ICUResourceBundle) UResourceBundle.getBundleInstance(
+ ICUData.ICU_BASE_NAME, locale);
+ String patternSeparator = null;
+ // The fallback of number format data isn't well-specified in the spec.
+ // But the separator can't be null / empty, and ICU uses Latin numbering system
+ // as fallback.
+ if (!"latn".equals(nsName)) {
+ try {
+ patternSeparator = rb.getStringWithFallback(
+ "NumberElements/" + nsName +"/symbols/list");
+ } catch (MissingResourceException e) {
+ // Try Latin numbering system later
+ }
+ }
+
+ if (patternSeparator == null) {
+ try {
+ patternSeparator = rb.getStringWithFallback("NumberElements/latn/symbols/list");
+ } catch (MissingResourceException e) {
+ // Fallback to the default separator ';'.
+ }
+ }
+
+ if (patternSeparator == null || patternSeparator.isEmpty()) {
+ patternSeparator = ";";
+ }
+
+ // Pattern separator in libcore supports single java character only.
+ localeData.patternSeparator = patternSeparator.charAt(0);
+ }
}
diff --git a/luni/src/main/java/libcore/io/BlockGuardOs.java b/luni/src/main/java/libcore/io/BlockGuardOs.java
index 9b1ebe9..ac10da6 100644
--- a/luni/src/main/java/libcore/io/BlockGuardOs.java
+++ b/luni/src/main/java/libcore/io/BlockGuardOs.java
@@ -65,16 +65,19 @@
@Override public boolean access(String path, int mode) throws ErrnoException {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
return os.access(path, mode);
}
@Override public void chmod(String path, int mode) throws ErrnoException {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
os.chmod(path, mode);
}
@Override public void chown(String path, int uid, int gid) throws ErrnoException {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
os.chown(path, uid, gid);
}
@@ -174,11 +177,14 @@
@Override public void lchown(String path, int uid, int gid) throws ErrnoException {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
os.lchown(path, uid, gid);
}
@Override public void link(String oldPath, String newPath) throws ErrnoException {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(oldPath);
+ BlockGuard.getVmPolicy().onPathAccess(newPath);
os.link(oldPath, newPath);
}
@@ -189,21 +195,25 @@
@Override public StructStat lstat(String path) throws ErrnoException {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
return os.lstat(path);
}
@Override public void mkdir(String path, int mode) throws ErrnoException {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
os.mkdir(path, mode);
}
@Override public void mkfifo(String path, int mode) throws ErrnoException {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
os.mkfifo(path, mode);
}
@Override public FileDescriptor open(String path, int flags, int mode) throws ErrnoException {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
if ((flags & O_ACCMODE) != O_RDONLY) {
BlockGuard.getThreadPolicy().onWriteToDisk();
}
@@ -256,11 +266,13 @@
@Override public String readlink(String path) throws ErrnoException {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
return os.readlink(path);
}
@Override public String realpath(String path) throws ErrnoException {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
return os.realpath(path);
}
@@ -281,11 +293,14 @@
@Override public void remove(String path) throws ErrnoException {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
os.remove(path);
}
@Override public void rename(String oldPath, String newPath) throws ErrnoException {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(oldPath);
+ BlockGuard.getVmPolicy().onPathAccess(newPath);
os.rename(oldPath, newPath);
}
@@ -325,16 +340,20 @@
@Override public StructStat stat(String path) throws ErrnoException {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
return os.stat(path);
}
@Override public StructStatVfs statvfs(String path) throws ErrnoException {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
return os.statvfs(path);
}
@Override public void symlink(String oldPath, String newPath) throws ErrnoException {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(oldPath);
+ BlockGuard.getVmPolicy().onPathAccess(newPath);
os.symlink(oldPath, newPath);
}
@@ -355,17 +374,20 @@
@Override public void execv(String filename, String[] argv) throws ErrnoException {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(filename);
os.execv(filename, argv);
}
@Override public void execve(String filename, String[] argv, String[] envp)
throws ErrnoException {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(filename);
os.execve(filename, argv, envp);
}
@Override public byte[] getxattr(String path, String name) throws ErrnoException {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
return os.getxattr(path, name);
}
@@ -378,12 +400,14 @@
@Override public void removexattr(String path, String name) throws ErrnoException {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
os.removexattr(path, name);
}
@Override public void setxattr(String path, String name, byte[] value, int flags)
throws ErrnoException {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
os.setxattr(path, name, value, flags);
}
@@ -395,6 +419,7 @@
@Override public void unlink(String pathname) throws ErrnoException {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(pathname);
os.unlink(pathname);
}
diff --git a/luni/src/main/java/libcore/io/ClassPathURLStreamHandler.java b/luni/src/main/java/libcore/io/ClassPathURLStreamHandler.java
index 117c1f8..1413223 100644
--- a/luni/src/main/java/libcore/io/ClassPathURLStreamHandler.java
+++ b/luni/src/main/java/libcore/io/ClassPathURLStreamHandler.java
@@ -25,7 +25,6 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
-import java.net.URLEncoder;
import java.net.URLStreamHandler;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
@@ -57,7 +56,7 @@
* entry cannot be found under the exact name presented.
*/
public URL getEntryUrlOrNull(String entryName) {
- if (findEntryWithDirectoryFallback(jarFile, entryName) != null) {
+ if (jarFile.getEntry(entryName) != null) {
try {
// Encode the path to ensure that any special characters like # survive their trip through
// the URL. Entry names must use / as the path separator.
@@ -89,19 +88,6 @@
jarFile.close();
}
- /**
- * Finds an entry with the specified name in the {@code jarFile}. If an exact match isn't found it
- * will also try with "/" appended, if appropriate. This is to maintain compatibility with
- * {@link sun.net.www.protocol.jar.Handler} and its treatment of directory entries.
- */
- static ZipEntry findEntryWithDirectoryFallback(JarFile jarFile, String entryName) {
- ZipEntry entry = jarFile.getEntry(entryName);
- if (entry == null && !entryName.endsWith("/") ) {
- entry = jarFile.getEntry(entryName + "/");
- }
- return entry;
- }
-
private class ClassPathURLConnection extends JarURLConnection {
// The JarFile instance can be shared across URLConnections and should not be closed when it is:
//
@@ -139,8 +125,7 @@
@Override
public void connect() throws IOException {
if (!connected) {
- this.jarEntry = findEntryWithDirectoryFallback(ClassPathURLStreamHandler.this.jarFile,
- getEntryName());
+ this.jarEntry = jarFile.getEntry(getEntryName());
if (jarEntry == null) {
throw new FileNotFoundException(
"URL does not correspond to an entry in the zip file. URL=" + url
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
index f141694..2e0ce9f 100644
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -70,6 +70,11 @@
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); }
+ public void android_fdsan_exchange_owner_tag(FileDescriptor fd, long previousOwnerId, long newOwnerId) { os.android_fdsan_exchange_owner_tag(fd, previousOwnerId, newOwnerId); }
+ public long android_fdsan_get_owner_tag(FileDescriptor fd) { return os.android_fdsan_get_owner_tag(fd); }
+ public String android_fdsan_get_tag_type(long tag) { return os.android_fdsan_get_tag_type(tag); }
+ public long android_fdsan_get_tag_value(long tag) { return os.android_fdsan_get_tag_value(tag); }
+
public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { os.connect(fd, address, port); }
public void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { os.connect(fd, address); }
public FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException { return os.dup(oldFd); }
diff --git a/luni/src/main/java/libcore/io/IoBridge.java b/luni/src/main/java/libcore/io/IoBridge.java
index a950bf5..8c1e7cb 100644
--- a/luni/src/main/java/libcore/io/IoBridge.java
+++ b/luni/src/main/java/libcore/io/IoBridge.java
@@ -22,6 +22,9 @@
import android.system.StructLinger;
import android.system.StructPollfd;
import android.system.StructTimeval;
+
+import libcore.util.ArrayUtils;
+
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -41,7 +44,6 @@
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
-import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import static android.system.OsConstants.*;
@@ -227,9 +229,11 @@
}
/**
- * Closes the supplied file descriptor and sends a signal to any threads are currently blocking.
- * In order for the signal to be sent the blocked threads must have registered with
- * the AsynchronousCloseMonitor before they entered the blocking operation.
+ * Closes the Unix file descriptor associated with the supplied file descriptor, resets the
+ * internal int to -1, and sends a signal to any threads are currently blocking. In order for
+ * the signal to be sent the blocked threads must have registered with the
+ * AsynchronousCloseMonitor before they entered the blocking operation. {@code fd} will be
+ * invalid after this call.
*
* <p>This method is a no-op if passed a {@code null} or already-closed file descriptor.
*/
@@ -237,15 +241,13 @@
if (fd == null || !fd.valid()) {
return;
}
- int intFd = fd.getInt$();
- fd.setInt$(-1);
- FileDescriptor oldFd = new FileDescriptor();
- oldFd.setInt$(intFd);
+ // fd is invalid after we call release.
+ FileDescriptor oldFd = fd.release$();
AsynchronousCloseMonitor.signalBlockedThreads(oldFd);
try {
Libcore.os.close(oldFd);
} catch (ErrnoException errnoException) {
- // TODO: are there any cases in which we should throw?
+ throw errnoException.rethrowAsIOException();
}
}
@@ -273,7 +275,9 @@
}
String detail = createMessageForException(fd, inetAddress, port, timeoutMs, cause);
if (cause.errno == ETIMEDOUT) {
- throw new SocketTimeoutException(detail, cause);
+ SocketTimeoutException e = new SocketTimeoutException(detail);
+ e.initCause(cause);
+ throw e;
}
throw new ConnectException(detail, cause);
}
@@ -478,7 +482,7 @@
} catch (ErrnoException errnoException) {
try {
if (fd != null) {
- IoUtils.close(fd);
+ closeAndSignalBlockedThreads(fd);
}
} catch (IOException ignored) {
}
@@ -493,7 +497,7 @@
* Unix practice where you'd read until you got 0 bytes (and any future read would return -1).
*/
public static int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws IOException {
- Arrays.checkOffsetAndCount(bytes.length, byteOffset, byteCount);
+ ArrayUtils.throwsIfOutOfBounds(bytes.length, byteOffset, byteCount);
if (byteCount == 0) {
return 0;
}
@@ -517,7 +521,7 @@
* Unix it never just writes as many bytes as happens to be convenient.)
*/
public static void write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws IOException {
- Arrays.checkOffsetAndCount(bytes.length, byteOffset, byteCount);
+ ArrayUtils.throwsIfOutOfBounds(bytes.length, byteOffset, byteCount);
if (byteCount == 0) {
return;
}
@@ -627,7 +631,9 @@
if (isConnected && errnoException.errno == ECONNREFUSED) {
throw new PortUnreachableException("ICMP Port Unreachable", errnoException);
} else if (errnoException.errno == EAGAIN) {
- throw new SocketTimeoutException(errnoException);
+ SocketTimeoutException e = new SocketTimeoutException();
+ e.initCause(errnoException);
+ throw e;
} else {
throw errnoException.rethrowAsSocketException();
}
diff --git a/luni/src/main/java/libcore/io/IoUtils.java b/luni/src/main/java/libcore/io/IoUtils.java
index b01759d..46ea573 100644
--- a/luni/src/main/java/libcore/io/IoUtils.java
+++ b/luni/src/main/java/libcore/io/IoUtils.java
@@ -26,7 +26,9 @@
import java.net.Socket;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
+import java.util.Objects;
import java.util.Random;
+import libcore.util.NonNull;
import static android.system.OsConstants.*;
public final class IoUtils {
@@ -34,17 +36,116 @@
}
/**
+ * Acquires ownership of an integer file descriptor from a FileDescriptor.
+ *
+ * This method invalidates the FileDescriptor passed in.
+ *
+ * The important part of this function is that you are taking ownership of a resource that you
+ * must either clean up yourself, or hand off to some other object that does that for you.
+ *
+ * See bionic/include/android/fdsan.h for more details.
+ *
+ * @param fd FileDescriptor to take ownership from, must be non-null.
+ * @throws NullPointerException if fd is null
+ */
+ public static int acquireRawFd(@NonNull FileDescriptor fd) {
+ Objects.requireNonNull(fd);
+
+ FileDescriptor copy = fd.release$();
+ // Get the numeric Unix file descriptor. -1 means it is invalid; for example if
+ // {@link FileDescriptor#release$()} has already been called on the FileDescriptor.
+ int rawFd = copy.getInt$();
+ long previousOwnerId = copy.getOwnerId$();
+ if (rawFd != -1 && previousOwnerId != FileDescriptor.NO_OWNER) {
+ // Clear the file descriptor's owner ID, aborting if the previous value isn't as expected.
+ Libcore.os.android_fdsan_exchange_owner_tag(copy, previousOwnerId,
+ FileDescriptor.NO_OWNER);
+ }
+ return rawFd;
+ }
+
+ private static boolean isParcelFileDescriptor(Object object) {
+ // We need to look up ParcelFileDescriptor dynamically, because there are cases where the
+ // framework classes will not be found on the classpath such as on-host development.
+ try {
+ Class<?> pfdClass = Class.forName("android.os.ParcelFileDescriptor");
+ if (pfdClass.isInstance(object)) {
+ return true;
+ }
+ return false;
+ } catch (ClassNotFoundException ex) {
+ return false;
+ }
+ }
+
+ private static long generateFdOwnerId(Object owner) {
+ if (owner == null) {
+ return 0;
+ }
+
+ // Type values from bionic's <android/fdsan.h>.
+ long tagType;
+ if (owner instanceof java.io.FileInputStream) {
+ tagType = 5;
+ } else if (owner instanceof java.io.FileOutputStream) {
+ tagType = 6;
+ } else if (owner instanceof java.io.RandomAccessFile) {
+ tagType = 7;
+ } else if (owner instanceof java.net.DatagramSocketImpl) {
+ tagType = 10;
+ } else if (owner instanceof java.net.SocketImpl) {
+ tagType = 11;
+ } else if (isParcelFileDescriptor(owner)) {
+ tagType = 8;
+ } else {
+ // Generic Java type.
+ tagType = 255;
+ }
+
+ // The owner ID is not required to be unique but should be stable and attempt to avoid
+ // collision with identifiers generated both here and in native code (which are simply the
+ // address of the owning object). identityHashCode(Object) meets these requirements.
+ long tagValue = System.identityHashCode(owner);
+ return tagType << 56 | tagValue;
+ }
+
+ /**
+ * Assigns ownership of an unowned FileDescriptor.
+ *
+ * Associates the supplied FileDescriptor and the underlying Unix file descriptor with an owner
+ * ID derived from the supplied {@code owner} object. If the FileDescriptor already has an
+ * associated owner an {@link IllegalStateException} will be thrown. If the underlying Unix
+ * file descriptor already has an associated owner, the process will abort.
+ *
+ * See bionic/include/android/fdsan.h for more details.
+ *
+ * @param fd FileDescriptor to take ownership from, must be non-null.
+ * @throws NullPointerException if fd or owner are null
+ * @throws IllegalStateException if fd is already owned
+ */
+ public static void setFdOwner(@NonNull FileDescriptor fd, @NonNull Object owner) {
+ Objects.requireNonNull(fd);
+ Objects.requireNonNull(owner);
+
+ long previousOwnerId = fd.getOwnerId$();
+ if (previousOwnerId != FileDescriptor.NO_OWNER) {
+ throw new IllegalStateException("Attempted to take ownership of already-owned " +
+ "FileDescriptor");
+ }
+
+ long ownerId = generateFdOwnerId(owner);
+ fd.setOwnerId$(ownerId);
+
+ // Set the file descriptor's owner ID, aborting if the previous value isn't as expected.
+ Libcore.os.android_fdsan_exchange_owner_tag(fd, previousOwnerId, ownerId);
+ }
+
+ /**
* Calls close(2) on 'fd'. Also resets the internal int to -1. Does nothing if 'fd' is null
* or invalid.
*/
public static void close(FileDescriptor fd) throws IOException {
- try {
- if (fd != null && fd.valid()) {
- Libcore.os.close(fd);
- }
- } catch (ErrnoException errnoException) {
- throw errnoException.rethrowAsIOException();
- }
+ IoBridge.closeAndSignalBlockedThreads(fd);
}
/**
diff --git a/luni/src/main/java/libcore/io/Linux.java b/luni/src/main/java/libcore/io/Linux.java
index 807e5a2..3766ac1 100644
--- a/luni/src/main/java/libcore/io/Linux.java
+++ b/luni/src/main/java/libcore/io/Linux.java
@@ -60,7 +60,13 @@
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;
+ public native void android_fdsan_exchange_owner_tag(FileDescriptor fd, long previousOwnerId, long newOwnerId);
+ public native long android_fdsan_get_owner_tag(FileDescriptor fd);
+ public native String android_fdsan_get_tag_type(long tag);
+ public native long android_fdsan_get_tag_value(long tag);
+
public native void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
public native void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
public native FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException;
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
index 61584b4..3f1c809 100644
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -54,7 +54,13 @@
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;
+ public void android_fdsan_exchange_owner_tag(FileDescriptor fd, long previousOwnerId, long newOwnerId);
+ public long android_fdsan_get_owner_tag(FileDescriptor fd);
+ public String android_fdsan_get_tag_type(long tag);
+ public long android_fdsan_get_tag_value(long tag);
+
public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
public void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
public FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException;
diff --git a/luni/src/main/java/libcore/io/Streams.java b/luni/src/main/java/libcore/io/Streams.java
index 1f78edd..346bba0 100644
--- a/luni/src/main/java/libcore/io/Streams.java
+++ b/luni/src/main/java/libcore/io/Streams.java
@@ -16,6 +16,8 @@
package libcore.io;
+import libcore.util.ArrayUtils;
+
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
@@ -23,7 +25,6 @@
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringWriter;
-import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReference;
public final class Streams {
@@ -76,7 +77,7 @@
if (dst == null) {
throw new NullPointerException("dst == null");
}
- Arrays.checkOffsetAndCount(dst.length, offset, byteCount);
+ ArrayUtils.throwsIfOutOfBounds(dst.length, offset, byteCount);
while (byteCount > 0) {
int bytesRead = in.read(dst, offset, byteCount);
if (bytesRead < 0) {
diff --git a/luni/src/main/java/libcore/mmodule/libart/DemoLibartClass.java b/luni/src/main/java/libcore/mmodule/libart/DemoLibartClass.java
new file mode 100644
index 0000000..360d2035ce
--- /dev/null
+++ b/luni/src/main/java/libcore/mmodule/libart/DemoLibartClass.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2018 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.mmodule.libart;
+
+import libcore.mmodule.simple.DemoSimpleClass;
+
+/**
+ * A class that provides:
+ * <ul>
+ * <li>A method within core-libart for the core-simple mmodule to depend on,
+ * and a method that depends on the core-simple mmodule thereby demonstrating a
+ * bi-directional, intra-module dependency.</li>
+ * <li>A "core platform API" method for use by higher-level code.</li>
+ * </ul>
+ *
+ * @hide
+ */
+@libcore.api.CorePlatformApi
+@libcore.api.IntraCoreApi
+public class DemoLibartClass {
+
+ private DemoLibartClass() {}
+
+ /**
+ * A method that depends on the simple mmodule to work.
+ */
+ @libcore.api.IntraCoreApi
+ public static String intraCoreDependencyMethod() {
+ // Delegate to core-simple code to implement the method.
+ return DemoSimpleClass.simpleMethod();
+ }
+
+ /**
+ * A simple method that has no native or data file dependencies but is part of the intra-core
+ * mmodule API contract.
+ */
+ @libcore.api.IntraCoreApi
+ public static String simpleMethod() {
+ return "Hello World";
+ }
+
+ /**
+ * A core platform API method provided to higher-level code in the Android software stack.
+ */
+ @libcore.api.CorePlatformApi
+ public static String corePlatformApiMethod() {
+ return "Hello World";
+ }
+
+ /**
+ * A method that is public but not part of either the intra-core or core platform API
+ * contracts, i.e. it cannot be used from the rest of the platform or another core mmodule.
+ */
+ public static String hiddenMethod() {
+ return "Hello World";
+ }
+}
diff --git a/luni/src/main/java/libcore/net/MimeUtils.java b/luni/src/main/java/libcore/net/MimeUtils.java
index 3ab4300..bd7c874 100644
--- a/luni/src/main/java/libcore/net/MimeUtils.java
+++ b/luni/src/main/java/libcore/net/MimeUtils.java
@@ -16,401 +16,73 @@
package libcore.net;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
+import java.util.regex.Pattern;
/**
* Utilities for dealing with MIME types.
* Used to implement java.net.URLConnection and android.webkit.MimeTypeMap.
*/
public final class MimeUtils {
+ private static final Pattern splitPattern = Pattern.compile("\\s+");
+
private static final Map<String, String> mimeTypeToExtensionMap = new HashMap<String, String>();
private static final Map<String, String> extensionToMimeTypeMap = new HashMap<String, String>();
static {
- // The following table is based on /etc/mime.types data minus
- // chemical/* MIME types and MIME types that don't map to any
- // file extensions. We also exclude top-level domain names to
- // deal with cases like:
- //
- // mail.google.com/a/google.com
- //
- // and "active" MIME types (due to potential security issues).
-
- // Note that this list is _not_ in alphabetical order and must not be sorted.
- // The "most popular" extension must come first, so that it's the one returned
- // by guessExtensionFromMimeType.
-
- add("application/andrew-inset", "ez");
- add("application/dsptype", "tsp");
- add("application/epub+zip", "epub");
- add("application/hta", "hta");
- add("application/mac-binhex40", "hqx");
- add("application/mathematica", "nb");
- add("application/msaccess", "mdb");
- add("application/oda", "oda");
- add("application/ogg", "ogx");
- add("application/pdf", "pdf");
- add("application/pgp-keys", "key");
- add("application/pgp-signature", "pgp");
- add("application/pics-rules", "prf");
- add("application/pkix-cert", "cer");
- add("application/rar", "rar");
- add("application/rdf+xml", "rdf");
- add("application/rss+xml", "rss");
- add("application/zip", "zip");
- add("application/vnd.android.package-archive", "apk");
- add("application/vnd.cinderella", "cdy");
- add("application/vnd.ms-pki.stl", "stl");
- add("application/vnd.oasis.opendocument.database", "odb");
- add("application/vnd.oasis.opendocument.formula", "odf");
- add("application/vnd.oasis.opendocument.graphics", "odg");
- add("application/vnd.oasis.opendocument.graphics-template", "otg");
- add("application/vnd.oasis.opendocument.image", "odi");
- add("application/vnd.oasis.opendocument.presentation", "odp");
- add("application/vnd.oasis.opendocument.presentation-template", "otp");
- add("application/vnd.oasis.opendocument.spreadsheet", "ods");
- add("application/vnd.oasis.opendocument.spreadsheet-template", "ots");
- add("application/vnd.oasis.opendocument.text", "odt");
- add("application/vnd.oasis.opendocument.text-master", "odm");
- add("application/vnd.oasis.opendocument.text-template", "ott");
- add("application/vnd.oasis.opendocument.text-web", "oth");
- add("application/vnd.google-earth.kml+xml", "kml");
- add("application/vnd.google-earth.kmz", "kmz");
- add("application/msword", "doc");
- add("application/msword", "dot");
- add("application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx");
- add("application/vnd.openxmlformats-officedocument.wordprocessingml.template", "dotx");
- add("application/vnd.ms-excel", "xls");
- add("application/vnd.ms-excel", "xlt");
- add("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx");
- add("application/vnd.openxmlformats-officedocument.spreadsheetml.template", "xltx");
- add("application/vnd.ms-powerpoint", "ppt");
- add("application/vnd.ms-powerpoint", "pot");
- add("application/vnd.ms-powerpoint", "pps");
- add("application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx");
- add("application/vnd.openxmlformats-officedocument.presentationml.template", "potx");
- add("application/vnd.openxmlformats-officedocument.presentationml.slideshow", "ppsx");
- add("application/vnd.rim.cod", "cod");
- add("application/vnd.smaf", "mmf");
- add("application/vnd.stardivision.calc", "sdc");
- add("application/vnd.stardivision.draw", "sda");
- add("application/vnd.stardivision.impress", "sdd");
- add("application/vnd.stardivision.impress", "sdp");
- add("application/vnd.stardivision.math", "smf");
- add("application/vnd.stardivision.writer", "sdw");
- add("application/vnd.stardivision.writer", "vor");
- add("application/vnd.stardivision.writer-global", "sgl");
- add("application/vnd.sun.xml.calc", "sxc");
- add("application/vnd.sun.xml.calc.template", "stc");
- add("application/vnd.sun.xml.draw", "sxd");
- add("application/vnd.sun.xml.draw.template", "std");
- add("application/vnd.sun.xml.impress", "sxi");
- add("application/vnd.sun.xml.impress.template", "sti");
- add("application/vnd.sun.xml.math", "sxm");
- add("application/vnd.sun.xml.writer", "sxw");
- add("application/vnd.sun.xml.writer.global", "sxg");
- add("application/vnd.sun.xml.writer.template", "stw");
- add("application/vnd.visio", "vsd");
- add("application/vnd.youtube.yt", "yt");
- add("application/x-abiword", "abw");
- add("application/x-apple-diskimage", "dmg");
- add("application/x-bcpio", "bcpio");
- add("application/x-bittorrent", "torrent");
- add("application/x-cdf", "cdf");
- add("application/x-cdlink", "vcd");
- add("application/x-chess-pgn", "pgn");
- add("application/x-cpio", "cpio");
- add("application/x-debian-package", "deb");
- add("application/x-debian-package", "udeb");
- add("application/x-director", "dcr");
- add("application/x-director", "dir");
- add("application/x-director", "dxr");
- add("application/x-dms", "dms");
- add("application/x-doom", "wad");
- add("application/x-dvi", "dvi");
- add("application/x-font", "pfa");
- add("application/x-font", "pfb");
- add("application/x-font", "gsf");
- add("application/x-font", "pcf");
- add("application/x-font", "pcf.Z");
- add("application/x-freemind", "mm");
- // application/futuresplash isn't IANA, so application/x-futuresplash should come first.
- add("application/x-futuresplash", "spl");
- add("application/futuresplash", "spl");
- add("application/x-gnumeric", "gnumeric");
- add("application/x-go-sgf", "sgf");
- add("application/x-graphing-calculator", "gcf");
- add("application/x-gtar", "tgz");
- add("application/x-gtar", "gtar");
- add("application/x-gtar", "taz");
- add("application/x-hdf", "hdf");
- add("application/x-hwp", "hwp"); // http://b/18788282.
- add("application/x-ica", "ica");
- add("application/x-internet-signup", "ins");
- add("application/x-internet-signup", "isp");
- add("application/x-iphone", "iii");
- add("application/x-iso9660-image", "iso");
- add("application/x-jmol", "jmz");
- add("application/x-kchart", "chrt");
- add("application/x-killustrator", "kil");
- add("application/x-koan", "skp");
- add("application/x-koan", "skd");
- add("application/x-koan", "skt");
- add("application/x-koan", "skm");
- add("application/x-kpresenter", "kpr");
- add("application/x-kpresenter", "kpt");
- add("application/x-kspread", "ksp");
- add("application/x-kword", "kwd");
- add("application/x-kword", "kwt");
- add("application/x-latex", "latex");
- add("application/x-lha", "lha");
- add("application/x-lzh", "lzh");
- add("application/x-lzx", "lzx");
- add("application/x-maker", "frm");
- add("application/x-maker", "maker");
- add("application/x-maker", "frame");
- add("application/x-maker", "fb");
- add("application/x-maker", "book");
- add("application/x-maker", "fbdoc");
- add("application/x-mif", "mif");
- add("application/x-ms-wmd", "wmd");
- add("application/x-ms-wmz", "wmz");
- add("application/x-msi", "msi");
- add("application/x-ns-proxy-autoconfig", "pac");
- add("application/x-nwc", "nwc");
- add("application/x-object", "o");
- add("application/x-oz-application", "oza");
- add("application/x-pem-file", "pem");
- add("application/x-pkcs12", "p12");
- add("application/x-pkcs12", "pfx");
- add("application/x-pkcs7-certreqresp", "p7r");
- add("application/x-pkcs7-crl", "crl");
- add("application/x-quicktimeplayer", "qtl");
- add("application/x-shar", "shar");
- add("application/x-shockwave-flash", "swf");
- add("application/x-stuffit", "sit");
- add("application/x-sv4cpio", "sv4cpio");
- add("application/x-sv4crc", "sv4crc");
- add("application/x-tar", "tar");
- add("application/x-texinfo", "texinfo");
- add("application/x-texinfo", "texi");
- add("application/x-troff", "t");
- add("application/x-troff", "roff");
- add("application/x-troff-man", "man");
- add("application/x-ustar", "ustar");
- add("application/x-wais-source", "src");
- add("application/x-wingz", "wz");
- add("application/x-webarchive", "webarchive");
- add("application/x-webarchive-xml", "webarchivexml");
- add("application/x-x509-ca-cert", "crt");
- add("application/x-x509-user-cert", "crt");
- add("application/x-x509-server-cert", "crt");
- add("application/x-xcf", "xcf");
- add("application/x-xfig", "fig");
- add("application/xhtml+xml", "xhtml");
- // Video mime types for 3GPP first so they'll be default for guessMimeTypeFromExtension
- // See RFC 3839 for 3GPP and RFC 4393 for 3GPP2
- add("video/3gpp", "3gpp");
- add("video/3gpp", "3gp");
- add("video/3gpp2", "3gpp2");
- add("video/3gpp2", "3g2");
- add("audio/3gpp", "3gpp");
- add("audio/aac", "aac");
- add("audio/aac-adts", "aac");
- add("audio/amr", "amr");
- add("audio/amr-wb", "awb");
- add("audio/basic", "snd");
- add("audio/flac", "flac");
- add("application/x-flac", "flac");
- add("audio/imelody", "imy");
- add("audio/midi", "mid");
- add("audio/midi", "midi");
- add("audio/midi", "ota");
- add("audio/midi", "kar");
- add("audio/midi", "rtttl");
- add("audio/midi", "xmf");
- add("audio/mobile-xmf", "mxmf");
- // add ".mp3" first so it will be the default for guessExtensionFromMimeType
- add("audio/mpeg", "mp3");
- add("audio/mpeg", "mpga");
- add("audio/mpeg", "mpega");
- add("audio/mpeg", "mp2");
- add("audio/mpeg", "m4a");
- add("audio/mpegurl", "m3u");
- add("audio/ogg", "oga");
- add("audio/ogg", "ogg");
- add("audio/ogg", "spx");
- add("audio/prs.sid", "sid");
- add("audio/x-aiff", "aif");
- add("audio/x-aiff", "aiff");
- add("audio/x-aiff", "aifc");
- add("audio/x-gsm", "gsm");
- add("audio/x-matroska", "mka");
- add("audio/x-mpegurl", "m3u");
- add("audio/x-ms-wma", "wma");
- add("audio/x-ms-wax", "wax");
- add("audio/x-pn-realaudio", "ra");
- add("audio/x-pn-realaudio", "rm");
- add("audio/x-pn-realaudio", "ram");
- add("audio/x-realaudio", "ra");
- add("audio/x-scpls", "pls");
- add("audio/x-sd2", "sd2");
- add("audio/x-wav", "wav");
- // image/bmp isn't IANA, so image/x-ms-bmp should come first.
- add("image/x-ms-bmp", "bmp");
- add("image/bmp", "bmp");
- add("image/gif", "gif");
- // image/ico isn't IANA, so image/x-icon should come first.
- add("image/x-icon", "ico");
- add("image/ico", "cur");
- add("image/ico", "ico");
- add("image/ief", "ief");
- // add ".jpg" first so it will be the default for guessExtensionFromMimeType
- add("image/jpeg", "jpg");
- add("image/jpeg", "jpeg");
- add("image/jpeg", "jpe");
- add("image/pcx", "pcx");
- add("image/png", "png");
- add("image/svg+xml", "svg");
- add("image/svg+xml", "svgz");
- add("image/tiff", "tiff");
- add("image/tiff", "tif");
- add("image/vnd.djvu", "djvu");
- add("image/vnd.djvu", "djv");
- add("image/vnd.wap.wbmp", "wbmp");
- add("image/webp", "webp");
- add("image/x-adobe-dng", "dng");
- add("image/x-canon-cr2", "cr2");
- add("image/x-cmu-raster", "ras");
- add("image/x-coreldraw", "cdr");
- add("image/x-coreldrawpattern", "pat");
- add("image/x-coreldrawtemplate", "cdt");
- add("image/x-corelphotopaint", "cpt");
- add("image/x-fuji-raf", "raf");
- add("image/x-jg", "art");
- add("image/x-jng", "jng");
- add("image/x-nikon-nef", "nef");
- add("image/x-nikon-nrw", "nrw");
- add("image/x-olympus-orf", "orf");
- add("image/x-panasonic-rw2", "rw2");
- add("image/x-pentax-pef", "pef");
- add("image/x-photoshop", "psd");
- add("image/x-portable-anymap", "pnm");
- add("image/x-portable-bitmap", "pbm");
- add("image/x-portable-graymap", "pgm");
- add("image/x-portable-pixmap", "ppm");
- add("image/x-samsung-srw", "srw");
- add("image/x-sony-arw", "arw");
- add("image/x-rgb", "rgb");
- add("image/x-xbitmap", "xbm");
- add("image/x-xpixmap", "xpm");
- add("image/x-xwindowdump", "xwd");
- add("model/iges", "igs");
- add("model/iges", "iges");
- add("model/mesh", "msh");
- add("model/mesh", "mesh");
- add("model/mesh", "silo");
- add("text/calendar", "ics");
- add("text/calendar", "icz");
- add("text/comma-separated-values", "csv");
- add("text/css", "css");
- add("text/html", "htm");
- add("text/html", "html");
- add("text/h323", "323");
- add("text/iuls", "uls");
- add("text/mathml", "mml");
- // add ".txt" first so it will be the default for guessExtensionFromMimeType
- add("text/plain", "txt");
- add("text/plain", "asc");
- add("text/plain", "text");
- add("text/plain", "diff");
- add("text/plain", "po"); // reserve "pot" for vnd.ms-powerpoint
- add("text/richtext", "rtx");
- add("text/rtf", "rtf");
- add("text/text", "phps");
- add("text/tab-separated-values", "tsv");
- add("text/xml", "xml");
- add("text/x-bibtex", "bib");
- add("text/x-boo", "boo");
- add("text/x-c++hdr", "hpp");
- add("text/x-c++hdr", "h++");
- add("text/x-c++hdr", "hxx");
- add("text/x-c++hdr", "hh");
- add("text/x-c++src", "cpp");
- add("text/x-c++src", "c++");
- add("text/x-c++src", "cc");
- add("text/x-c++src", "cxx");
- add("text/x-chdr", "h");
- add("text/x-component", "htc");
- add("text/x-csh", "csh");
- add("text/x-csrc", "c");
- add("text/x-dsrc", "d");
- add("text/x-haskell", "hs");
- add("text/x-java", "java");
- add("text/x-literate-haskell", "lhs");
- add("text/x-moc", "moc");
- add("text/x-pascal", "p");
- add("text/x-pascal", "pas");
- add("text/x-pcs-gcd", "gcd");
- add("text/x-setext", "etx");
- add("text/x-tcl", "tcl");
- add("text/x-tex", "tex");
- add("text/x-tex", "ltx");
- add("text/x-tex", "sty");
- add("text/x-tex", "cls");
- add("text/x-vcalendar", "vcs");
- add("text/x-vcard", "vcf");
- add("video/avi", "avi");
- add("video/dl", "dl");
- add("video/dv", "dif");
- add("video/dv", "dv");
- add("video/fli", "fli");
- add("video/m4v", "m4v");
- add("video/mp2ts", "ts");
- add("video/mpeg", "mpeg");
- add("video/mpeg", "mpg");
- add("video/mpeg", "mpe");
- add("video/mp4", "mp4");
- add("video/mpeg", "VOB");
- add("video/ogg", "ogv");
- add("video/quicktime", "qt");
- add("video/quicktime", "mov");
- add("video/vnd.mpegurl", "mxu");
- add("video/webm", "webm");
- add("video/x-la-asf", "lsf");
- add("video/x-la-asf", "lsx");
- add("video/x-matroska", "mkv");
- add("video/x-mng", "mng");
- add("video/x-ms-asf", "asf");
- add("video/x-ms-asf", "asx");
- add("video/x-ms-wm", "wm");
- add("video/x-ms-wmv", "wmv");
- add("video/x-ms-wmx", "wmx");
- add("video/x-ms-wvx", "wvx");
- add("video/x-sgi-movie", "movie");
- add("video/x-webex", "wrf");
- add("x-conference/x-cooltalk", "ice");
- add("x-epoc/x-sisx-app", "sisx");
+ parseTypes("mime.types");
+ parseTypes("android.mime.types");
}
- private static void add(String mimeType, String extension) {
- // If we have an existing x -> y mapping, we do not want to
- // override it with another mapping x -> y2.
- // If a mime type maps to several extensions
- // the first extension added is considered the most popular
- // so we do not want to overwrite it later.
- if (!mimeTypeToExtensionMap.containsKey(mimeType)) {
- mimeTypeToExtensionMap.put(mimeType, extension);
- }
- if (!extensionToMimeTypeMap.containsKey(extension)) {
- extensionToMimeTypeMap.put(extension, mimeType);
- }
- }
+ private static void parseTypes(String resource) {
+ try (BufferedReader r = new BufferedReader(
+ new InputStreamReader(MimeUtils.class.getResourceAsStream(resource)))) {
+ String line;
+ while ((line = r.readLine()) != null) {
+ int commentPos = line.indexOf('#');
+ if (commentPos >= 0) {
+ line = line.substring(0, commentPos);
+ }
+ line = line.trim();
+ if (line.equals("")) {
+ continue;
+ }
- private MimeUtils() {
+ final String[] split = splitPattern.split(line);
+ final String mimeType = split[0];
+ for (int i = 1; i < split.length; i++) {
+ String extension = split[i].toLowerCase(Locale.US);
+
+ // Normally the first MIME type definition wins, and the
+ // last extension definition wins. However, a file can
+ // override a MIME type definition by adding the "!" suffix
+ // to an extension.
+
+ if (extension.endsWith("!")) {
+ extension = extension.substring(0, extension.length() - 1);
+
+ // Overriding MIME definition wins
+ mimeTypeToExtensionMap.put(mimeType, extension);
+ } else {
+ // First MIME definition wins
+ if (!mimeTypeToExtensionMap.containsKey(mimeType)) {
+ mimeTypeToExtensionMap.put(mimeType, extension);
+ }
+ }
+
+ // Last extension definition wins
+ extensionToMimeTypeMap.put(extension, mimeType);
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to parse " + resource, e);
+ }
}
/**
diff --git a/luni/src/main/java/libcore/net/UriCodec.java b/luni/src/main/java/libcore/net/UriCodec.java
deleted file mode 100644
index 240e910..0000000
--- a/luni/src/main/java/libcore/net/UriCodec.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * 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
- */
-
-package libcore.net;
-
-import java.io.ByteArrayOutputStream;
-import java.net.URISyntaxException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
-import java.nio.charset.StandardCharsets;
-
-/**
- * Encodes and decodes “application/x-www-form-urlencoded” content.
- *
- * Subclasses define “isRetained”, which decides which chars need to be escaped and which don’t.
- * Output is encoded as UTF-8 by default. I.e, each character (or surrogate pair) is converted to
- * its equivalent UTF-8 encoded byte sequence, which is then converted to it’s escaped form.
- * e.g a 4 byte sequence might look like” %c6%ef%e0%e8”
- */
-public abstract class UriCodec {
- /**
- * Returns true iff. ‘c’ does not need to be escaped.
- * 'a’ - ‘z’ , ‘A’ - ‘Z’ and ‘0’ - ‘9’ are always considered valid (i.e, don’t need to be
- * escaped. This set is referred to as the ``whitelist''.
- */
- protected abstract boolean isRetained(char c);
-
- private static boolean isWhitelisted(char c) {
- return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9');
- }
-
- private boolean isWhitelistedOrRetained(char c) {
- return isWhitelisted(c) || isRetained(c);
- }
-
- /**
- * Throw URISyntaxException if any of the characters in the range [start, end) are not valid
- * according to this codec.
- * - If a char is in the whitelist or retained, it is valid both escaped and unescaped.
- * - All escaped octets appearing in the input are structurally valid hex, i.e convertible to
- * decimals.
- *
- * On success, the substring [start, end) is returned.
- * {@code name} is not used, except to generate debugging info.
- */
- public final String validate(String uri, int start, int end, String name)
- throws URISyntaxException {
- int i = start;
- while (i < end) {
- char c = uri.charAt(i++);
- if (isWhitelistedOrRetained(c)) {
- continue;
- }
- // c is either '%' or character not allowed in a uri.
- if (c != '%') {
- throw unexpectedCharacterException(uri, name, c, i - 1);
- }
- // Expect two characters representing a number in hex.
- for (int j = 0; j < 2; j++) {
- c = getNextCharacter(uri, i++, end, name);
- if (hexCharToValue(c) < 0) {
- throw unexpectedCharacterException(uri, name, c, i - 1);
- }
- }
- }
- return uri.substring(start, end);
- }
-
- /**
- * Interprets a char as hex digits, returning a number from -1 (invalid char) to 15 ('f').
- */
- private static int hexCharToValue(char c) {
- if('0' <= c && c <= '9') {
- return c - '0';
- }
- if ('a' <= c && c <= 'f') {
- return 10 + c - 'a';
- }
- if ('A' <= c && c <= 'F') {
- return 10 + c - 'A';
- }
- return -1;
- }
-
- private static URISyntaxException unexpectedCharacterException(
- String uri, String name, char unexpected, int index) {
- String nameString = (name == null) ? "" : " in [" + name + "]";
- return new URISyntaxException(
- uri, "Unexpected character" + nameString + ": " + unexpected, index);
- }
-
- private static char getNextCharacter(String uri, int index, int end, String name)
- throws URISyntaxException {
- if (index >= end) {
- String nameString = (name == null) ? "" : " in [" + name + "]";
- throw new URISyntaxException(
- uri, "Unexpected end of string" + nameString, index);
- }
- return uri.charAt(index);
- }
-
- /**
- * Throws {@link URISyntaxException} if any character in {@code uri} is neither whitelisted nor
- * in {@code legal}.
- */
- public static void validateSimple(String uri, String legal) throws URISyntaxException {
- for (int i = 0; i < uri.length(); i++) {
- char c = uri.charAt(i);
- if (!isWhitelisted(c) && legal.indexOf(c) < 0) {
- throw unexpectedCharacterException(uri, null /* name */, c, i);
- }
- }
- }
-
- /**
- * Encodes the string {@code s} as per the rules of this encoder (see class level comment).
- *
- * @throws IllegalArgumentException if the encoder is unable to encode a sequence of bytes.
- */
- public final String encode(String s, Charset charset) {
- StringBuilder builder = new StringBuilder(s.length());
- appendEncoded(builder, s, charset, false);
- return builder.toString();
- }
-
- /**
- * Encodes the string {@code s} as per the rules of this encoder (see class level comment).
- *
- * Encoded output is appended to {@code builder}. This uses the default output encoding (UTF-8).
- */
- public final void appendEncoded(StringBuilder builder, String s) {
- appendEncoded(builder, s, StandardCharsets.UTF_8, false);
- }
-
- /**
- * Encodes the string {@code s} as per the rules of this encoder (see class level comment).
- *
- * Encoded output is appended to {@code builder}. This uses the default output encoding (UTF-8).
- * This method must produce partially encoded output. What this means is that if encoded octets
- * appear in the input string, they are passed through unmodified, instead of being double
- * escaped. Consider a decoder operating on the global whitelist dealing with a string
- * “foo%25bar”. With this method, the output will be “foo%25bar”, but with appendEncoded, it
- * will be double encoded into “foo%2525bar”.
- */
- public final void appendPartiallyEncoded(StringBuilder builder, String s) {
- appendEncoded(builder, s, StandardCharsets.UTF_8, true);
- }
-
- private void appendEncoded(
- StringBuilder builder, String s, Charset charset, boolean partiallyEncoded) {
- CharsetEncoder encoder = charset.newEncoder()
- .onMalformedInput(CodingErrorAction.REPORT)
- .onUnmappableCharacter(CodingErrorAction.REPORT);
- CharBuffer cBuffer = CharBuffer.allocate(s.length());
- for (int i = 0; i < s.length(); i++) {
- char c = s.charAt(i);
- if (c == '%' && partiallyEncoded) {
- // In case there are characters waiting to be encoded.
- flushEncodingCharBuffer(builder, encoder, cBuffer);
- builder.append('%');
- continue;
- }
-
- if (c == ' ' && isRetained(' ')) {
- flushEncodingCharBuffer(builder, encoder, cBuffer);
- builder.append('+');
- continue;
- }
-
- if (isWhitelistedOrRetained(c)) {
- flushEncodingCharBuffer(builder, encoder, cBuffer);
- builder.append(c);
- continue;
- }
-
- // Put the character in the queue for encoding.
- cBuffer.put(c);
- }
- flushEncodingCharBuffer(builder, encoder, cBuffer);
- }
-
- private static void flushEncodingCharBuffer(
- StringBuilder builder,
- CharsetEncoder encoder,
- CharBuffer cBuffer) {
- if (cBuffer.position() == 0) {
- return;
- }
- // We are reading from the buffer now.
- cBuffer.flip();
- ByteBuffer byteBuffer = ByteBuffer.allocate(
- cBuffer.remaining() * (int) Math.ceil(encoder.maxBytesPerChar()));
- byteBuffer.position(0);
- CoderResult result = encoder.encode(cBuffer, byteBuffer, true /* endOfInput */);
- // According to the {@code CharsetEncoder#encode} spec, the method returns underflow
- // and leaves an empty output when all bytes were processed correctly.
- if (result != CoderResult.UNDERFLOW) {
- throw new IllegalArgumentException(
- "Error encoding, unexpected result ["
- + result.toString()
- + "] using encoder for ["
- + encoder.charset().name()
- + "]");
- }
- if (cBuffer.hasRemaining()) {
- throw new IllegalArgumentException(
- "Encoder for [" + encoder.charset().name() + "] failed with underflow with "
- + "remaining input [" + cBuffer + "]");
- }
- // Need to flush in case the encoder saves internal state.
- encoder.flush(byteBuffer);
- if (result != CoderResult.UNDERFLOW) {
- throw new IllegalArgumentException(
- "Error encoding, unexpected result ["
- + result.toString()
- + "] flushing encoder for ["
- + encoder.charset().name()
- + "]");
- }
- encoder.reset();
-
- byteBuffer.flip();
- // Write the encoded bytes.
- while(byteBuffer.hasRemaining()) {
- byte b = byteBuffer.get();
- builder.append('%');
- builder.append(intToHexDigit((b & 0xf0) >>> 4));
- builder.append(intToHexDigit(b & 0x0f));
-
- }
- // Use the character buffer to write again.
- cBuffer.flip();
- cBuffer.limit(cBuffer.capacity());
- }
-
- private static char intToHexDigit(int b) {
- if (b < 10) {
- return (char) ('0' + b);
- } else {
- return (char) ('A' + b - 10);
- }
- }
-
- /**
- * Decode a string according to the rules of this decoder.
- *
- * - if {@code convertPlus == true} all ‘+’ chars in the decoded output are converted to ‘ ‘
- * (white space)
- * - if {@code throwOnFailure == true}, an {@link IllegalArgumentException} is thrown for
- * invalid inputs. Else, U+FFFd is emitted to the output in place of invalid input octets.
- */
- public static String decode(
- String s, boolean convertPlus, Charset charset, boolean throwOnFailure) {
- StringBuilder builder = new StringBuilder(s.length());
- appendDecoded(builder, s, convertPlus, charset, throwOnFailure);
- return builder.toString();
- }
-
- /**
- * Character to be output when there's an error decoding an input.
- */
- private static final char INVALID_INPUT_CHARACTER = '\ufffd';
-
- private static void appendDecoded(
- StringBuilder builder,
- String s,
- boolean convertPlus,
- Charset charset,
- boolean throwOnFailure) {
- CharsetDecoder decoder = charset.newDecoder()
- .onMalformedInput(CodingErrorAction.REPLACE)
- .replaceWith("\ufffd")
- .onUnmappableCharacter(CodingErrorAction.REPORT);
- // Holds the bytes corresponding to the escaped chars being read (empty if the last char
- // wasn't a escaped char).
- ByteBuffer byteBuffer = ByteBuffer.allocate(s.length());
- int i = 0;
- while (i < s.length()) {
- char c = s.charAt(i);
- i++;
- switch (c) {
- case '+':
- flushDecodingByteAccumulator(
- builder, decoder, byteBuffer, throwOnFailure);
- builder.append(convertPlus ? ' ' : '+');
- break;
- case '%':
- // Expect two characters representing a number in hex.
- byte hexValue = 0;
- for (int j = 0; j < 2; j++) {
- try {
- c = getNextCharacter(s, i, s.length(), null /* name */);
- } catch (URISyntaxException e) {
- // Unexpected end of input.
- if (throwOnFailure) {
- throw new IllegalArgumentException(e);
- } else {
- flushDecodingByteAccumulator(
- builder, decoder, byteBuffer, throwOnFailure);
- builder.append(INVALID_INPUT_CHARACTER);
- return;
- }
- }
- i++;
- int newDigit = hexCharToValue(c);
- if (newDigit < 0) {
- if (throwOnFailure) {
- throw new IllegalArgumentException(
- unexpectedCharacterException(s, null /* name */, c, i - 1));
- } else {
- flushDecodingByteAccumulator(
- builder, decoder, byteBuffer, throwOnFailure);
- builder.append(INVALID_INPUT_CHARACTER);
- break;
- }
- }
- hexValue = (byte) (hexValue * 0x10 + newDigit);
- }
- byteBuffer.put(hexValue);
- break;
- default:
- flushDecodingByteAccumulator(builder, decoder, byteBuffer, throwOnFailure);
- builder.append(c);
- }
- }
- flushDecodingByteAccumulator(builder, decoder, byteBuffer, throwOnFailure);
- }
-
- private static void flushDecodingByteAccumulator(
- StringBuilder builder,
- CharsetDecoder decoder,
- ByteBuffer byteBuffer,
- boolean throwOnFailure) {
- if (byteBuffer.position() == 0) {
- return;
- }
- byteBuffer.flip();
- try {
- builder.append(decoder.decode(byteBuffer));
- } catch (CharacterCodingException e) {
- if (throwOnFailure) {
- throw new IllegalArgumentException(e);
- } else {
- builder.append(INVALID_INPUT_CHARACTER);
- }
- } finally {
- // Use the byte buffer to write again.
- byteBuffer.flip();
- byteBuffer.limit(byteBuffer.capacity());
- }
- }
-
- /**
- * Equivalent to {@code decode(s, false, UTF_8, true)}
- */
- public static String decode(String s) {
- return decode(
- s, false /* convertPlus */, StandardCharsets.UTF_8, true /* throwOnFailure */);
- }
-}
\ No newline at end of file
diff --git a/luni/src/main/java/libcore/net/android.mime.types b/luni/src/main/java/libcore/net/android.mime.types
new file mode 100644
index 0000000..0413051
--- /dev/null
+++ b/luni/src/main/java/libcore/net/android.mime.types
@@ -0,0 +1,93 @@
+
+###############################################################################
+#
+# Android-specific MIME type mappings
+#
+# MIME types that Android has manually added or historically chosen to
+# override, and which take precidence over any upstream mime.types.
+#
+###############################################################################
+
+application/epub+zip epub
+application/pkix-cert cer
+application/rss+xml rss
+application/vnd.apple.mpegurl m3u8
+application/vnd.ms-pki.stl stl
+application/vnd.ms-powerpoint pot
+application/vnd.ms-wpl wpl
+application/vnd.stardivision.impress sdp
+application/vnd.stardivision.writer vor
+application/vnd.youtube.yt yt
+application/x-android-drm-fl fl
+application/x-flac flac
+application/x-font pcf
+application/x-mpegurl m3u m3u8
+application/x-pem-file pem
+application/x-pkcs12 p12 pfx
+application/x-webarchive webarchive
+application/x-webarchive-xml webarchivexml
+application/x-x509-server-cert crt
+application/x-x509-user-cert crt
+
+audio/3gpp 3gpp
+audio/aac-adts aac
+audio/imelody imy
+audio/midi ota rtttl xmf
+audio/mobile-xmf mxmf
+audio/mp4 m4a
+audio/mpegurl m3u
+audio/sp-midi smf
+audio/x-matroska mka
+audio/x-pn-realaudio ra
+
+image/bmp bmp
+image/heic heic
+image/heic-sequence heics
+image/heif heif hif
+image/heif-sequence heifs
+image/ico cur
+image/webp webp
+image/x-adobe-dng dng
+image/x-fuji-raf raf
+image/x-icon ico
+image/x-nikon-nrw nrw
+image/x-panasonic-rw2 rw2
+image/x-pentax-pef pef
+image/x-samsung-srw srw
+image/x-sony-arw arw
+
+text/comma-separated-values csv
+text/plain diff po
+text/rtf rtf
+text/text phps
+text/xml xml
+text/x-vcard vcf
+
+video/3gpp2 3gpp2 3g2
+video/3gpp 3gpp
+video/avi avi
+video/m4v m4v
+video/mp2p mpeg
+video/mp2ts ts
+video/x-webex wrf
+
+# Special cases where Android has a strong opinion about mappings, so we
+# define them very last and use "!" to ensure that we force the mapping
+# in both directions.
+application/pgp-signature pgp!
+application/x-x509-ca-cert crt!
+audio/aac aac!
+audio/basic snd!
+audio/flac flac!
+audio/midi rtx!
+audio/mpeg mp3! m4a
+audio/x-mpegurl m3u8! m3u!
+image/jpeg jpg!
+image/x-ms-bmp bmp!
+text/plain txt!
+text/x-c++hdr hpp!
+text/x-c++src cpp!
+video/3gpp 3gpp!
+video/mpeg mpeg!
+video/quicktime mov!
+video/x-matroska mkv!
diff --git a/luni/src/main/java/libcore/net/mime.types b/luni/src/main/java/libcore/net/mime.types
new file mode 100644
index 0000000..dfa7a42
--- /dev/null
+++ b/luni/src/main/java/libcore/net/mime.types
@@ -0,0 +1,844 @@
+###############################################################################
+#
+# MIME media types and the extensions that represent them.
+#
+# The format of this file is a media type on the left and zero or more
+# filename extensions on the right. Programs using this file will map
+# files ending with those extensions to the associated type.
+#
+# This file is part of the "mime-support" package. Please report a bug using
+# the "reportbug" command of the "reportbug" package if you would like new
+# types or extensions to be added.
+#
+# The reason that all types are managed by the mime-support package instead
+# allowing individual packages to install types in much the same way as they
+# add entries in to the mailcap file is so these types can be referenced by
+# other programs (such as a web server) even if the specific support package
+# for that type is not installed.
+#
+# Users can add their own types if they wish by creating a ".mime.types"
+# file in their home directory. Definitions included there will take
+# precedence over those listed here.
+#
+###############################################################################
+
+
+application/activemessage
+application/andrew-inset ez
+application/annodex anx
+application/applefile
+application/atom+xml atom
+application/atomcat+xml atomcat
+application/atomicmail
+application/atomserv+xml atomsrv
+application/batch-SMTP
+application/bbolin lin
+application/beep+xml
+application/cals-1840
+application/commonground
+application/cu-seeme cu
+application/cybercash
+application/davmount+xml davmount
+application/dca-rft
+application/dec-dx
+application/dicom dcm
+application/docbook+xml
+application/dsptype tsp
+application/dvcs
+application/ecmascript es
+application/edi-consent
+application/edi-x12
+application/edifact
+application/epub+zip epub
+application/eshop
+application/font-sfnt otf ttf
+application/font-tdpfr pfr
+application/font-woff woff
+application/futuresplash spl
+application/ghostview
+application/gzip gz
+application/hta hta
+application/http
+application/hyperstudio
+application/iges
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/iotp
+application/ipp
+application/isup
+application/java-archive jar
+application/java-serialized-object ser
+application/java-vm class
+application/javascript js
+application/json json
+application/m3g m3g
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/marc
+application/mathematica nb nbp
+application/mbox mbox
+application/ms-tnef
+application/msaccess mdb
+application/msword doc dot
+application/mxf mxf
+application/news-message-id
+application/news-transmission
+application/ocsp-request
+application/ocsp-response
+application/octet-stream bin deploy msu msp
+application/oda oda
+application/oebps-package+xml opf
+application/ogg ogx
+application/onenote one onetoc2 onetmp onepkg
+application/parityfec
+application/pdf pdf
+application/pgp-encrypted pgp
+application/pgp-keys key
+application/pgp-signature sig
+application/pics-rules prf
+application/pkcs10
+application/pkcs7-mime
+application/pkcs7-signature
+application/pkix-cert
+application/pkix-crl
+application/pkixcmp
+application/postscript ps ai eps epsi epsf eps2 eps3
+application/prs.alvestrand.titrax-sheet
+application/prs.cww
+application/prs.nprend
+application/qsig
+application/rar rar
+application/rdf+xml rdf
+application/remote-printing
+application/riscos
+application/rtf rtf
+application/sdp
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog
+application/sieve
+application/sla stl
+application/slate
+application/smil+xml smi smil
+application/timestamp-query
+application/timestamp-reply
+application/vemmi
+application/whoispp-query
+application/whoispp-response
+application/wita
+application/x400-bp
+application/xhtml+xml xhtml xht
+application/xml xml xsd
+application/xml-dtd
+application/xml-external-parsed-entity
+application/xslt+xml xsl xslt
+application/xspf+xml xspf
+application/zip zip
+application/vnd.3M.Post-it-Notes
+application/vnd.accpac.simply.aso
+application/vnd.accpac.simply.imp
+application/vnd.acucobol
+application/vnd.aether.imp
+application/vnd.android.package-archive apk
+application/vnd.anser-web-certificate-issue-initiation
+application/vnd.anser-web-funds-transfer-initiation
+application/vnd.audiograph
+application/vnd.bmi
+application/vnd.businessobjects
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.cinderella cdy
+application/vnd.claymore
+application/vnd.commerce-battelle
+application/vnd.commonspace
+application/vnd.comsocaller
+application/vnd.contact.cmsg
+application/vnd.cosmocaller
+application/vnd.ctc-posml
+application/vnd.cups-postscript
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.cybank
+application/vnd.debian.binary-package deb ddeb udeb
+application/vnd.dna
+application/vnd.dpgraph
+application/vnd.dxr
+application/vnd.ecdis-update
+application/vnd.ecowin.chart
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+application/vnd.enliven
+application/vnd.epson.esf
+application/vnd.epson.msf
+application/vnd.epson.quickanime
+application/vnd.epson.salt
+application/vnd.epson.ssf
+application/vnd.ericsson.quickcall
+application/vnd.eudora.data
+application/vnd.fdf
+application/vnd.ffsns
+application/vnd.flographit
+application/vnd.font-fontforge-sfd sfd
+application/vnd.framemaker
+application/vnd.fsc.weblaunch
+application/vnd.fujitsu.oasys
+application/vnd.fujitsu.oasys2
+application/vnd.fujitsu.oasys3
+application/vnd.fujitsu.oasysgp
+application/vnd.fujitsu.oasysprs
+application/vnd.fujixerox.ddd
+application/vnd.fujixerox.docuworks
+application/vnd.fujixerox.docuworks.binder
+application/vnd.fut-misnet
+application/vnd.google-earth.kml+xml kml
+application/vnd.google-earth.kmz kmz
+application/vnd.grafeq
+application/vnd.groove-account
+application/vnd.groove-identity-message
+application/vnd.groove-injector
+application/vnd.groove-tool-message
+application/vnd.groove-tool-template
+application/vnd.groove-vcard
+application/vnd.hhe.lesson-player
+application/vnd.hp-HPGL
+application/vnd.hp-PCL
+application/vnd.hp-PCLXL
+application/vnd.hp-hpid
+application/vnd.hp-hps
+application/vnd.httphone
+application/vnd.hzn-3d-crossword
+application/vnd.ibm.MiniPay
+application/vnd.ibm.afplinedata
+application/vnd.ibm.modcap
+application/vnd.informix-visionary
+application/vnd.intercon.formnet
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo
+application/vnd.intu.qfx
+application/vnd.irepository.package+xml
+application/vnd.is-xpr
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.koan
+application/vnd.lotus-1-2-3
+application/vnd.lotus-approach
+application/vnd.lotus-freelance
+application/vnd.lotus-notes
+application/vnd.lotus-organizer
+application/vnd.lotus-screencam
+application/vnd.lotus-wordpro
+application/vnd.mcd
+application/vnd.mediastation.cdkey
+application/vnd.meridian-slingshot
+application/vnd.mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf
+application/vnd.mobius.dis
+application/vnd.mobius.msl
+application/vnd.mobius.plc
+application/vnd.mobius.txf
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.mozilla.xul+xml xul
+application/vnd.ms-artgalry
+application/vnd.ms-asf
+application/vnd.ms-excel xls xlb xlt
+application/vnd.ms-excel.addin.macroEnabled.12 xlam
+application/vnd.ms-excel.sheet.binary.macroEnabled.12 xlsb
+application/vnd.ms-excel.sheet.macroEnabled.12 xlsm
+application/vnd.ms-excel.template.macroEnabled.12 xltm
+application/vnd.ms-fontobject eot
+application/vnd.ms-lrm
+application/vnd.ms-officetheme thmx
+application/vnd.ms-pki.seccat cat
+#application/vnd.ms-pki.stl stl
+application/vnd.ms-powerpoint ppt pps
+application/vnd.ms-powerpoint.addin.macroEnabled.12 ppam
+application/vnd.ms-powerpoint.presentation.macroEnabled.12 pptm
+application/vnd.ms-powerpoint.slide.macroEnabled.12 sldm
+application/vnd.ms-powerpoint.slideshow.macroEnabled.12 ppsm
+application/vnd.ms-powerpoint.template.macroEnabled.12 potm
+application/vnd.ms-project
+application/vnd.ms-tnef
+application/vnd.ms-word.document.macroEnabled.12 docm
+application/vnd.ms-word.template.macroEnabled.12 dotm
+application/vnd.ms-works
+application/vnd.mseq
+application/vnd.msign
+application/vnd.music-niff
+application/vnd.musician
+application/vnd.netfpx
+application/vnd.noblenet-directory
+application/vnd.noblenet-sealer
+application/vnd.noblenet-web
+application/vnd.novadigm.EDM
+application/vnd.novadigm.EDX
+application/vnd.novadigm.EXT
+application/vnd.oasis.opendocument.chart odc
+application/vnd.oasis.opendocument.database odb
+application/vnd.oasis.opendocument.formula odf
+application/vnd.oasis.opendocument.graphics odg
+application/vnd.oasis.opendocument.graphics-template otg
+application/vnd.oasis.opendocument.image odi
+application/vnd.oasis.opendocument.presentation odp
+application/vnd.oasis.opendocument.presentation-template otp
+application/vnd.oasis.opendocument.spreadsheet ods
+application/vnd.oasis.opendocument.spreadsheet-template ots
+application/vnd.oasis.opendocument.text odt
+application/vnd.oasis.opendocument.text-master odm
+application/vnd.oasis.opendocument.text-template ott
+application/vnd.oasis.opendocument.text-web oth
+application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
+application/vnd.openxmlformats-officedocument.presentationml.slide sldx
+application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
+application/vnd.openxmlformats-officedocument.presentationml.template potx
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
+application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
+application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
+application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
+application/vnd.osa.netdeploy
+application/vnd.palm
+application/vnd.pg.format
+application/vnd.pg.osasli
+application/vnd.powerbuilder6
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.previewsystems.box
+application/vnd.publishare-delta-tree
+application/vnd.pvi.ptid1
+application/vnd.pwg-xhtml-print+xml
+application/vnd.rapid
+application/vnd.rim.cod cod
+application/vnd.s3sms
+application/vnd.seemail
+application/vnd.shana.informed.formdata
+application/vnd.shana.informed.formtemplate
+application/vnd.shana.informed.interchange
+application/vnd.shana.informed.package
+application/vnd.smaf mmf
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.stardivision.calc sdc
+application/vnd.stardivision.chart sds
+application/vnd.stardivision.draw sda
+application/vnd.stardivision.impress sdd
+application/vnd.stardivision.math sdf
+application/vnd.stardivision.writer sdw
+application/vnd.stardivision.writer-global sgl
+application/vnd.street-stream
+application/vnd.sun.xml.calc sxc
+application/vnd.sun.xml.calc.template stc
+application/vnd.sun.xml.draw sxd
+application/vnd.sun.xml.draw.template std
+application/vnd.sun.xml.impress sxi
+application/vnd.sun.xml.impress.template sti
+application/vnd.sun.xml.math sxm
+application/vnd.sun.xml.writer sxw
+application/vnd.sun.xml.writer.global sxg
+application/vnd.sun.xml.writer.template stw
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.symbian.install sis
+application/vnd.tcpdump.pcap cap pcap
+application/vnd.triscape.mxs
+application/vnd.trueapp
+application/vnd.truedoc
+application/vnd.tve-trigger
+application/vnd.ufdl
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.vcx
+application/vnd.vectorworks
+application/vnd.vidsoft.vidconference
+application/vnd.visio vsd vst vsw vss
+application/vnd.vividence.scriptfile
+application/vnd.wap.sic
+application/vnd.wap.slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo
+application/vnd.wordperfect wpd
+application/vnd.wordperfect5.1 wp5
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf
+application/vnd.xara
+application/vnd.xfdl
+application/vnd.yellowriver-custom-menu
+application/zlib
+application/x-123 wk
+application/x-7z-compressed 7z
+application/x-abiword abw
+application/x-apple-diskimage dmg
+application/x-bcpio bcpio
+application/x-bittorrent torrent
+application/x-cab cab
+application/x-cbr cbr
+application/x-cbz cbz
+application/x-cdf cdf cda
+application/x-cdlink vcd
+application/x-chess-pgn pgn
+application/x-comsol mph
+application/x-core
+application/x-cpio cpio
+application/x-csh csh
+application/x-debian-package deb udeb
+application/x-director dcr dir dxr
+application/x-dms dms
+application/x-doom wad
+application/x-dvi dvi
+application/x-executable
+application/x-font pfa pfb gsf
+application/x-font-pcf pcf pcf.Z
+application/x-freemind mm
+application/x-futuresplash spl
+application/x-ganttproject gan
+application/x-gnumeric gnumeric
+application/x-go-sgf sgf
+application/x-graphing-calculator gcf
+application/x-gtar gtar
+application/x-gtar-compressed tgz taz
+application/x-hdf hdf
+#application/x-httpd-eruby rhtml
+#application/x-httpd-php phtml pht php
+#application/x-httpd-php-source phps
+#application/x-httpd-php3 php3
+#application/x-httpd-php3-preprocessed php3p
+#application/x-httpd-php4 php4
+#application/x-httpd-php5 php5
+application/x-hwp hwp
+application/x-ica ica
+application/x-info info
+application/x-internet-signup ins isp
+application/x-iphone iii
+application/x-iso9660-image iso
+application/x-jam jam
+application/x-java-applet
+application/x-java-bean
+application/x-java-jnlp-file jnlp
+application/x-jmol jmz
+application/x-kchart chrt
+application/x-kdelnk
+application/x-killustrator kil
+application/x-koan skp skd skt skm
+application/x-kpresenter kpr kpt
+application/x-kspread ksp
+application/x-kword kwd kwt
+application/x-latex latex
+application/x-lha lha
+application/x-lyx lyx
+application/x-lzh lzh
+application/x-lzx lzx
+application/x-maker frm maker frame fm fb book fbdoc
+application/x-mif mif
+application/x-mpegURL m3u8
+application/x-ms-application application
+application/x-ms-manifest manifest
+application/x-ms-wmd wmd
+application/x-ms-wmz wmz
+application/x-msdos-program com exe bat dll
+application/x-msi msi
+application/x-netcdf nc
+application/x-ns-proxy-autoconfig pac
+application/x-nwc nwc
+application/x-object o
+application/x-oz-application oza
+application/x-pkcs7-certreqresp p7r
+application/x-pkcs7-crl crl
+application/x-python-code pyc pyo
+application/x-qgis qgs shp shx
+application/x-quicktimeplayer qtl
+application/x-rdp rdp
+application/x-redhat-package-manager rpm
+application/x-rss+xml rss
+application/x-ruby rb
+application/x-rx
+application/x-scilab sci sce
+application/x-scilab-xcos xcos
+application/x-sh sh
+application/x-shar shar
+application/x-shellscript
+application/x-shockwave-flash swf swfl
+application/x-silverlight scr
+application/x-sql sql
+application/x-stuffit sit sitx
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex-gf gf
+application/x-tex-pk pk
+application/x-texinfo texinfo texi
+application/x-trash ~ % bak old sik
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-videolan
+application/x-wais-source src
+application/x-wingz wz
+application/x-x509-ca-cert crt
+application/x-xcf xcf
+application/x-xfig fig
+application/x-xpinstall xpi
+application/x-xz xz
+
+audio/32kadpcm
+audio/3gpp
+audio/amr amr
+audio/amr-wb awb
+audio/annodex axa
+audio/basic au snd
+audio/csound csd orc sco
+audio/flac flac
+audio/g.722.1
+audio/l16
+audio/midi mid midi kar
+audio/mp4a-latm
+audio/mpa-robust
+audio/mpeg mpga mpega mp2 mp3 m4a
+audio/mpegurl m3u
+audio/ogg oga ogg opus spx
+audio/parityfec
+audio/prs.sid sid
+audio/telephone-event
+audio/tone
+audio/vnd.cisco.nse
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.digital-winds
+audio/vnd.everad.plj
+audio/vnd.lucent.voice
+audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800
+audio/vnd.nuera.ecelp7470
+audio/vnd.nuera.ecelp9600
+audio/vnd.octel.sbc
+audio/vnd.qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.vmx.cvsd
+audio/x-aiff aif aiff aifc
+audio/x-gsm gsm
+audio/x-mpegurl m3u
+audio/x-ms-wma wma
+audio/x-ms-wax wax
+audio/x-pn-realaudio-plugin
+audio/x-pn-realaudio ra rm ram
+audio/x-realaudio ra
+audio/x-scpls pls
+audio/x-sd2 sd2
+audio/x-wav wav
+
+chemical/x-alchemy alc
+chemical/x-cache cac cache
+chemical/x-cache-csf csf
+chemical/x-cactvs-binary cbin cascii ctab
+chemical/x-cdx cdx
+chemical/x-cerius cer
+chemical/x-chem3d c3d
+chemical/x-chemdraw chm
+chemical/x-cif cif
+chemical/x-cmdf cmdf
+chemical/x-cml cml
+chemical/x-compass cpa
+chemical/x-crossfire bsd
+chemical/x-csml csml csm
+chemical/x-ctx ctx
+chemical/x-cxf cxf cef
+#chemical/x-daylight-smiles smi
+chemical/x-embl-dl-nucleotide emb embl
+chemical/x-galactic-spc spc
+chemical/x-gamess-input inp gam gamin
+chemical/x-gaussian-checkpoint fch fchk
+chemical/x-gaussian-cube cub
+chemical/x-gaussian-input gau gjc gjf
+chemical/x-gaussian-log gal
+chemical/x-gcg8-sequence gcg
+chemical/x-genbank gen
+chemical/x-hin hin
+chemical/x-isostar istr ist
+chemical/x-jcamp-dx jdx dx
+chemical/x-kinemage kin
+chemical/x-macmolecule mcm
+chemical/x-macromodel-input mmd mmod
+chemical/x-mdl-molfile mol
+chemical/x-mdl-rdfile rd
+chemical/x-mdl-rxnfile rxn
+chemical/x-mdl-sdfile sd sdf
+chemical/x-mdl-tgf tgf
+#chemical/x-mif mif
+chemical/x-mmcif mcif
+chemical/x-mol2 mol2
+chemical/x-molconn-Z b
+chemical/x-mopac-graph gpt
+chemical/x-mopac-input mop mopcrt mpc zmt
+chemical/x-mopac-out moo
+chemical/x-mopac-vib mvb
+chemical/x-ncbi-asn1 asn
+chemical/x-ncbi-asn1-ascii prt ent
+chemical/x-ncbi-asn1-binary val aso
+chemical/x-ncbi-asn1-spec asn
+chemical/x-pdb pdb ent
+chemical/x-rosdal ros
+chemical/x-swissprot sw
+chemical/x-vamas-iso14976 vms
+chemical/x-vmd vmd
+chemical/x-xtel xtel
+chemical/x-xyz xyz
+
+font/collection ttc
+font/otf ttf otf
+font/sfnt ttf otf
+font/ttf ttf otf
+font/woff woff
+font/woff2 woff2
+
+image/cgm
+image/g3fax
+image/gif gif
+image/ief ief
+image/jp2 jp2 jpg2
+image/jpeg jpeg jpg jpe
+image/jpm jpm
+image/jpx jpx jpf
+image/naplps
+image/pcx pcx
+image/png png
+image/prs.btif
+image/prs.pti
+image/svg+xml svg svgz
+image/tiff tiff tif
+image/vnd.cns.inf2
+image/vnd.djvu djvu djv
+image/vnd.dwg
+image/vnd.dxf
+image/vnd.fastbidsheet
+image/vnd.fpx
+image/vnd.fst
+image/vnd.fujixerox.edmics-mmr
+image/vnd.fujixerox.edmics-rlc
+image/vnd.microsoft.icon ico
+image/vnd.mix
+image/vnd.net-fpx
+image/vnd.svf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff
+image/x-canon-cr2 cr2
+image/x-canon-crw crw
+image/x-cmu-raster ras
+image/x-coreldraw cdr
+image/x-coreldrawpattern pat
+image/x-coreldrawtemplate cdt
+image/x-corelphotopaint cpt
+image/x-epson-erf erf
+image/x-icon
+image/x-jg art
+image/x-jng jng
+image/x-ms-bmp bmp
+image/x-nikon-nef nef
+image/x-olympus-orf orf
+image/x-photoshop psd
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+
+inode/chardevice
+inode/blockdevice
+inode/directory-locked
+inode/directory
+inode/fifo
+inode/socket
+
+message/delivery-status
+message/disposition-notification
+message/external-body
+message/http
+message/s-http
+message/news
+message/partial
+message/rfc822 eml
+
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.dwf
+model/vnd.flatland.3dml
+model/vnd.gdl
+model/vnd.gs-gdl
+model/vnd.gtw
+model/vnd.mts
+model/vnd.vtu
+model/vrml wrl vrml
+model/x3d+vrml x3dv
+model/x3d+xml x3d
+model/x3d+binary x3db
+
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/voice-message
+
+text/cache-manifest appcache
+text/calendar ics icz
+text/css css
+text/csv csv
+text/directory
+text/english
+text/enriched
+text/h323 323
+text/html html htm shtml
+text/iuls uls
+text/mathml mml
+text/markdown md markdown
+text/parityfec
+text/plain asc txt text pot brf srt
+text/prs.lines.tag
+text/rfc822-headers
+text/richtext rtx
+text/rtf
+text/scriptlet sct wsc
+text/t140
+text/texmacs tm
+text/tab-separated-values tsv
+text/turtle ttl
+text/uri-list
+text/vcard vcf vcard
+text/vnd.abc
+text/vnd.curl
+text/vnd.debian.copyright
+text/vnd.DMClientScript
+text/vnd.flatland.3dml
+text/vnd.fly
+text/vnd.fmi.flexstor
+text/vnd.in3d.3dml
+text/vnd.in3d.spot
+text/vnd.IPTC.NewsML
+text/vnd.IPTC.NITF
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage
+text/vnd.sun.j2me.app-descriptor jad
+text/vnd.wap.si
+text/vnd.wap.sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/x-bibtex bib
+text/x-boo boo
+text/x-c++hdr h++ hpp hxx hh
+text/x-c++src c++ cpp cxx cc
+text/x-chdr h
+text/x-component htc
+text/x-crontab
+text/x-csh csh
+text/x-csrc c
+text/x-dsrc d
+text/x-diff diff patch
+text/x-haskell hs
+text/x-java java
+text/x-lilypond ly
+text/x-literate-haskell lhs
+text/x-makefile
+text/x-moc moc
+text/x-pascal p pas
+text/x-pcs-gcd gcd
+text/x-perl pl pm
+text/x-python py
+text/x-scala scala
+text/x-server-parsed-html
+text/x-setext etx
+text/x-sfv sfv
+text/x-sh sh
+text/x-tcl tcl tk
+text/x-tex tex ltx sty cls
+text/x-vcalendar vcs
+
+video/3gpp 3gp
+video/annodex axv
+video/dl dl
+video/dv dif dv
+video/fli fli
+video/gl gl
+video/mpeg mpeg mpg mpe
+video/MP2T ts
+video/mp4 mp4
+video/quicktime qt mov
+video/mp4v-es
+video/ogg ogv
+video/parityfec
+video/pointer
+video/webm webm
+video/vnd.fvt
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl mxu
+video/vnd.mts
+video/vnd.nokia.interleaved-multimedia
+video/vnd.vivo
+video/x-flv flv
+video/x-la-asf lsf lsx
+video/x-mng mng
+video/x-ms-asf asf asx
+video/x-ms-wm wm
+video/x-ms-wmv wmv
+video/x-ms-wmx wmx
+video/x-ms-wvx wvx
+video/x-msvideo avi
+video/x-sgi-movie movie
+video/x-matroska mpv mkv
+
+x-conference/x-cooltalk ice
+
+x-epoc/x-sisx-app sisx
+x-world/x-vrml vrm vrml wrl
diff --git a/luni/src/main/java/libcore/net/mime.types.README b/luni/src/main/java/libcore/net/mime.types.README
new file mode 100644
index 0000000..3479703
--- /dev/null
+++ b/luni/src/main/java/libcore/net/mime.types.README
@@ -0,0 +1,13 @@
+
+Debian is the upstream for this mapping file:
+https://salsa.debian.org/debian/mime-support
+
+Last updated as of commit d4bbcca4ba04582ad1d253d82fc139bb23841a43.
+
+Copyright: public-domain
+License: ad-hoc
+ This package was written by Brian White <bcwhite@pobox.com> and others.
+ It contains public information compiled from around the 'net and many people.
+ .
+ The "update-mime" program was written by Brian White and has been
+ placed in the public domain.
diff --git a/luni/src/main/java/libcore/util/ArrayUtils.java b/luni/src/main/java/libcore/util/ArrayUtils.java
new file mode 100644
index 0000000..2d25bc8
--- /dev/null
+++ b/luni/src/main/java/libcore/util/ArrayUtils.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 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;
+
+public final class ArrayUtils {
+ private ArrayUtils() {}
+
+ /**
+ * Throws {@link ArrayIndexOutOfBoundsException} if the range is out of bounds.
+ * @param len length of the array. Must be non-negative
+ * @param offset start index of the range. Must be non-negative
+ * @param count length of the range. Must be non-negative
+ * @throws ArrayIndexOutOfBoundsException if the range from {@code offset} with length
+ * {@code count} is out of bounds of the array
+ */
+ public static void throwsIfOutOfBounds(int len, int offset, int count) {
+ if (len < 0) {
+ throw new ArrayIndexOutOfBoundsException("Negative length: " + len);
+ }
+
+ if ((offset | count) < 0 || offset > len - count) {
+ throw new ArrayIndexOutOfBoundsException(
+ "length=" + len + "; regionStart=" + offset + "; regionLength=" + count);
+ }
+ }
+}
diff --git a/luni/src/main/java/libcore/util/RecoverySystem.java b/luni/src/main/java/libcore/util/RecoverySystem.java
deleted file mode 100644
index ea9a889..0000000
--- a/luni/src/main/java/libcore/util/RecoverySystem.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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
- */
-
-package libcore.util;
-
-import sun.security.pkcs.PKCS7;
-import sun.security.pkcs.SignerInfo;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.SignatureException;
-import java.security.cert.X509Certificate;
-import java.util.Set;
-
-public class RecoverySystem {
- private RecoverySystem() {
- }
-
- /**
- * Verifies that the signature computed from {@code contentStream} matches
- * that specified in {@code blockStream}. The public key of the certificates specified
- * in the PCKS7 block must match
- */
- public static void verify(InputStream blockStream, InputStream contentStream,
- Set<X509Certificate> trustedCerts)
- throws IOException, SignatureException, NoSuchAlgorithmException {
- PKCS7 block = new PKCS7(blockStream);
-
- // Take the first certificate from the signature (packages
- // should contain only one).
- X509Certificate[] certificates = block.getCertificates();
- if (certificates == null || certificates.length == 0) {
- throw new SignatureException("signature contains no certificates");
- }
- X509Certificate cert = certificates[0];
- PublicKey signatureKey = cert.getPublicKey();
-
- SignerInfo[] signerInfos = block.getSignerInfos();
- if (signerInfos == null || signerInfos.length == 0) {
- throw new SignatureException("signature contains no signedData");
- }
- SignerInfo signerInfo = signerInfos[0];
-
- boolean verified = false;
- for (X509Certificate c : trustedCerts) {
- if (c.getPublicKey().equals(signatureKey)) {
- verified = true;
- break;
- }
- }
-
- if (!verified) {
- throw new SignatureException("signature doesn't match any trusted key");
- }
-
- SignerInfo verifyResult = block.verify(signerInfo, contentStream);
- if (verifyResult == null) {
- throw new SignatureException("signature digest verification failed");
- }
- }
-}
diff --git a/luni/src/main/java/libcore/util/XmlObjectFactory.java b/luni/src/main/java/libcore/util/XmlObjectFactory.java
new file mode 100644
index 0000000..139f3a0
--- /dev/null
+++ b/luni/src/main/java/libcore/util/XmlObjectFactory.java
@@ -0,0 +1,55 @@
+/*
+ * 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 libcore.util;
+
+import com.android.org.kxml2.io.KXmlParser;
+import com.android.org.kxml2.io.KXmlSerializer;
+import org.apache.harmony.xml.ExpatReader;
+import org.xml.sax.XMLReader;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
+
+/**
+ * An internal class for creating platform-default XML parsers and related objects.
+ */
+public class XmlObjectFactory {
+
+ private XmlObjectFactory() {}
+
+ /**
+ * Returns a new instance of the platform default {@link XmlSerializer} more efficiently than
+ * using {@code XmlPullParserFactory.newInstance().newSerializer()}.
+ */
+ public static XmlSerializer newXmlSerializer() {
+ return new KXmlSerializer();
+ }
+
+ /**
+ * Returns a new instance of the platform default {@link XmlPullParser} more efficiently than
+ * using {@code XmlPullParserFactory.newInstance().newPullParser()}.
+ */
+ public static XmlPullParser newXmlPullParser() {
+ return new KXmlParser();
+ }
+
+ /**
+ * Returns the plaform default {@link XMLReader}.
+ */
+ public static XMLReader newXMLReader() {
+ return new ExpatReader();
+ }
+}
diff --git a/luni/src/main/java/libcore/util/ZoneInfo.java b/luni/src/main/java/libcore/util/ZoneInfo.java
index 4236061..66fb518 100644
--- a/luni/src/main/java/libcore/util/ZoneInfo.java
+++ b/luni/src/main/java/libcore/util/ZoneInfo.java
@@ -290,6 +290,8 @@
// Use the latest non-daylight offset (if any) as the raw offset.
if (mTransitions.length == 0) {
+ // This case is no longer expected to occur in the data used on Android after changes
+ // made in zic version 2014c. It is kept as a fallback.
// If there are no transitions then use the first GMT offset.
mRawOffset = gmtOffsets[0];
} else {
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/util/TimezoneGetter.java b/luni/src/main/java/org/apache/harmony/luni/internal/util/TimezoneGetter.java
deleted file mode 100644
index a31ecc0..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/internal/util/TimezoneGetter.java
+++ /dev/null
@@ -1,55 +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 org.apache.harmony.luni.internal.util;
-
-/**
- * This class provides a way to add an implementation specific way to
- * access the current timezone.
- */
-public abstract class TimezoneGetter {
-
- private static TimezoneGetter instance;
-
- /**
- * Retrieves the singleton instance of this class.
- *
- * @return TimezoneGetter the single instance of this class.
- */
- public static TimezoneGetter getInstance() {
- return instance;
- }
-
- /**
- * Sets the singleton instance of this class.
- *
- * @param instance
- * TimezoneGetter the single instance of this class.
- */
- public static void setInstance(TimezoneGetter getter) {
- if (instance != null) {
- throw new UnsupportedOperationException("TimezoneGetter instance already set");
- }
- instance = getter;
- }
-
- /**
- * Retrieves the ID of the current time zone.
- *
- * @return String the ID of the current time zone.
- */
- public abstract String getId();
-}
diff --git a/luni/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java b/luni/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
index 4f54fb5..b6ed988 100644
--- a/luni/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
@@ -16,6 +16,7 @@
package org.apache.harmony.xml.parsers;
+import com.android.org.kxml2.io.KXmlParser;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
@@ -26,7 +27,6 @@
import org.apache.harmony.xml.dom.DocumentImpl;
import org.apache.harmony.xml.dom.DocumentTypeImpl;
import org.apache.harmony.xml.dom.TextImpl;
-import org.kxml2.io.KXmlParser;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
diff --git a/include/ScopedIcuLocale.h b/luni/src/main/native/ScopedIcuLocale.h
similarity index 100%
rename from include/ScopedIcuLocale.h
rename to luni/src/main/native/ScopedIcuLocale.h
diff --git a/include/ScopedJavaUnicodeString.h b/luni/src/main/native/ScopedJavaUnicodeString.h
similarity index 100%
rename from include/ScopedJavaUnicodeString.h
rename to luni/src/main/native/ScopedJavaUnicodeString.h
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index e373a12..60d36f1 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -385,6 +385,7 @@
initConstant(env, c, "MS_SYNC", MS_SYNC);
initConstant(env, c, "NETLINK_NETFILTER", NETLINK_NETFILTER);
initConstant(env, c, "NETLINK_ROUTE", NETLINK_ROUTE);
+ initConstant(env, c, "NETLINK_INET_DIAG", NETLINK_INET_DIAG);
initConstant(env, c, "NI_DGRAM", NI_DGRAM);
initConstant(env, c, "NI_NAMEREQD", NI_NAMEREQD);
initConstant(env, c, "NI_NOFQDN", NI_NOFQDN);
diff --git a/luni/src/main/native/java_util_regex_Matcher.cpp b/luni/src/main/native/java_util_regex_Matcher.cpp
index 11af4bd..47d8b80 100644
--- a/luni/src/main/native/java_util_regex_Matcher.cpp
+++ b/luni/src/main/native/java_util_regex_Matcher.cpp
@@ -161,7 +161,11 @@
// Return a guess of the amount of native memory to be deallocated by a typical call to
// Matcher_free().
static jint Matcher_nativeSize(JNIEnv*, jclass) {
- return 200; // Very rough guess based on a quick look at the implementation.
+ // This value can be tuned. 200 was found to cause performance issues (b/111141123) so 10000
+ // is being used instead. If the value is too small, there's no pressure to collect matchers,
+ // too large and we'll run GC too often.
+ // Also see b/111141123.
+ return 10000;
}
static jint Matcher_findImpl(JNIEnv* env, jclass, jlong addr, jint startIndex, jintArray offsets) {
diff --git a/luni/src/main/native/libcore_io_Linux.cpp b/luni/src/main/native/libcore_io_Linux.cpp
index 30da35c..8a3e1be 100644
--- a/luni/src/main/native/libcore_io_Linux.cpp
+++ b/luni/src/main/native/libcore_io_Linux.cpp
@@ -49,8 +49,13 @@
#include <memory>
+#if defined(__BIONIC__)
+#include <android/fdsan.h>
+#endif
+
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/macros.h>
#include <android-base/strings.h>
#include <log/log.h>
#include <nativehelper/AsynchronousCloseMonitor.h>
@@ -1086,13 +1091,65 @@
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).
+ if (javaFd == nullptr) {
+ jniThrowNullPointerException(env, "null fd");
+ return;
+ }
int fd = jniGetFDFromFileDescriptor(env, javaFd);
jniSetFileDescriptorOfFD(env, javaFd, -1);
+#if defined(__BIONIC__)
+ jlong ownerId = jniGetOwnerIdFromFileDescriptor(env, javaFd);
+
+ // Close with bionic's fd ownership tracking (which returns 0 in the case of EINTR).
+ throwIfMinusOne(env, "close", android_fdsan_close_with_tag(fd, ownerId));
+#else
// Even if close(2) fails with EINTR, the fd will have been closed.
// Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone else's fd.
// http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
throwIfMinusOne(env, "close", close(fd));
+#endif
+}
+
+static void Linux_android_fdsan_exchange_owner_tag(JNIEnv* env, jclass,
+ jobject javaFd,
+ jlong expectedOwnerId,
+ jlong newOwnerId) {
+#if defined(__BIONIC__)
+ int fd = jniGetFDFromFileDescriptor(env, javaFd);
+ android_fdsan_exchange_owner_tag(fd, expectedOwnerId, newOwnerId);
+#else
+ UNUSED(env, javaFd, expectedOwnerId, newOwnerId);
+#endif
+}
+
+static jlong Linux_android_fdsan_get_owner_tag(JNIEnv* env, jclass, jobject javaFd) {
+#if defined(__BIONIC__)
+ int fd = jniGetFDFromFileDescriptor(env, javaFd);
+ return android_fdsan_get_owner_tag(fd);
+#else
+ UNUSED(env, javaFd);
+ return 0;
+#endif
+}
+
+static jstring Linux_android_fdsan_get_tag_type(JNIEnv* env, jclass, jlong tag) {
+#if defined(__BIONIC__)
+ return env->NewStringUTF(android_fdsan_get_tag_type(tag));
+#else
+ UNUSED(tag);
+ return env->NewStringUTF("unknown");
+#endif
+}
+
+static jlong Linux_android_fdsan_get_tag_value(JNIEnv* env, jclass, jlong tag) {
+#if defined(__BIONIC__)
+ UNUSED(env);
+ return android_fdsan_get_tag_value(tag);
+#else
+ UNUSED(env, tag);
+ return 0;
+#endif
}
static void Linux_connect(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) {
@@ -2297,10 +2354,18 @@
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) {
- jniSetFileDescriptorOfFD(env, javaFd1, fds[0]);
- jniSetFileDescriptorOfFD(env, javaFd2, fds[1]);
+ // Fail fast to avoid leaking file descriptors if either FileDescriptor is null.
+ if (javaFd1 == nullptr) {
+ jniThrowNullPointerException(env, "null fd1");
+ } else if (javaFd2 == nullptr) {
+ jniThrowNullPointerException(env, "null fd2");
+ } else {
+ int rc = throwIfMinusOne(env, "socketpair",
+ TEMP_FAILURE_RETRY(socketpair(domain, type, protocol, fds)));
+ if (rc != -1) {
+ jniSetFileDescriptorOfFD(env, javaFd1, fds[0]);
+ jniSetFileDescriptorOfFD(env, javaFd2, fds[1]);
+ }
}
}
@@ -2467,6 +2532,10 @@
static JNINativeMethod gMethods[] = {
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_fdsan_exchange_owner_tag, "(Ljava/io/FileDescriptor;JJ)V"),
+ NATIVE_METHOD(Linux, android_fdsan_get_owner_tag, "(Ljava/io/FileDescriptor;)J"),
+ NATIVE_METHOD(Linux, android_fdsan_get_tag_type, "(J)Ljava/lang/String;"),
+ NATIVE_METHOD(Linux, android_fdsan_get_tag_value, "(J)J"),
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),
diff --git a/luni/src/test/java/libcore/dalvik/system/BlockGuardTest.java b/luni/src/test/java/libcore/dalvik/system/BlockGuardTest.java
index fa99f53..440fd40 100644
--- a/luni/src/test/java/libcore/dalvik/system/BlockGuardTest.java
+++ b/luni/src/test/java/libcore/dalvik/system/BlockGuardTest.java
@@ -117,8 +117,11 @@
try {
recorder.clear();
+ // Opening a file for read triggers:
+ // 1. Read violation from open()
+ // 2. Read violation from EISDIR check
FileInputStream fis = new FileInputStream(tmpFile);
- recorder.expectAndClear("onReadFromDisk");
+ recorder.expectAndClear("onReadFromDisk", "onReadFromDisk");
fis.read(new byte[4], 0, 4);
recorder.expectAndClear("onReadFromDisk");
@@ -139,8 +142,12 @@
File f = File.createTempFile("foo", "bar");
recorder.clear();
+ // Opening a file for write triggers:
+ // 1. Read violation from open()
+ // 2. Write violation from open()
+ // 3. Read violation from EISDIR check
FileOutputStream fos = new FileOutputStream(f);
- recorder.expectAndClear("onWriteToDisk");
+ recorder.expectAndClear("onReadFromDisk", "onWriteToDisk", "onReadFromDisk");
fos.write(new byte[3]);
recorder.expectAndClear("onWriteToDisk");
@@ -155,6 +162,32 @@
recorder.expectNoViolations();
}
+ public void testRandomAccessFile() throws Exception {
+ File f = File.createTempFile("foo", "bar");
+ recorder.clear();
+
+ // Opening a file for write triggers:
+ // 1. Read violation from open()
+ // 2. Write violation from open()
+ // 3. Read violation from EISDIR check
+ RandomAccessFile raf = new RandomAccessFile(f, "rw");
+ recorder.expectAndClear("onReadFromDisk", "onWriteToDisk", "onReadFromDisk");
+
+ raf.seek(0);
+ recorder.expectAndClear("onReadFromDisk");
+
+ raf.length();
+ recorder.expectAndClear("onReadFromDisk");
+
+ raf.read();
+ recorder.expectAndClear("onReadFromDisk");
+
+ raf.write(42);
+ recorder.expectAndClear("onWriteToDisk");
+
+ raf.close();
+ }
+
public void testUnbufferedIO() throws Exception {
File f = File.createTempFile("foo", "bar");
recorder.setChecks(EnumSet.of(RecordingPolicy.Check.UNBUFFERED_IO));
@@ -266,7 +299,13 @@
Os.close(fd);
}
- public static class RecordingPolicy implements BlockGuard.Policy {
+ public void testSystemGc() throws Exception {
+ recorder.clear();
+ Runtime.getRuntime().gc();
+ recorder.expectAndClear("onExplicitGc");
+ }
+
+ private static class RecordingPolicy implements BlockGuard.Policy {
private final List<String> violations = new ArrayList<>();
private Set<Check> checksList;
@@ -275,6 +314,7 @@
READ_FROM_DISK,
NETWORK,
UNBUFFERED_IO,
+ EXPLICIT_GC,
}
public void setChecks(EnumSet<Check> checksList) {
@@ -309,6 +349,13 @@
}
}
+ @Override
+ public void onExplicitGc() {
+ if (checksList != null && checksList.contains(Check.EXPLICIT_GC)) {
+ addViolation("onExplicitGc");
+ }
+ }
+
private void addViolation(String type) {
StackTraceElement[] threadTrace = Thread.currentThread().getStackTrace();
diff --git a/luni/src/test/java/libcore/dalvik/system/PathClassLoaderTest.java b/luni/src/test/java/libcore/dalvik/system/PathClassLoaderTest.java
index 552c732..1320d6c 100644
--- a/luni/src/test/java/libcore/dalvik/system/PathClassLoaderTest.java
+++ b/luni/src/test/java/libcore/dalvik/system/PathClassLoaderTest.java
@@ -150,6 +150,11 @@
}
@Override
+ public void onExplicitGc() {
+ throw new RuntimeException("onExplicitGc");
+ }
+
+ @Override
public int getPolicyMask() {
return 0;
}
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index 3619497..dd8e15b 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -2069,6 +2069,16 @@
}
}
+ public void testSetSSLSocketFactory_null() throws Exception {
+ URL url = new URL("https://google.com");
+ HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+ try {
+ connection.setSSLSocketFactory(null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
public void testSetDefaultSSLSocketFactory_null() {
try {
HttpsURLConnection.setDefaultSSLSocketFactory(null);
diff --git a/luni/src/test/java/libcore/java/net/URLTest.java b/luni/src/test/java/libcore/java/net/URLTest.java
index 1ff9b33..333594c 100644
--- a/luni/src/test/java/libcore/java/net/URLTest.java
+++ b/luni/src/test/java/libcore/java/net/URLTest.java
@@ -913,6 +913,11 @@
}
@Override
+ public void onExplicitGc() {
+ fail("Blockguard.Policy.onExplicitGc");
+ }
+
+ @Override
public int getPolicyMask() {
return 0;
}
diff --git a/luni/src/test/java/libcore/java/nio/BufferTest.java b/luni/src/test/java/libcore/java/nio/BufferTest.java
index 5950690..206f37d 100644
--- a/luni/src/test/java/libcore/java/nio/BufferTest.java
+++ b/luni/src/test/java/libcore/java/nio/BufferTest.java
@@ -60,62 +60,6 @@
return result;
}
- /**
- * Try to create a {@link MappedByteBuffer} from /dev/zero, to see if
- * we support mapping UNIX character devices.
- */
- public void testDevZeroMap() throws Exception {
- RandomAccessFile raf = new RandomAccessFile("/dev/zero", "r");
- try {
- MappedByteBuffer mbb = raf.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, 65536);
-
- // Create an array initialized to all "(byte) 1"
- byte[] buf1 = new byte[65536];
- Arrays.fill(buf1, (byte) 1);
-
- // Read from mapped /dev/zero, and overwrite this array.
- mbb.get(buf1);
-
- // Verify that everything is zero
- for (int i = 0; i < 65536; i++) {
- assertEquals((byte) 0, buf1[i]);
- }
- } finally {
- raf.close();
- }
- }
-
- /**
- * Same as {@link libcore.java.nio.BufferTest#testDevZeroMap()}, but try to see
- * if we can write to the UNIX character device.
- */
- public void testDevZeroMapRW() throws Exception {
- RandomAccessFile raf = new RandomAccessFile("/dev/zero", "rw");
- try {
- MappedByteBuffer mbb = raf.getChannel()
- .map(FileChannel.MapMode.READ_WRITE, 65536, 131072);
-
- // Create an array initialized to all "(byte) 1"
- byte[] buf1 = new byte[65536];
- Arrays.fill(buf1, (byte) 1);
-
- // Put all "(byte) 1"s into the /dev/zero MappedByteBuffer.
- mbb.put(buf1);
-
- mbb.position(0);
-
- byte[] buf2 = new byte[65536];
- mbb.get(buf2);
-
- // Verify that everything is one
- for (int i = 0; i < 65536; i++) {
- assertEquals((byte) 1, buf2[i]);
- }
- } finally {
- raf.close();
- }
- }
-
public void testByteSwappedBulkGetDirect() throws Exception {
testByteSwappedBulkGet(ByteBuffer.allocateDirect(10));
}
diff --git a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
deleted file mode 100644
index ac6148a..0000000
--- a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Copyright (C) 2010 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.java.security;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.PrivateKey;
-import java.security.Provider;
-import java.security.Provider.Service;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.Security;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.DSAPublicKey;
-import java.security.interfaces.ECPrivateKey;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.DSAParameterSpec;
-import java.security.spec.ECGenParameterSpec;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import javax.crypto.interfaces.DHPrivateKey;
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.DHParameterSpec;
-
-import junit.framework.TestCase;
-
-import dalvik.system.VMRuntime;
-import sun.security.jca.Providers;
-
-public class KeyPairGeneratorTest extends TestCase {
-
- private List<Provider> providers = new ArrayList<Provider>();
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
- // Allow access to deprecated BC algorithms in this test, so we can ensure they
- // continue to work
- Providers.setMaximumAllowableApiLevelForBcDeprecation(
- VMRuntime.getRuntime().getTargetSdkVersion());
-
- Provider[] providers = Security.getProviders();
- for (Provider p : providers) {
- // Do not test AndroidKeyStore Provider. It does not accept vanilla public keys for
- // signature verification. It's OKish not to test here because it's tested by
- // cts/tests/tests/keystore.
- if (!p.getName().startsWith("AndroidKeyStore")) {
- this.providers.add(p);
- }
- }
- }
-
- @Override
- public void tearDown() throws Exception {
- providers.clear();
- Providers.setMaximumAllowableApiLevelForBcDeprecation(
- Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
- super.tearDown();
- }
-
- public void test_providerCount() {
- // We expect there to be at least one provider.
- assertTrue(providers.size() > 0);
- // If this fails remember to add _provider methods below. This test is sharded because it
- // takes a long time to execute.
- assertTrue(providers.size() < 10);
- }
-
- public void test_getInstance_provider0() throws Exception {
- test_getInstance(0);
- }
-
- public void test_getInstance_provider1() throws Exception {
- test_getInstance(1);
- }
-
- public void test_getInstance_provider2() throws Exception {
- test_getInstance(2);
- }
-
- public void test_getInstance_provider3() throws Exception {
- test_getInstance(3);
- }
-
- public void test_getInstance_provider4() throws Exception {
- test_getInstance(4);
- }
-
- public void test_getInstance_provider5() throws Exception {
- test_getInstance(5);
- }
-
- public void test_getInstance_provider6() throws Exception {
- test_getInstance(6);
- }
-
- public void test_getInstance_provider7() throws Exception {
- test_getInstance(7);
- }
-
- public void test_getInstance_provider8() throws Exception {
- test_getInstance(8);
- }
-
- public void test_getInstance_provider9() throws Exception {
- test_getInstance(9);
- }
-
- private void test_getInstance(int providerIndex) throws Exception {
- if (providerIndex >= providers.size()) {
- // Providers can be added by vendors and other tests. We do not
- // specify a fixed number and silenty pass if the provider at the
- // specified index does not exist.
- return;
- }
-
- Provider provider = providers.get(providerIndex);
- Set<Provider.Service> services = provider.getServices();
- for (Provider.Service service : services) {
- String type = service.getType();
- if (!type.equals("KeyPairGenerator")) {
- continue;
- }
- String algorithm = service.getAlgorithm();
- AlgorithmParameterSpec params = null;
-
- if ("DH".equals(algorithm)) {
- params = getDHParams();
- }
-
- try {
- // KeyPairGenerator.getInstance(String)
- KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(algorithm);
- assertEquals(algorithm, kpg1.getAlgorithm());
- if (params != null) {
- kpg1.initialize(params);
- }
- test_KeyPairGenerator(kpg1);
-
- // KeyPairGenerator.getInstance(String, Provider)
- KeyPairGenerator kpg2 = KeyPairGenerator.getInstance(algorithm, provider);
- assertEquals(algorithm, kpg2.getAlgorithm());
- assertEquals(provider, kpg2.getProvider());
- if (params != null) {
- kpg2.initialize(params);
- }
- test_KeyPairGenerator(kpg2);
-
- // KeyPairGenerator.getInstance(String, String)
- KeyPairGenerator kpg3 = KeyPairGenerator.getInstance(algorithm,
- provider.getName());
- assertEquals(algorithm, kpg3.getAlgorithm());
- assertEquals(provider, kpg3.getProvider());
- if (params != null) {
- kpg3.initialize(params);
- }
- test_KeyPairGenerator(kpg3);
- } catch (Exception e) {
- throw new Exception("Problem testing KeyPairGenerator." + algorithm, e);
- }
- }
- }
-
- private static final Map<String, List<Integer>> KEY_SIZES
- = new HashMap<String, List<Integer>>();
- private static void putKeySize(String algorithm, int keySize) {
- algorithm = algorithm.toUpperCase();
- List<Integer> keySizes = KEY_SIZES.get(algorithm);
- if (keySizes == null) {
- keySizes = new ArrayList<Integer>();
- KEY_SIZES.put(algorithm, keySizes);
- }
- keySizes.add(keySize);
- }
- private static List<Integer> getKeySizes(String algorithm) throws Exception {
- algorithm = algorithm.toUpperCase();
- List<Integer> keySizes = KEY_SIZES.get(algorithm);
- if (keySizes == null) {
- throw new Exception("Unknown key sizes for KeyPairGenerator." + algorithm);
- }
- return keySizes;
- }
- static {
- putKeySize("DSA", 512);
- putKeySize("DSA", 512+64);
- putKeySize("DSA", 1024);
- putKeySize("RSA", 512);
- putKeySize("DH", 512);
- putKeySize("DH", 512+64);
- putKeySize("DH", 1024);
- putKeySize("DiffieHellman", 512);
- putKeySize("DiffieHellman", 512+64);
- putKeySize("DiffieHellman", 1024);
- putKeySize("EC", 224);
- putKeySize("EC", 256);
- putKeySize("EC", 384);
- putKeySize("EC", 521);
- }
-
- /** Elliptic Curve Crypto named curves that should be supported. */
- private static final String[] EC_NAMED_CURVES = {
- // NIST P-256 aka SECG secp256r1 aka ANSI X9.62 prime256v1
- "secp256r1", "prime256v1",
- // NIST P-521 aka SECG secp521r1
- "secp521r1",
- };
-
- private void test_KeyPairGenerator(KeyPairGenerator kpg) throws Exception {
- // without a call to initialize
- test_KeyPair(kpg, kpg.genKeyPair());
- test_KeyPair(kpg, kpg.generateKeyPair());
-
- String algorithm = kpg.getAlgorithm();
-
- // TODO: detect if we're running in vogar and run the full test
- if ("DH".equals(algorithm)) {
- // Disabled because this takes too long on devices.
- // TODO: Re-enable DH test. http://b/5513723.
- return;
- }
-
- List<Integer> keySizes = getKeySizes(algorithm);
- for (int keySize : keySizes) {
- kpg.initialize(keySize);
- test_KeyPair(kpg, kpg.genKeyPair());
- test_KeyPair(kpg, kpg.generateKeyPair());
-
- kpg.initialize(keySize, (SecureRandom) null);
- test_KeyPair(kpg, kpg.genKeyPair());
- test_KeyPair(kpg, kpg.generateKeyPair());
-
- kpg.initialize(keySize, new SecureRandom());
- test_KeyPair(kpg, kpg.genKeyPair());
- test_KeyPair(kpg, kpg.generateKeyPair());
- }
-
- if (("EC".equals(algorithm)) || ("ECDH".equals(algorithm))
- || ("ECDSA".equals(algorithm))) {
- for (String curveName : EC_NAMED_CURVES) {
- kpg.initialize(new ECGenParameterSpec(curveName));
- test_KeyPair(kpg, kpg.genKeyPair());
- test_KeyPair(kpg, kpg.generateKeyPair());
-
- kpg.initialize(new ECGenParameterSpec(curveName), (SecureRandom) null);
- test_KeyPair(kpg, kpg.genKeyPair());
- test_KeyPair(kpg, kpg.generateKeyPair());
-
- kpg.initialize(new ECGenParameterSpec(curveName), new SecureRandom());
- test_KeyPair(kpg, kpg.genKeyPair());
- test_KeyPair(kpg, kpg.generateKeyPair());
- }
- }
- }
-
- private void test_KeyPair(KeyPairGenerator kpg, KeyPair kp) throws Exception {
- assertNotNull(kp);
- test_Key(kpg, kp.getPrivate());
- test_Key(kpg, kp.getPublic());
- }
-
- private void test_Key(KeyPairGenerator kpg, Key k) throws Exception {
- String expectedAlgorithm = kpg.getAlgorithm().toUpperCase(Locale.ROOT);
- if (StandardNames.IS_RI && expectedAlgorithm.equals("DIFFIEHELLMAN")) {
- expectedAlgorithm = "DH";
- }
- assertEquals(expectedAlgorithm, k.getAlgorithm().toUpperCase());
- if (expectedAlgorithm.equals("DH")) {
- if (k instanceof DHPublicKey) {
- DHPublicKey dhPub = (DHPublicKey) k;
- assertEquals(dhPub.getParams().getP(), getDHParams().getP());
- } else if (k instanceof DHPrivateKey) {
- DHPrivateKey dhPriv = (DHPrivateKey) k;
- assertEquals(dhPriv.getParams().getP(), getDHParams().getP());
- } else {
- fail("not a public or private key!?");
- }
- }
- assertNotNull(k.getEncoded());
- assertNotNull(k.getFormat());
-
- // Test serialization
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream(16384);
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(k);
-
- ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
- ObjectInputStream ois = new ObjectInputStream(bais);
- Key inflatedKey = (Key) ois.readObject();
-
- assertEquals(k, inflatedKey);
- }
-
- test_KeyWithAllKeyFactories(k);
- }
-
- private void test_KeyWithAllKeyFactories(Key k) throws Exception {
- byte[] encoded = k.getEncoded();
-
- String keyAlgo = k.getAlgorithm();
- for (Provider p : providers) {
- Set<Provider.Service> services = p.getServices();
- for (Provider.Service service : services) {
- if (!"KeyFactory".equals(service.getType())) {
- continue;
- }
- if (!service.getAlgorithm().equals(keyAlgo)) {
- continue;
- }
-
- if ("PKCS#8".equals(k.getFormat())) {
- PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(encoded);
- KeyFactory kf = KeyFactory.getInstance(k.getAlgorithm(), p);
- PrivateKey privKey = kf.generatePrivate(spec);
- assertNotNull(k.getAlgorithm() + ", provider=" + p.getName(), privKey);
-
- /*
- * EC keys are unique because they can have explicit parameters or a curve
- * name. Check them specially so this test can continue to function.
- */
- if (k instanceof ECPrivateKey) {
- assertECPrivateKeyEquals((ECPrivateKey) k, (ECPrivateKey) privKey);
- } else {
- assertEquals(k.getAlgorithm() + ", provider=" + p.getName(),
- Arrays.toString(encoded),
- Arrays.toString(privKey.getEncoded()));
- }
- } else if ("X.509".equals(k.getFormat())) {
- X509EncodedKeySpec spec = new X509EncodedKeySpec(encoded);
- KeyFactory kf = KeyFactory.getInstance(k.getAlgorithm(), p);
- PublicKey pubKey = kf.generatePublic(spec);
- assertNotNull(pubKey);
- assertTrue(Arrays.equals(encoded, pubKey.getEncoded()));
- }
- }
- }
- }
-
- private static void assertECPrivateKeyEquals(ECPrivateKey expected, ECPrivateKey actual) {
- assertEquals(expected.getS(), actual.getS());
- assertECParametersEquals(expected.getParams(), actual.getParams());
- }
-
- private static void assertECParametersEquals(ECParameterSpec expected, ECParameterSpec actual) {
- assertEquals(expected.getCurve(), actual.getCurve());
- assertEquals(expected.getGenerator(), actual.getGenerator());
- assertEquals(expected.getOrder(), actual.getOrder());
- assertEquals(expected.getCofactor(), actual.getCofactor());
- }
-
- /**
- * DH parameters pre-generated so that the test doesn't take too long.
- * These parameters were generated with:
- *
- * openssl gendh 512 | openssl dhparams -C
- */
- private static DHParameterSpec getDHParams() {
- BigInteger p = new BigInteger("E7AB1768BD75CD24700960FFA32D3F1557344E587101237532CC641646ED7A7C104743377F6D46251698B665CE2A6CBAB6714C2569A7D2CA22C0CF03FA40AC93", 16);
- BigInteger g = new BigInteger("02", 16);
- return new DHParameterSpec(p, g, 512);
- }
-
- private static final BigInteger DSA_P = new BigInteger(new byte[] {
- (byte) 0x00, (byte) 0x9e, (byte) 0x61, (byte) 0xc2, (byte) 0x89, (byte) 0xef, (byte) 0x77, (byte) 0xa9,
- (byte) 0x4e, (byte) 0x13, (byte) 0x67, (byte) 0x64, (byte) 0x1f, (byte) 0x09, (byte) 0x01, (byte) 0xfe,
- (byte) 0x24, (byte) 0x13, (byte) 0x53, (byte) 0xe0, (byte) 0xb7, (byte) 0x90, (byte) 0xa8, (byte) 0x4e,
- (byte) 0x76, (byte) 0xfe, (byte) 0x89, (byte) 0x82, (byte) 0x7f, (byte) 0x7a, (byte) 0xc5, (byte) 0x3c,
- (byte) 0x4e, (byte) 0x0c, (byte) 0x20, (byte) 0x55, (byte) 0x30, (byte) 0x95, (byte) 0x42, (byte) 0x85,
- (byte) 0xe1, (byte) 0x40, (byte) 0x7d, (byte) 0x27, (byte) 0x8f, (byte) 0x07, (byte) 0x0d, (byte) 0xe8,
- (byte) 0xdc, (byte) 0x99, (byte) 0xef, (byte) 0xb3, (byte) 0x07, (byte) 0x94, (byte) 0x34, (byte) 0xd6,
- (byte) 0x7c, (byte) 0xff, (byte) 0x9c, (byte) 0xbe, (byte) 0x69, (byte) 0xd3, (byte) 0xeb, (byte) 0x44,
- (byte) 0x37, (byte) 0x50, (byte) 0xef, (byte) 0x49, (byte) 0xf8, (byte) 0xe2, (byte) 0x5b, (byte) 0xd8,
- (byte) 0xd1, (byte) 0x10, (byte) 0x84, (byte) 0x97, (byte) 0xea, (byte) 0xe3, (byte) 0xa5, (byte) 0x1c,
- (byte) 0xc0, (byte) 0x4e, (byte) 0x69, (byte) 0xca, (byte) 0x70, (byte) 0x3d, (byte) 0x78, (byte) 0xb9,
- (byte) 0x16, (byte) 0xe5, (byte) 0xfe, (byte) 0x61, (byte) 0x5d, (byte) 0x8a, (byte) 0x5a, (byte) 0xb3,
- (byte) 0x2c, (byte) 0x61, (byte) 0xb6, (byte) 0x01, (byte) 0x3b, (byte) 0xd0, (byte) 0x01, (byte) 0x7c,
- (byte) 0x32, (byte) 0x8d, (byte) 0xe1, (byte) 0xf3, (byte) 0x69, (byte) 0x0e, (byte) 0x8b, (byte) 0x58,
- (byte) 0xc6, (byte) 0xcf, (byte) 0x00, (byte) 0x94, (byte) 0xf8, (byte) 0x49, (byte) 0x2a, (byte) 0x4b,
- (byte) 0xea, (byte) 0xda, (byte) 0x00, (byte) 0xff, (byte) 0x4b, (byte) 0xd0, (byte) 0xbe, (byte) 0x40,
- (byte) 0x23,
- });
-
- private static final BigInteger DSA_Q = new BigInteger(new byte[] {
- (byte) 0x00, (byte) 0xbf, (byte) 0xee, (byte) 0xaa, (byte) 0x0f, (byte) 0x12, (byte) 0x34, (byte) 0x50,
- (byte) 0x72, (byte) 0xf8, (byte) 0x60, (byte) 0x13, (byte) 0xd8, (byte) 0xf1, (byte) 0x41, (byte) 0x01,
- (byte) 0x10, (byte) 0xa5, (byte) 0x2f, (byte) 0x57, (byte) 0x5f,
- });
-
- private static final BigInteger DSA_G = new BigInteger(new byte[] {
- (byte) 0x77, (byte) 0xd4, (byte) 0x7a, (byte) 0x12, (byte) 0xcc, (byte) 0x81, (byte) 0x7e, (byte) 0x7e,
- (byte) 0xeb, (byte) 0x3a, (byte) 0xfb, (byte) 0xe6, (byte) 0x86, (byte) 0x6d, (byte) 0x5a, (byte) 0x10,
- (byte) 0x1d, (byte) 0xad, (byte) 0xa9, (byte) 0x4f, (byte) 0xb9, (byte) 0x03, (byte) 0x5d, (byte) 0x21,
- (byte) 0x1a, (byte) 0xe4, (byte) 0x30, (byte) 0x95, (byte) 0x75, (byte) 0x8e, (byte) 0xcd, (byte) 0x5e,
- (byte) 0xd1, (byte) 0xbd, (byte) 0x0a, (byte) 0x45, (byte) 0xee, (byte) 0xe7, (byte) 0xf7, (byte) 0x6b,
- (byte) 0x65, (byte) 0x02, (byte) 0x60, (byte) 0xd0, (byte) 0x2e, (byte) 0xaf, (byte) 0x3d, (byte) 0xbc,
- (byte) 0x07, (byte) 0xdd, (byte) 0x2b, (byte) 0x8e, (byte) 0x33, (byte) 0xc0, (byte) 0x93, (byte) 0x80,
- (byte) 0xd9, (byte) 0x2b, (byte) 0xa7, (byte) 0x71, (byte) 0x57, (byte) 0x76, (byte) 0xbc, (byte) 0x8e,
- (byte) 0xb9, (byte) 0xe0, (byte) 0xd7, (byte) 0xf4, (byte) 0x23, (byte) 0x8d, (byte) 0x41, (byte) 0x1a,
- (byte) 0x97, (byte) 0x4f, (byte) 0x2c, (byte) 0x1b, (byte) 0xd5, (byte) 0x4b, (byte) 0x66, (byte) 0xe8,
- (byte) 0xfa, (byte) 0xd2, (byte) 0x50, (byte) 0x0d, (byte) 0x17, (byte) 0xab, (byte) 0x34, (byte) 0x31,
- (byte) 0x3d, (byte) 0xa4, (byte) 0x88, (byte) 0xd8, (byte) 0x8e, (byte) 0xa8, (byte) 0xa7, (byte) 0x6e,
- (byte) 0x17, (byte) 0x03, (byte) 0xb7, (byte) 0x0f, (byte) 0x68, (byte) 0x7c, (byte) 0x64, (byte) 0x7b,
- (byte) 0x92, (byte) 0xb8, (byte) 0x63, (byte) 0xe4, (byte) 0x9a, (byte) 0x67, (byte) 0x18, (byte) 0x81,
- (byte) 0x27, (byte) 0xd4, (byte) 0x0b, (byte) 0x13, (byte) 0x48, (byte) 0xd3, (byte) 0x7d, (byte) 0x4e,
- (byte) 0xf6, (byte) 0xa8, (byte) 0x8f, (byte) 0x56, (byte) 0x17, (byte) 0x2d, (byte) 0x08, (byte) 0x51,
- });
-
- public void testDSAGeneratorWithParams() throws Exception {
- final DSAParameterSpec dsaSpec = new DSAParameterSpec(DSA_P, DSA_Q, DSA_G);
-
- final Provider[] providers = Security.getProviders();
- for (final Provider p : providers) {
- Service s = p.getService("KeyPairGenerator", "DSA");
- if (s == null) {
- continue;
- }
-
- final KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", p);
- kpg.initialize(dsaSpec);
- KeyPair pair = kpg.generateKeyPair();
- DSAPrivateKey privKey = (DSAPrivateKey) pair.getPrivate();
- DSAPublicKey pubKey = (DSAPublicKey) pair.getPublic();
-
- DSAParams actualParams = privKey.getParams();
- assertNotNull("DSA params should not be null", actualParams);
-
- assertEquals("DSA P should be the same as supplied with provider " + p.getName(),
- DSA_P, actualParams.getP());
- assertEquals("DSA Q should be the same as supplied with provider " + p.getName(),
- DSA_Q, actualParams.getQ());
- assertEquals("DSA G should be the same as supplied with provider " + p.getName(),
- DSA_G, actualParams.getG());
-
- actualParams = pubKey.getParams();
- assertNotNull("DSA params should not be null", actualParams);
-
- assertEquals("DSA P should be the same as supplied with provider " + p.getName(),
- DSA_P, actualParams.getP());
- assertEquals("DSA Q should be the same as supplied with provider " + p.getName(),
- DSA_Q, actualParams.getQ());
- assertEquals("DSA G should be the same as supplied with provider " + p.getName(),
- DSA_G, actualParams.getG());
- }
- }
-}
diff --git a/luni/src/test/java/libcore/java/security/MessageDigestTest.java b/luni/src/test/java/libcore/java/security/MessageDigestTest.java
index d08920b..e896459 100644
--- a/luni/src/test/java/libcore/java/security/MessageDigestTest.java
+++ b/luni/src/test/java/libcore/java/security/MessageDigestTest.java
@@ -19,16 +19,9 @@
import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.security.MessageDigestSpi;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
@@ -36,238 +29,8 @@
import java.util.concurrent.TimeUnit;
import junit.framework.TestCase;
-import dalvik.system.VMRuntime;
-import sun.security.jca.Providers;
-
public final class MessageDigestTest extends TestCase {
- // Allow access to deprecated BC algorithms in this test, so we can ensure they
- // continue to work
- @Override
- public void setUp() throws Exception {
- super.setUp();
- Providers.setMaximumAllowableApiLevelForBcDeprecation(
- VMRuntime.getRuntime().getTargetSdkVersion());
- }
-
- @Override
- public void tearDown() throws Exception {
- Providers.setMaximumAllowableApiLevelForBcDeprecation(
- Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
- super.tearDown();
- }
-
- private final byte[] sha_456 = {
- -24, 9, -59, -47, -50, -92, 123, 69, -29, 71,
- 1, -46, 63, 96, -118, -102, 88, 3, 77, -55
- };
-
- public void testShaReset() throws NoSuchAlgorithmException {
- MessageDigest sha = MessageDigest.getInstance("SHA");
- sha.update(new byte[] { 1, 2, 3 });
- sha.reset();
- sha.update(new byte[] { 4, 5, 6 });
- assertEquals(Arrays.toString(sha_456), Arrays.toString(sha.digest()));
- }
-
- public void test_getInstance() throws Exception {
- Provider[] providers = Security.getProviders();
- for (Provider provider : providers) {
- Set<Provider.Service> services = provider.getServices();
- for (Provider.Service service : services) {
- String type = service.getType();
- if (!type.equals("MessageDigest")) {
- continue;
- }
- String algorithm = service.getAlgorithm();
- try {
- // MessageDigest.getInstance(String)
- MessageDigest md1 = MessageDigest.getInstance(algorithm);
- assertEquals(algorithm, md1.getAlgorithm());
- test_MessageDigest(md1);
-
- // MessageDigest.getInstance(String, Provider)
- MessageDigest md2 = MessageDigest.getInstance(algorithm, provider);
- assertEquals(algorithm, md2.getAlgorithm());
- assertEquals(provider, md2.getProvider());
- test_MessageDigest(md2);
-
- // MessageDigest.getInstance(String, String)
- MessageDigest md3 = MessageDigest.getInstance(algorithm, provider.getName());
- assertEquals(algorithm, md3.getAlgorithm());
- assertEquals(provider, md3.getProvider());
- test_MessageDigest(md3);
- } catch (Exception e) {
- throw new Exception("Problem testing MessageDigest." + algorithm, e);
- }
- }
- }
- }
-
- private static final Map<String, Map<String, byte[]>> EXPECTATIONS
- = new HashMap<String, Map<String, byte[]>>();
- private static void putExpectation(String algorithm, String inputName, byte[] expected) {
- algorithm = algorithm.toUpperCase();
- Map<String, byte[]> expectations = EXPECTATIONS.get(algorithm);
- if (expectations == null) {
- expectations = new HashMap<String, byte[]>();
- EXPECTATIONS.put(algorithm, expectations);
- }
- expectations.put(inputName, expected);
- }
- private static Map<String, byte[]> getExpectations(String algorithm) throws Exception {
- algorithm = algorithm.toUpperCase();
- Map<String, byte[]> expectations = EXPECTATIONS.get(algorithm);
- if (expectations == null) {
- throw new Exception("No expectations for MessageDigest." + algorithm);
- }
- return expectations;
- }
- private static final String INPUT_EMPTY = "empty";
- private static final String INPUT_256MB = "256mb";
- static {
- // INPUT_EMPTY
- putExpectation("MD2",
- INPUT_EMPTY,
- new byte[] { -125, 80, -27, -93, -30, 76, 21, 61,
- -14, 39, 92, -97, -128, 105, 39, 115 });
- putExpectation("MD5",
- INPUT_EMPTY,
- new byte[] { -44, 29, -116, -39, -113, 0, -78, 4,
- -23, -128, 9, -104, -20, -8, 66, 126 });
- putExpectation("SHA",
- INPUT_EMPTY,
- new byte[] { -38, 57, -93, -18, 94, 107, 75, 13,
- 50, 85, -65, -17, -107, 96, 24, -112,
- -81, -40, 7, 9});
- putExpectation("SHA-1",
- INPUT_EMPTY,
- new byte[] { -38, 57, -93, -18, 94, 107, 75, 13,
- 50, 85, -65, -17, -107, 96, 24, -112,
- -81, -40, 7, 9});
- putExpectation("SHA-224",
- INPUT_EMPTY,
- new byte[] { -47, 74, 2, -116, 42, 58, 43, -55, 71,
- 97, 2, -69, 40, -126, 52, -60, 21,
- -94, -80, 31, -126, -114, -90, 42,
- -59, -77, -28, 47});
- putExpectation("SHA-256",
- INPUT_EMPTY,
- new byte[] { -29, -80, -60, 66, -104, -4, 28, 20,
- -102, -5, -12, -56, -103, 111, -71, 36,
- 39, -82, 65, -28, 100, -101, -109, 76,
- -92, -107, -103, 27, 120, 82, -72, 85 });
- putExpectation("SHA-384",
- INPUT_EMPTY,
- new byte[] { 56, -80, 96, -89, 81, -84, -106, 56,
- 76, -39, 50, 126, -79, -79, -29, 106,
- 33, -3, -73, 17, 20, -66, 7, 67,
- 76, 12, -57, -65, 99, -10, -31, -38,
- 39, 78, -34, -65, -25, 111, 101, -5,
- -43, 26, -46, -15, 72, -104, -71, 91 });
- putExpectation("SHA-512",
- INPUT_EMPTY,
- new byte[] { -49, -125, -31, 53, 126, -17, -72, -67,
- -15, 84, 40, 80, -42, 109, -128, 7,
- -42, 32, -28, 5, 11, 87, 21, -36,
- -125, -12, -87, 33, -45, 108, -23, -50,
- 71, -48, -47, 60, 93, -123, -14, -80,
- -1, -125, 24, -46, -121, 126, -20, 47,
- 99, -71, 49, -67, 71, 65, 122, -127,
- -91, 56, 50, 122, -7, 39, -38, 62 });
-
- // Regression test for a SHA-1 problem with inputs larger than 256 MiB. http://b/4501620
- // In mid-2013 this takes 3 minutes even on the host, so let's not run it on devices.
- if (System.getenv("ANDROID_BUILD_TOP") != null) {
- // INPUT_256MB
- putExpectation("MD2",
- INPUT_256MB,
- new byte[] { -63, -120, 6, 67, 12, -87, -39, -11,
- -67, -3, -31, -41, -91, 16, -35, 91 });
- putExpectation("MD5",
- INPUT_256MB,
- new byte[] { 31, 80, 57, -27, 11, -42, 107, 41,
- 12, 86, 104, 77, -123, 80, -58, -62 });
- putExpectation("SHA",
- INPUT_256MB,
- new byte[] { 123, -111, -37, -36, 86, -59, 120, 30,
- -33, 108, -120, 71, -76, -86, 105, 101,
- 86, 108, 92, 117 });
- putExpectation("SHA-1",
- INPUT_256MB,
- new byte[] { 123, -111, -37, -36, 86, -59, 120, 30,
- -33, 108, -120, 71, -76, -86, 105, 101,
- 86, 108, 92, 117 });
- putExpectation("SHA-224",
- INPUT_256MB,
- new byte[] { -78, 82, 5, -71, 57, 119, 77, -32,
- -62, -74, -40, 64, -57, 79, 40, 116,
- -18, 48, -69, 45, 18, -94, 111, 114,
- -45, -93, 43, -11 });
- putExpectation("SHA-256",
- INPUT_256MB,
- new byte[] { -90, -41, 42, -57, 105, 15, 83, -66,
- 106, -28, 107, -88, -123, 6, -67, -105,
- 48, 42, 9, 63, 113, 8, 71, 43,
- -39, -17, -61, -50, -3, -96, 100, -124 });
- putExpectation("SHA-384",
- INPUT_256MB,
- new byte[] { 71, 72, 77, -83, -110, 22, -118, -18,
- -58, 119, 115, 74, -67, -36, 84, 122,
- -105, -67, -75, 15, -33, 37, 78, -95,
- 4, 118, -53, 106, 65, -115, -19, 121,
- -59, -94, -45, -111, -124, 35, 35, 60,
- 67, -34, 62, 106, -16, 122, -110, -14 });
- putExpectation("SHA-512",
- INPUT_256MB,
- new byte[] { 36, 7, -120, 39, -87, -87, 84, -40,
- -66, 114, 62, -73, 107, 101, -117, -12,
- -124, 20, 109, 103, -92, 125, 111, 102,
- 12, 114, -68, 100, 30, 25, -88, 62,
- 108, 56, 9, -107, 89, -25, -50, 118,
- -87, 100, 13, 37, -14, 66, -40, -97,
- 105, -27, 79, -62, 53, -31, 83, 40,
- 4, 57, 90, -81, 63, -77, -42, 113 });
- }
- }
-
- private void test_MessageDigest(MessageDigest md) throws Exception {
- String algorithm = md.getAlgorithm();
- for (Map.Entry<String, byte[]> expectation : getExpectations(algorithm).entrySet()) {
- String inputName = expectation.getKey();
- byte[] expected = expectation.getValue();
- byte[] actual;
- if (inputName.equals(INPUT_EMPTY)) {
- actual = md.digest();
- } else if (inputName.equals(INPUT_256MB)) {
- byte[] mb = new byte[1 * 1024 * 1024];
- for (int i = 0; i < 256; i++) {
- md.update(mb);
- }
- actual = md.digest();
- } else {
- throw new AssertionError(inputName);
- }
- assertDigest(algorithm, expected, actual);
- assertEquals(algorithm, expected.length, md.getDigestLength());
- }
- }
-
- private void assertDigest(String algorithm, byte[] actual, byte[] expected) {
- assertEquals(algorithm, javaBytes(actual), javaBytes(expected));
- }
-
- private String javaBytes(byte[] bytes) {
- StringBuffer buf = new StringBuffer();
- buf.append("new byte[] { ");
- for (byte b : bytes) {
- buf.append(b);
- buf.append(", ");
- }
- buf.append(" }");
- return buf.toString();
- }
-
private final int THREAD_COUNT = 10;
public void testMessageDigest_MultipleThreads_Misuse() throws Exception {
diff --git a/luni/src/test/java/libcore/java/security/README b/luni/src/test/java/libcore/java/security/README
new file mode 100644
index 0000000..f89b27d
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/README
@@ -0,0 +1,2 @@
+Most tests for java.security can be found in external/conscrypt. They
+should be updated at http://github.com/google/conscrypt.
diff --git a/luni/src/test/java/libcore/java/security/SignatureTest.java b/luni/src/test/java/libcore/java/security/SignatureTest.java
index 28e735c..3750742 100644
--- a/luni/src/test/java/libcore/java/security/SignatureTest.java
+++ b/luni/src/test/java/libcore/java/security/SignatureTest.java
@@ -16,21 +16,16 @@
package libcore.java.security;
-import static java.nio.charset.StandardCharsets.UTF_8;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import java.lang.reflect.Method;
-import java.math.BigInteger;
import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
@@ -38,36 +33,11 @@
import java.security.Signature;
import java.security.SignatureException;
import java.security.SignatureSpi;
-import java.security.spec.DSAPrivateKeySpec;
-import java.security.spec.DSAPublicKeySpec;
-import java.security.spec.ECFieldFp;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.ECPublicKeySpec;
-import java.security.spec.EllipticCurve;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.InvalidParameterSpecException;
-import java.security.spec.MGF1ParameterSpec;
-import java.security.spec.PSSParameterSpec;
-import java.security.spec.RSAPrivateCrtKeySpec;
-import java.security.spec.RSAPrivateKeySpec;
-import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
import junit.framework.TestCase;
-
import libcore.util.HexEncoding;
import dalvik.system.VMRuntime;
@@ -342,6 +312,13 @@
}
}
+ private static final byte[] PK_BYTES = HexEncoding.decode(
+ "30819f300d06092a864886f70d010101050003818d0030818902818100cd769d178f61475fce3001"
+ + "2604218320c77a427121d3b41dd76756c8fc0c428cd15cb754adc85466f47547b1c85623d9c17fc6"
+ + "4f202fca21099caf99460c824ad657caa8c2db34996838d32623c4f23c8b6a4e6698603901262619"
+ + "4840e0896b1a6ec4f6652484aad04569bb6a885b822a10d700224359c632dc7324520cbb3d020301"
+ + "0001");
+
private static PublicKey createPublicKey() throws Exception {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(PK_BYTES);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
@@ -470,2835 +447,6 @@
}
}
- // 20 bytes for DSA
- private final byte[] DATA = new byte[20];
-
- public void test_getInstance() throws Exception {
- Provider[] providers = Security.getProviders();
- for (Provider provider : providers) {
- // Do not test AndroidKeyStore's Signature. It needs an AndroidKeyStore-specific key.
- // It's OKish not to test AndroidKeyStore's Signature here because it's tested
- // by cts/tests/test/keystore.
- if (provider.getName().startsWith("AndroidKeyStore")) {
- continue;
- }
- Set<Provider.Service> services = provider.getServices();
- for (Provider.Service service : services) {
- String type = service.getType();
- if (!type.equals("Signature")) {
- continue;
- }
- String algorithm = service.getAlgorithm();
- try {
- KeyPair kp = keyPair(algorithm, provider.getName());
- // Signature.getInstance(String)
- Signature sig1 = Signature.getInstance(algorithm);
- assertEquals(algorithm, sig1.getAlgorithm());
- test_Signature(sig1, kp);
-
- // Signature.getInstance(String, Provider)
- Signature sig2 = Signature.getInstance(algorithm, provider);
- assertEquals(algorithm, sig2.getAlgorithm());
- assertEquals(provider, sig2.getProvider());
- test_Signature(sig2, kp);
-
- // Signature.getInstance(String, String)
- Signature sig3 = Signature.getInstance(algorithm, provider.getName());
- assertEquals(algorithm, sig3.getAlgorithm());
- assertEquals(provider, sig3.getProvider());
- test_Signature(sig3, kp);
- } catch (Exception e) {
- throw new Exception("Problem testing Signature." + algorithm, e);
- }
- }
- }
- }
-
- private final Map<String, KeyPair> keypairAlgorithmToInstance
- = new HashMap<String, KeyPair>();
-
- private KeyPair keyPair(String sigAlgorithm, String providerName) throws Exception {
- String sigAlgorithmUpperCase = sigAlgorithm.toUpperCase(Locale.US);
- if (sigAlgorithmUpperCase.endsWith("ENCRYPTION")) {
- sigAlgorithm = sigAlgorithm.substring(0, sigAlgorithm.length()-"ENCRYPTION".length());
- sigAlgorithmUpperCase = sigAlgorithm.toUpperCase(Locale.US);
- }
-
- String kpAlgorithm;
- // note ECDSA must be before DSA
- if (sigAlgorithmUpperCase.endsWith("ECDSA")) {
- kpAlgorithm = "EC";
- } else if (sigAlgorithmUpperCase.endsWith("DSA")) {
- kpAlgorithm = "DSA";
- } else if ((sigAlgorithmUpperCase.endsWith("RSA"))
- || (sigAlgorithmUpperCase.endsWith("RSA/PSS"))) {
- kpAlgorithm = "RSA";
- } else {
- throw new Exception("Unknown KeyPair algorithm for Signature algorithm "
- + sigAlgorithm);
- }
-
- KeyPair kp = keypairAlgorithmToInstance.get(kpAlgorithm);
- if (kp == null) {
- kp = KeyPairGenerator.getInstance(kpAlgorithm).generateKeyPair();
- keypairAlgorithmToInstance.put(kpAlgorithm, kp);
- }
- return kp;
- }
-
- private void test_Signature(Signature sig, KeyPair keyPair) throws Exception {
- sig.initSign(keyPair.getPrivate());
- sig.update(DATA);
- byte[] signature = sig.sign();
- assertNotNull(sig.getAlgorithm(), signature);
- assertTrue(sig.getAlgorithm(), signature.length > 0);
-
- sig.initVerify(keyPair.getPublic());
- sig.update(DATA);
- assertTrue(sig.getAlgorithm(), sig.verify(signature));
-
- // After verify, should be reusable as if we are after initVerify
- sig.update(DATA);
- assertTrue(sig.getAlgorithm(), sig.verify(signature));
-
- /*
- * The RI appears to clear out the input data in RawDSA while calling
- * verify a second time.
- */
- if (StandardNames.IS_RI && "NONEwithDSA".equalsIgnoreCase(sig.getAlgorithm())) {
- try {
- sig.verify(signature);
- fail("Expected RI to have a NONEwithDSA bug");
- } catch (SignatureException bug) {
- }
- } else {
- // Calling Signature.verify a second time should not throw
- // http://code.google.com/p/android/issues/detail?id=34933
- sig.verify(signature);
- }
-
- testSignature_MultipleThreads_Misuse(sig);
- }
-
- private static final byte[] PK_BYTES = HexEncoding.decode(
- "30819f300d06092a864886f70d010101050003818d0030818902818100cd769d178f61475fce3001"
- + "2604218320c77a427121d3b41dd76756c8fc0c428cd15cb754adc85466f47547b1c85623d9c17fc6"
- + "4f202fca21099caf99460c824ad657caa8c2db34996838d32623c4f23c8b6a4e6698603901262619"
- + "4840e0896b1a6ec4f6652484aad04569bb6a885b822a10d700224359c632dc7324520cbb3d020301"
- + "0001");
- private static final byte[] CONTENT = HexEncoding.decode(
- "f2fa9d73656e00fa01edc12e73656e2e7670632e6432004867268c46dd95030b93ce7260423e5c00"
- + "fabd4d656d6265727300fa018dc12e73656e2e7670632e643100d7c258dc00fabd44657669636573"
- + "00faa54b65797300fa02b5c12e4d2e4b009471968cc68835f8a68dde10f53d19693d480de767e5fb"
- + "976f3562324006372300fabdfd04e1f51ef3aa00fa8d00000001a203e202859471968cc68835f8a6"
- + "8dde10f53d19693d480de767e5fb976f356232400637230002bab504e1f51ef5810002c29d28463f"
- + "0003da8d000001e201eaf2fa9d73656e00fa01edc12e73656e2e7670632e6432004867268c46dd95"
- + "030b93ce7260423e5c00fabd4d656d6265727300fa018dc12e73656e2e7670632e643100d7c258dc"
- + "00fabd4465766963657300faa54b65797300fa02b5c12e4d2e4b009471968cc68835f8a68dde10f5"
- + "3d19693d480de767e5fb976f3562324006372300fabdfd04e1f51ef3aa000003e202859471968cc6"
- + "8835f8a68dde10f53d19693d480de767e5fb976f3562324006372300000000019a0a9530819f300d"
- + "06092a864886f70d010101050003818d0030818902818100cd769d178f61475fce30012604218320"
- + "c77a427121d3b41dd76756c8fc0c428cd15cb754adc85466f47547b1c85623d9c17fc64f202fca21"
- + "099caf99460c824ad657caa8c2db34996838d32623c4f23c8b6a4e66986039012626194840e0896b"
- + "1a6ec4f6652484aad04569bb6a885b822a10d700224359c632dc7324520cbb3d020301000100");
- private static final byte[] SIGNATURE = HexEncoding.decode(
- "b4016456148cd2e9f580470aad63d19c1fee52b38c9dcb5b4d61a7ca369a7277497775d106d86394"
- + "a69229184333b5a3e6261d5bcebdb02530ca9909f4d790199eae7c140f7db39dee2232191bdf0bfb"
- + "34fdadc44326b9b3f3fa828652bab07f0362ac141c8c3784ebdec44e0b156a5e7bccdc81a56fe954"
- + "56ac8c0e4ae12d97");
-
-
- /**
- * This should actually fail because the ASN.1 encoding is incorrect. It is
- * missing the NULL in the AlgorithmIdentifier field.
- * <p>
- * http://code.google.com/p/android/issues/detail?id=18566 <br/>
- * http://b/5038554
- */
- public void test18566_AlgorithmOid_MissingNull_Failure() throws Exception {
- X509EncodedKeySpec keySpec = new X509EncodedKeySpec(PK_BYTES);
- KeyFactory keyFactory = KeyFactory.getInstance("RSA");
- PublicKey pk = keyFactory.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA256withRSA");
- sig.initVerify(pk);
- sig.update(CONTENT);
- assertFalse(sig.verify(SIGNATURE));
- }
-
- /*
- * Test vectors generated with this private key:
- *
- * -----BEGIN RSA PRIVATE KEY-----
- * MIIEpAIBAAKCAQEA4Ec+irjyKE/rnnQv+XSPoRjtmGM8kvUq63ouvg075gMpvnZq
- * 0Q62pRXQ0s/ZvqeTDwwwZTeJn3lYzT6FsB+IGFJNMSWEqUslHjYltUFB7b/uGYgI
- * 4buX/Hy0m56qr2jpyY19DtxTu8D6ADQ1bWMF+7zDxwAUBThqu8hzyw8+90JfPTPf
- * ezFa4DbSoLZq/UdQOxab8247UWJRW3Ff2oPeryxYrrmr+zCXw8yd2dvl7ylsF2E5
- * Ao6KZx5jBW1F9AGI0sQTNJCEXeUsJTTpxrJHjAe9rpKII7YtBmx3cPn2Pz26JH9T
- * CER0e+eqqF2FO4vSRKzsPePImrRkU6tNJMOsaQIDAQABAoIBADd4R3al8XaY9ayW
- * DfuDobZ1ZOZIvQWXz4q4CHGG8macJ6nsvdSA8Bl6gNBzCebGqW+SUzHlf4tKxvTU
- * XtpFojJpwJ/EKMB6Tm7fc4oV3sl/q9Lyu0ehTyDqcvz+TDbgGtp3vRN82NTaELsW
- * LpSkZilx8XX5hfoYjwVsuX7igW9Dq503R2Ekhs2owWGWwwgYqZXshdOEZ3kSZ7O/
- * IfJzcQppJYYldoQcW2cSwS1L0govMpmtt8E12l6VFavadufK8qO+gFUdBzt4vxFi
- * xIrSt/R0OgI47k0lL31efmUzzK5kzLOTYAdaL9HgNOw65c6cQIzL8OJeQRQCFoez
- * 3UdUroECgYEA9UGIS8Nzeyki1BGe9F4t7izUy7dfRVBaFXqlAJ+Zxzot8HJKxGAk
- * MGMy6omBd2NFRl3G3x4KbxQK/ztzluaomUrF2qloc0cv43dJ0U6z4HXmKdvrNYMz
- * im82SdCiZUp6Qv2atr+krE1IHTkLsimwZL3DEcwb4bYxidp8QM3s8rECgYEA6hp0
- * LduIHO23KIyH442GjdekCdFaQ/RF1Td6C1cx3b/KLa8oqOE81cCvzsM0fXSjniNa
- * PNljPydN4rlPkt9DgzkR2enxz1jyfeLgj/RZZMcg0+whOdx8r8kSlTzeyy81Wi4s
- * NaUPrXVMs7IxZkJLo7bjESoriYw4xcFe2yOGkzkCgYBRgo8exv2ZYCmQG68dfjN7
- * pfCvJ+mE6tiVrOYr199O5FoiQInyzBUa880XP84EdLywTzhqLNzA4ANrokGfVFeS
- * YtRxAL6TGYSj76Bb7PFBV03AebOpXEqD5sQ/MhTW3zLVEt4ZgIXlMeYWuD/X3Z0f
- * TiYHwzM9B8VdEH0dOJNYcQKBgQDbT7UPUN6O21P/NMgJMYigUShn2izKBIl3WeWH
- * wkQBDa+GZNWegIPRbBZHiTAfZ6nweAYNg0oq29NnV1toqKhCwrAqibPzH8zsiiL+
- * OVeVxcbHQitOXXSh6ajzDndZufwtY5wfFWc+hOk6XvFQb0MVODw41Fy9GxQEj0ch
- * 3IIyYQKBgQDYEUWTr0FfthLb8ZI3ENVNB0hiBadqO0MZSWjA3/HxHvD2GkozfV/T
- * dBu8lkDkR7i2tsR8OsEgQ1fTsMVbqShr2nP2KSlvX6kUbYl2NX08dR51FIaWpAt0
- * aFyCzjCQLWOdck/yTV4ulAfuNO3tLjtN9lqpvP623yjQe6aQPxZXaA==
- * -----END RSA PRIVATE KEY-----
- *
- */
-
- private static final BigInteger RSA_2048_modulus = new BigInteger(new byte[] {
- (byte) 0x00, (byte) 0xe0, (byte) 0x47, (byte) 0x3e, (byte) 0x8a, (byte) 0xb8, (byte) 0xf2, (byte) 0x28,
- (byte) 0x4f, (byte) 0xeb, (byte) 0x9e, (byte) 0x74, (byte) 0x2f, (byte) 0xf9, (byte) 0x74, (byte) 0x8f,
- (byte) 0xa1, (byte) 0x18, (byte) 0xed, (byte) 0x98, (byte) 0x63, (byte) 0x3c, (byte) 0x92, (byte) 0xf5,
- (byte) 0x2a, (byte) 0xeb, (byte) 0x7a, (byte) 0x2e, (byte) 0xbe, (byte) 0x0d, (byte) 0x3b, (byte) 0xe6,
- (byte) 0x03, (byte) 0x29, (byte) 0xbe, (byte) 0x76, (byte) 0x6a, (byte) 0xd1, (byte) 0x0e, (byte) 0xb6,
- (byte) 0xa5, (byte) 0x15, (byte) 0xd0, (byte) 0xd2, (byte) 0xcf, (byte) 0xd9, (byte) 0xbe, (byte) 0xa7,
- (byte) 0x93, (byte) 0x0f, (byte) 0x0c, (byte) 0x30, (byte) 0x65, (byte) 0x37, (byte) 0x89, (byte) 0x9f,
- (byte) 0x79, (byte) 0x58, (byte) 0xcd, (byte) 0x3e, (byte) 0x85, (byte) 0xb0, (byte) 0x1f, (byte) 0x88,
- (byte) 0x18, (byte) 0x52, (byte) 0x4d, (byte) 0x31, (byte) 0x25, (byte) 0x84, (byte) 0xa9, (byte) 0x4b,
- (byte) 0x25, (byte) 0x1e, (byte) 0x36, (byte) 0x25, (byte) 0xb5, (byte) 0x41, (byte) 0x41, (byte) 0xed,
- (byte) 0xbf, (byte) 0xee, (byte) 0x19, (byte) 0x88, (byte) 0x08, (byte) 0xe1, (byte) 0xbb, (byte) 0x97,
- (byte) 0xfc, (byte) 0x7c, (byte) 0xb4, (byte) 0x9b, (byte) 0x9e, (byte) 0xaa, (byte) 0xaf, (byte) 0x68,
- (byte) 0xe9, (byte) 0xc9, (byte) 0x8d, (byte) 0x7d, (byte) 0x0e, (byte) 0xdc, (byte) 0x53, (byte) 0xbb,
- (byte) 0xc0, (byte) 0xfa, (byte) 0x00, (byte) 0x34, (byte) 0x35, (byte) 0x6d, (byte) 0x63, (byte) 0x05,
- (byte) 0xfb, (byte) 0xbc, (byte) 0xc3, (byte) 0xc7, (byte) 0x00, (byte) 0x14, (byte) 0x05, (byte) 0x38,
- (byte) 0x6a, (byte) 0xbb, (byte) 0xc8, (byte) 0x73, (byte) 0xcb, (byte) 0x0f, (byte) 0x3e, (byte) 0xf7,
- (byte) 0x42, (byte) 0x5f, (byte) 0x3d, (byte) 0x33, (byte) 0xdf, (byte) 0x7b, (byte) 0x31, (byte) 0x5a,
- (byte) 0xe0, (byte) 0x36, (byte) 0xd2, (byte) 0xa0, (byte) 0xb6, (byte) 0x6a, (byte) 0xfd, (byte) 0x47,
- (byte) 0x50, (byte) 0x3b, (byte) 0x16, (byte) 0x9b, (byte) 0xf3, (byte) 0x6e, (byte) 0x3b, (byte) 0x51,
- (byte) 0x62, (byte) 0x51, (byte) 0x5b, (byte) 0x71, (byte) 0x5f, (byte) 0xda, (byte) 0x83, (byte) 0xde,
- (byte) 0xaf, (byte) 0x2c, (byte) 0x58, (byte) 0xae, (byte) 0xb9, (byte) 0xab, (byte) 0xfb, (byte) 0x30,
- (byte) 0x97, (byte) 0xc3, (byte) 0xcc, (byte) 0x9d, (byte) 0xd9, (byte) 0xdb, (byte) 0xe5, (byte) 0xef,
- (byte) 0x29, (byte) 0x6c, (byte) 0x17, (byte) 0x61, (byte) 0x39, (byte) 0x02, (byte) 0x8e, (byte) 0x8a,
- (byte) 0x67, (byte) 0x1e, (byte) 0x63, (byte) 0x05, (byte) 0x6d, (byte) 0x45, (byte) 0xf4, (byte) 0x01,
- (byte) 0x88, (byte) 0xd2, (byte) 0xc4, (byte) 0x13, (byte) 0x34, (byte) 0x90, (byte) 0x84, (byte) 0x5d,
- (byte) 0xe5, (byte) 0x2c, (byte) 0x25, (byte) 0x34, (byte) 0xe9, (byte) 0xc6, (byte) 0xb2, (byte) 0x47,
- (byte) 0x8c, (byte) 0x07, (byte) 0xbd, (byte) 0xae, (byte) 0x92, (byte) 0x88, (byte) 0x23, (byte) 0xb6,
- (byte) 0x2d, (byte) 0x06, (byte) 0x6c, (byte) 0x77, (byte) 0x70, (byte) 0xf9, (byte) 0xf6, (byte) 0x3f,
- (byte) 0x3d, (byte) 0xba, (byte) 0x24, (byte) 0x7f, (byte) 0x53, (byte) 0x08, (byte) 0x44, (byte) 0x74,
- (byte) 0x7b, (byte) 0xe7, (byte) 0xaa, (byte) 0xa8, (byte) 0x5d, (byte) 0x85, (byte) 0x3b, (byte) 0x8b,
- (byte) 0xd2, (byte) 0x44, (byte) 0xac, (byte) 0xec, (byte) 0x3d, (byte) 0xe3, (byte) 0xc8, (byte) 0x9a,
- (byte) 0xb4, (byte) 0x64, (byte) 0x53, (byte) 0xab, (byte) 0x4d, (byte) 0x24, (byte) 0xc3, (byte) 0xac,
- (byte) 0x69,
- });
-
- private static final BigInteger RSA_2048_privateExponent = new BigInteger(new byte[] {
- (byte) 0x37, (byte) 0x78, (byte) 0x47, (byte) 0x76, (byte) 0xa5, (byte) 0xf1, (byte) 0x76, (byte) 0x98,
- (byte) 0xf5, (byte) 0xac, (byte) 0x96, (byte) 0x0d, (byte) 0xfb, (byte) 0x83, (byte) 0xa1, (byte) 0xb6,
- (byte) 0x75, (byte) 0x64, (byte) 0xe6, (byte) 0x48, (byte) 0xbd, (byte) 0x05, (byte) 0x97, (byte) 0xcf,
- (byte) 0x8a, (byte) 0xb8, (byte) 0x08, (byte) 0x71, (byte) 0x86, (byte) 0xf2, (byte) 0x66, (byte) 0x9c,
- (byte) 0x27, (byte) 0xa9, (byte) 0xec, (byte) 0xbd, (byte) 0xd4, (byte) 0x80, (byte) 0xf0, (byte) 0x19,
- (byte) 0x7a, (byte) 0x80, (byte) 0xd0, (byte) 0x73, (byte) 0x09, (byte) 0xe6, (byte) 0xc6, (byte) 0xa9,
- (byte) 0x6f, (byte) 0x92, (byte) 0x53, (byte) 0x31, (byte) 0xe5, (byte) 0x7f, (byte) 0x8b, (byte) 0x4a,
- (byte) 0xc6, (byte) 0xf4, (byte) 0xd4, (byte) 0x5e, (byte) 0xda, (byte) 0x45, (byte) 0xa2, (byte) 0x32,
- (byte) 0x69, (byte) 0xc0, (byte) 0x9f, (byte) 0xc4, (byte) 0x28, (byte) 0xc0, (byte) 0x7a, (byte) 0x4e,
- (byte) 0x6e, (byte) 0xdf, (byte) 0x73, (byte) 0x8a, (byte) 0x15, (byte) 0xde, (byte) 0xc9, (byte) 0x7f,
- (byte) 0xab, (byte) 0xd2, (byte) 0xf2, (byte) 0xbb, (byte) 0x47, (byte) 0xa1, (byte) 0x4f, (byte) 0x20,
- (byte) 0xea, (byte) 0x72, (byte) 0xfc, (byte) 0xfe, (byte) 0x4c, (byte) 0x36, (byte) 0xe0, (byte) 0x1a,
- (byte) 0xda, (byte) 0x77, (byte) 0xbd, (byte) 0x13, (byte) 0x7c, (byte) 0xd8, (byte) 0xd4, (byte) 0xda,
- (byte) 0x10, (byte) 0xbb, (byte) 0x16, (byte) 0x2e, (byte) 0x94, (byte) 0xa4, (byte) 0x66, (byte) 0x29,
- (byte) 0x71, (byte) 0xf1, (byte) 0x75, (byte) 0xf9, (byte) 0x85, (byte) 0xfa, (byte) 0x18, (byte) 0x8f,
- (byte) 0x05, (byte) 0x6c, (byte) 0xb9, (byte) 0x7e, (byte) 0xe2, (byte) 0x81, (byte) 0x6f, (byte) 0x43,
- (byte) 0xab, (byte) 0x9d, (byte) 0x37, (byte) 0x47, (byte) 0x61, (byte) 0x24, (byte) 0x86, (byte) 0xcd,
- (byte) 0xa8, (byte) 0xc1, (byte) 0x61, (byte) 0x96, (byte) 0xc3, (byte) 0x08, (byte) 0x18, (byte) 0xa9,
- (byte) 0x95, (byte) 0xec, (byte) 0x85, (byte) 0xd3, (byte) 0x84, (byte) 0x67, (byte) 0x79, (byte) 0x12,
- (byte) 0x67, (byte) 0xb3, (byte) 0xbf, (byte) 0x21, (byte) 0xf2, (byte) 0x73, (byte) 0x71, (byte) 0x0a,
- (byte) 0x69, (byte) 0x25, (byte) 0x86, (byte) 0x25, (byte) 0x76, (byte) 0x84, (byte) 0x1c, (byte) 0x5b,
- (byte) 0x67, (byte) 0x12, (byte) 0xc1, (byte) 0x2d, (byte) 0x4b, (byte) 0xd2, (byte) 0x0a, (byte) 0x2f,
- (byte) 0x32, (byte) 0x99, (byte) 0xad, (byte) 0xb7, (byte) 0xc1, (byte) 0x35, (byte) 0xda, (byte) 0x5e,
- (byte) 0x95, (byte) 0x15, (byte) 0xab, (byte) 0xda, (byte) 0x76, (byte) 0xe7, (byte) 0xca, (byte) 0xf2,
- (byte) 0xa3, (byte) 0xbe, (byte) 0x80, (byte) 0x55, (byte) 0x1d, (byte) 0x07, (byte) 0x3b, (byte) 0x78,
- (byte) 0xbf, (byte) 0x11, (byte) 0x62, (byte) 0xc4, (byte) 0x8a, (byte) 0xd2, (byte) 0xb7, (byte) 0xf4,
- (byte) 0x74, (byte) 0x3a, (byte) 0x02, (byte) 0x38, (byte) 0xee, (byte) 0x4d, (byte) 0x25, (byte) 0x2f,
- (byte) 0x7d, (byte) 0x5e, (byte) 0x7e, (byte) 0x65, (byte) 0x33, (byte) 0xcc, (byte) 0xae, (byte) 0x64,
- (byte) 0xcc, (byte) 0xb3, (byte) 0x93, (byte) 0x60, (byte) 0x07, (byte) 0x5a, (byte) 0x2f, (byte) 0xd1,
- (byte) 0xe0, (byte) 0x34, (byte) 0xec, (byte) 0x3a, (byte) 0xe5, (byte) 0xce, (byte) 0x9c, (byte) 0x40,
- (byte) 0x8c, (byte) 0xcb, (byte) 0xf0, (byte) 0xe2, (byte) 0x5e, (byte) 0x41, (byte) 0x14, (byte) 0x02,
- (byte) 0x16, (byte) 0x87, (byte) 0xb3, (byte) 0xdd, (byte) 0x47, (byte) 0x54, (byte) 0xae, (byte) 0x81,
- });
-
- private static final BigInteger RSA_2048_publicExponent = new BigInteger(new byte[] {
- (byte) 0x01, (byte) 0x00, (byte) 0x01,
- });
-
- private static final BigInteger RSA_2048_primeP = new BigInteger(new byte[] {
- (byte) 0x00, (byte) 0xf5, (byte) 0x41, (byte) 0x88, (byte) 0x4b, (byte) 0xc3, (byte) 0x73, (byte) 0x7b,
- (byte) 0x29, (byte) 0x22, (byte) 0xd4, (byte) 0x11, (byte) 0x9e, (byte) 0xf4, (byte) 0x5e, (byte) 0x2d,
- (byte) 0xee, (byte) 0x2c, (byte) 0xd4, (byte) 0xcb, (byte) 0xb7, (byte) 0x5f, (byte) 0x45, (byte) 0x50,
- (byte) 0x5a, (byte) 0x15, (byte) 0x7a, (byte) 0xa5, (byte) 0x00, (byte) 0x9f, (byte) 0x99, (byte) 0xc7,
- (byte) 0x3a, (byte) 0x2d, (byte) 0xf0, (byte) 0x72, (byte) 0x4a, (byte) 0xc4, (byte) 0x60, (byte) 0x24,
- (byte) 0x30, (byte) 0x63, (byte) 0x32, (byte) 0xea, (byte) 0x89, (byte) 0x81, (byte) 0x77, (byte) 0x63,
- (byte) 0x45, (byte) 0x46, (byte) 0x5d, (byte) 0xc6, (byte) 0xdf, (byte) 0x1e, (byte) 0x0a, (byte) 0x6f,
- (byte) 0x14, (byte) 0x0a, (byte) 0xff, (byte) 0x3b, (byte) 0x73, (byte) 0x96, (byte) 0xe6, (byte) 0xa8,
- (byte) 0x99, (byte) 0x4a, (byte) 0xc5, (byte) 0xda, (byte) 0xa9, (byte) 0x68, (byte) 0x73, (byte) 0x47,
- (byte) 0x2f, (byte) 0xe3, (byte) 0x77, (byte) 0x49, (byte) 0xd1, (byte) 0x4e, (byte) 0xb3, (byte) 0xe0,
- (byte) 0x75, (byte) 0xe6, (byte) 0x29, (byte) 0xdb, (byte) 0xeb, (byte) 0x35, (byte) 0x83, (byte) 0x33,
- (byte) 0x8a, (byte) 0x6f, (byte) 0x36, (byte) 0x49, (byte) 0xd0, (byte) 0xa2, (byte) 0x65, (byte) 0x4a,
- (byte) 0x7a, (byte) 0x42, (byte) 0xfd, (byte) 0x9a, (byte) 0xb6, (byte) 0xbf, (byte) 0xa4, (byte) 0xac,
- (byte) 0x4d, (byte) 0x48, (byte) 0x1d, (byte) 0x39, (byte) 0x0b, (byte) 0xb2, (byte) 0x29, (byte) 0xb0,
- (byte) 0x64, (byte) 0xbd, (byte) 0xc3, (byte) 0x11, (byte) 0xcc, (byte) 0x1b, (byte) 0xe1, (byte) 0xb6,
- (byte) 0x31, (byte) 0x89, (byte) 0xda, (byte) 0x7c, (byte) 0x40, (byte) 0xcd, (byte) 0xec, (byte) 0xf2,
- (byte) 0xb1,
- });
-
- private static final BigInteger RSA_2048_primeQ = new BigInteger(new byte[] {
- (byte) 0x00, (byte) 0xea, (byte) 0x1a, (byte) 0x74, (byte) 0x2d, (byte) 0xdb, (byte) 0x88, (byte) 0x1c,
- (byte) 0xed, (byte) 0xb7, (byte) 0x28, (byte) 0x8c, (byte) 0x87, (byte) 0xe3, (byte) 0x8d, (byte) 0x86,
- (byte) 0x8d, (byte) 0xd7, (byte) 0xa4, (byte) 0x09, (byte) 0xd1, (byte) 0x5a, (byte) 0x43, (byte) 0xf4,
- (byte) 0x45, (byte) 0xd5, (byte) 0x37, (byte) 0x7a, (byte) 0x0b, (byte) 0x57, (byte) 0x31, (byte) 0xdd,
- (byte) 0xbf, (byte) 0xca, (byte) 0x2d, (byte) 0xaf, (byte) 0x28, (byte) 0xa8, (byte) 0xe1, (byte) 0x3c,
- (byte) 0xd5, (byte) 0xc0, (byte) 0xaf, (byte) 0xce, (byte) 0xc3, (byte) 0x34, (byte) 0x7d, (byte) 0x74,
- (byte) 0xa3, (byte) 0x9e, (byte) 0x23, (byte) 0x5a, (byte) 0x3c, (byte) 0xd9, (byte) 0x63, (byte) 0x3f,
- (byte) 0x27, (byte) 0x4d, (byte) 0xe2, (byte) 0xb9, (byte) 0x4f, (byte) 0x92, (byte) 0xdf, (byte) 0x43,
- (byte) 0x83, (byte) 0x39, (byte) 0x11, (byte) 0xd9, (byte) 0xe9, (byte) 0xf1, (byte) 0xcf, (byte) 0x58,
- (byte) 0xf2, (byte) 0x7d, (byte) 0xe2, (byte) 0xe0, (byte) 0x8f, (byte) 0xf4, (byte) 0x59, (byte) 0x64,
- (byte) 0xc7, (byte) 0x20, (byte) 0xd3, (byte) 0xec, (byte) 0x21, (byte) 0x39, (byte) 0xdc, (byte) 0x7c,
- (byte) 0xaf, (byte) 0xc9, (byte) 0x12, (byte) 0x95, (byte) 0x3c, (byte) 0xde, (byte) 0xcb, (byte) 0x2f,
- (byte) 0x35, (byte) 0x5a, (byte) 0x2e, (byte) 0x2c, (byte) 0x35, (byte) 0xa5, (byte) 0x0f, (byte) 0xad,
- (byte) 0x75, (byte) 0x4c, (byte) 0xb3, (byte) 0xb2, (byte) 0x31, (byte) 0x66, (byte) 0x42, (byte) 0x4b,
- (byte) 0xa3, (byte) 0xb6, (byte) 0xe3, (byte) 0x11, (byte) 0x2a, (byte) 0x2b, (byte) 0x89, (byte) 0x8c,
- (byte) 0x38, (byte) 0xc5, (byte) 0xc1, (byte) 0x5e, (byte) 0xdb, (byte) 0x23, (byte) 0x86, (byte) 0x93,
- (byte) 0x39,
- });
-
- /* Test data is: "Android.\n" */
- private static final byte[] Vector1Data = new byte[] {
- (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x2e,
- (byte) 0x0a,
- };
-
- private static final byte[] SHA1withRSA_Vector1Signature = {
- (byte) 0x6d, (byte) 0x5b, (byte) 0xff, (byte) 0x68, (byte) 0xda, (byte) 0x18, (byte) 0x98, (byte) 0x72,
- (byte) 0x5c, (byte) 0x1f, (byte) 0x46, (byte) 0x51, (byte) 0x77, (byte) 0x15, (byte) 0x11, (byte) 0xcb,
- (byte) 0xe0, (byte) 0xb9, (byte) 0x3b, (byte) 0x7d, (byte) 0xf5, (byte) 0x96, (byte) 0x98, (byte) 0x24,
- (byte) 0x85, (byte) 0x9d, (byte) 0x3e, (byte) 0xed, (byte) 0x9b, (byte) 0xb2, (byte) 0x8a, (byte) 0x91,
- (byte) 0xfb, (byte) 0xf6, (byte) 0x85, (byte) 0x64, (byte) 0x74, (byte) 0x18, (byte) 0xb5, (byte) 0x1c,
- (byte) 0xb3, (byte) 0x8d, (byte) 0x99, (byte) 0x0d, (byte) 0xdf, (byte) 0xaa, (byte) 0xa6, (byte) 0xa1,
- (byte) 0xc3, (byte) 0xb6, (byte) 0x25, (byte) 0xb3, (byte) 0x06, (byte) 0xe0, (byte) 0xef, (byte) 0x28,
- (byte) 0xb0, (byte) 0x4d, (byte) 0x50, (byte) 0xc7, (byte) 0x75, (byte) 0x39, (byte) 0xb9, (byte) 0x2c,
- (byte) 0x47, (byte) 0xb5, (byte) 0xe2, (byte) 0x96, (byte) 0xf8, (byte) 0xf6, (byte) 0xcb, (byte) 0xa0,
- (byte) 0x58, (byte) 0xc9, (byte) 0x3e, (byte) 0xd5, (byte) 0xfc, (byte) 0x26, (byte) 0xd9, (byte) 0x55,
- (byte) 0x73, (byte) 0x39, (byte) 0x75, (byte) 0xb3, (byte) 0xb0, (byte) 0x0a, (byte) 0x5f, (byte) 0x5e,
- (byte) 0x3b, (byte) 0x4a, (byte) 0x2e, (byte) 0xb1, (byte) 0x0e, (byte) 0x7d, (byte) 0xe5, (byte) 0xcc,
- (byte) 0x04, (byte) 0x2c, (byte) 0xd1, (byte) 0x0a, (byte) 0x32, (byte) 0xaa, (byte) 0xd9, (byte) 0x8d,
- (byte) 0x1f, (byte) 0xcb, (byte) 0xe3, (byte) 0x7f, (byte) 0x63, (byte) 0x12, (byte) 0xb1, (byte) 0x98,
- (byte) 0x46, (byte) 0x46, (byte) 0x07, (byte) 0xd9, (byte) 0x49, (byte) 0xd2, (byte) 0xbf, (byte) 0xb5,
- (byte) 0xbc, (byte) 0xbb, (byte) 0xfd, (byte) 0x1c, (byte) 0xd7, (byte) 0x11, (byte) 0x94, (byte) 0xaa,
- (byte) 0x5f, (byte) 0x7b, (byte) 0xb2, (byte) 0x0c, (byte) 0x5d, (byte) 0x94, (byte) 0x53, (byte) 0x5e,
- (byte) 0x81, (byte) 0x5c, (byte) 0xbb, (byte) 0x1d, (byte) 0x4f, (byte) 0x30, (byte) 0xcd, (byte) 0xf8,
- (byte) 0xd7, (byte) 0xa5, (byte) 0xfa, (byte) 0x5e, (byte) 0xe0, (byte) 0x19, (byte) 0x3f, (byte) 0xa4,
- (byte) 0xaa, (byte) 0x56, (byte) 0x4e, (byte) 0xec, (byte) 0xeb, (byte) 0xee, (byte) 0xa2, (byte) 0x6c,
- (byte) 0xc9, (byte) 0x4f, (byte) 0xc2, (byte) 0xcc, (byte) 0x2a, (byte) 0xbc, (byte) 0x5b, (byte) 0x09,
- (byte) 0x10, (byte) 0x73, (byte) 0x61, (byte) 0x0c, (byte) 0x04, (byte) 0xb6, (byte) 0xb7, (byte) 0x2c,
- (byte) 0x37, (byte) 0xd2, (byte) 0xca, (byte) 0x2d, (byte) 0x54, (byte) 0xf2, (byte) 0xf7, (byte) 0x77,
- (byte) 0xe1, (byte) 0xba, (byte) 0x9f, (byte) 0x29, (byte) 0x07, (byte) 0xa2, (byte) 0x74, (byte) 0xc6,
- (byte) 0xe9, (byte) 0x1e, (byte) 0xde, (byte) 0xd7, (byte) 0x9c, (byte) 0x4b, (byte) 0xb7, (byte) 0x66,
- (byte) 0x52, (byte) 0xe8, (byte) 0xac, (byte) 0xf6, (byte) 0x76, (byte) 0xab, (byte) 0x16, (byte) 0x82,
- (byte) 0x96, (byte) 0x87, (byte) 0x40, (byte) 0x0f, (byte) 0xad, (byte) 0x2d, (byte) 0x46, (byte) 0xa6,
- (byte) 0x28, (byte) 0x04, (byte) 0x13, (byte) 0xc2, (byte) 0xce, (byte) 0x50, (byte) 0x56, (byte) 0x6d,
- (byte) 0xbe, (byte) 0x0c, (byte) 0x91, (byte) 0xd0, (byte) 0x8e, (byte) 0x80, (byte) 0x9e, (byte) 0x91,
- (byte) 0x8f, (byte) 0x62, (byte) 0xb3, (byte) 0x57, (byte) 0xd6, (byte) 0xae, (byte) 0x53, (byte) 0x91,
- (byte) 0x83, (byte) 0xe9, (byte) 0x38, (byte) 0x77, (byte) 0x8f, (byte) 0x20, (byte) 0xdd, (byte) 0x13,
- (byte) 0x7d, (byte) 0x15, (byte) 0x44, (byte) 0x7e, (byte) 0xb5, (byte) 0x00, (byte) 0xd6, (byte) 0x45,
- };
-
- private static final byte[] Vector2Data = new byte[] {
- (byte) 0x54, (byte) 0x68, (byte) 0x69, (byte) 0x73, (byte) 0x20, (byte) 0x69, (byte) 0x73, (byte) 0x20,
- (byte) 0x61, (byte) 0x20, (byte) 0x73, (byte) 0x69, (byte) 0x67, (byte) 0x6e, (byte) 0x65, (byte) 0x64,
- (byte) 0x20, (byte) 0x6d, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x61, (byte) 0x67, (byte) 0x65,
- (byte) 0x20, (byte) 0x66, (byte) 0x72, (byte) 0x6f, (byte) 0x6d, (byte) 0x20, (byte) 0x4b, (byte) 0x65,
- (byte) 0x6e, (byte) 0x6e, (byte) 0x79, (byte) 0x20, (byte) 0x52, (byte) 0x6f, (byte) 0x6f, (byte) 0x74,
- (byte) 0x2e, (byte) 0x0a,
- };
-
- private static final byte[] SHA1withRSA_Vector2Signature = new byte[] {
- (byte) 0x2e, (byte) 0xa6, (byte) 0x33, (byte) 0xd1, (byte) 0x9d, (byte) 0xfc, (byte) 0x4e, (byte) 0x27,
- (byte) 0xb3, (byte) 0xa8, (byte) 0x9a, (byte) 0xf2, (byte) 0x48, (byte) 0x62, (byte) 0x15, (byte) 0xa2,
- (byte) 0xce, (byte) 0x5f, (byte) 0x2b, (byte) 0x0e, (byte) 0xc5, (byte) 0x26, (byte) 0xba, (byte) 0xd9,
- (byte) 0x0f, (byte) 0x60, (byte) 0xeb, (byte) 0xf0, (byte) 0xd5, (byte) 0x5c, (byte) 0x6b, (byte) 0x23,
- (byte) 0x11, (byte) 0x95, (byte) 0xa4, (byte) 0xbd, (byte) 0x11, (byte) 0x68, (byte) 0xe7, (byte) 0x3a,
- (byte) 0x37, (byte) 0x3d, (byte) 0x79, (byte) 0xb8, (byte) 0x4f, (byte) 0xe9, (byte) 0xa1, (byte) 0x88,
- (byte) 0xfb, (byte) 0xa9, (byte) 0x8b, (byte) 0x34, (byte) 0xa1, (byte) 0xe0, (byte) 0xca, (byte) 0x11,
- (byte) 0xdd, (byte) 0xd0, (byte) 0x83, (byte) 0x7f, (byte) 0xc1, (byte) 0x0b, (byte) 0x16, (byte) 0x61,
- (byte) 0xac, (byte) 0x09, (byte) 0xa2, (byte) 0xdd, (byte) 0x40, (byte) 0x5b, (byte) 0x8c, (byte) 0x7a,
- (byte) 0xb2, (byte) 0xb4, (byte) 0x02, (byte) 0x7c, (byte) 0xd4, (byte) 0x9a, (byte) 0xe6, (byte) 0xa5,
- (byte) 0x1a, (byte) 0x27, (byte) 0x77, (byte) 0x70, (byte) 0xe3, (byte) 0xe3, (byte) 0x71, (byte) 0xc7,
- (byte) 0x59, (byte) 0xc7, (byte) 0x9f, (byte) 0xb8, (byte) 0xef, (byte) 0xe7, (byte) 0x15, (byte) 0x02,
- (byte) 0x0d, (byte) 0x70, (byte) 0xdc, (byte) 0x2c, (byte) 0xe9, (byte) 0xf7, (byte) 0x63, (byte) 0x2a,
- (byte) 0xb5, (byte) 0xee, (byte) 0x9f, (byte) 0x29, (byte) 0x56, (byte) 0x86, (byte) 0x99, (byte) 0xb3,
- (byte) 0x0f, (byte) 0xe5, (byte) 0x1f, (byte) 0x76, (byte) 0x22, (byte) 0x3b, (byte) 0x7f, (byte) 0xa9,
- (byte) 0x9e, (byte) 0xd4, (byte) 0xc4, (byte) 0x83, (byte) 0x5d, (byte) 0x57, (byte) 0xcc, (byte) 0x37,
- (byte) 0xcb, (byte) 0x9a, (byte) 0x9e, (byte) 0x73, (byte) 0x44, (byte) 0x93, (byte) 0xb4, (byte) 0xf1,
- (byte) 0x6b, (byte) 0x98, (byte) 0xa0, (byte) 0x57, (byte) 0xbb, (byte) 0x5e, (byte) 0x8f, (byte) 0x89,
- (byte) 0x5b, (byte) 0x97, (byte) 0x26, (byte) 0xe4, (byte) 0xd0, (byte) 0x51, (byte) 0x0a, (byte) 0x5a,
- (byte) 0xb7, (byte) 0x12, (byte) 0x1a, (byte) 0x6d, (byte) 0xb0, (byte) 0x79, (byte) 0x30, (byte) 0x51,
- (byte) 0x83, (byte) 0x2e, (byte) 0xe2, (byte) 0x7a, (byte) 0x67, (byte) 0x66, (byte) 0xd3, (byte) 0x95,
- (byte) 0xca, (byte) 0xfc, (byte) 0xcb, (byte) 0x92, (byte) 0x79, (byte) 0x32, (byte) 0x26, (byte) 0x86,
- (byte) 0xe1, (byte) 0x0d, (byte) 0xd8, (byte) 0x19, (byte) 0xfa, (byte) 0x65, (byte) 0x37, (byte) 0xc9,
- (byte) 0x4c, (byte) 0x2a, (byte) 0xe1, (byte) 0x42, (byte) 0xc7, (byte) 0xd4, (byte) 0xb7, (byte) 0xeb,
- (byte) 0x1f, (byte) 0xc3, (byte) 0x53, (byte) 0x64, (byte) 0x6f, (byte) 0x2b, (byte) 0x78, (byte) 0x18,
- (byte) 0x03, (byte) 0xda, (byte) 0x8d, (byte) 0x62, (byte) 0x24, (byte) 0x70, (byte) 0xab, (byte) 0xe6,
- (byte) 0x16, (byte) 0x13, (byte) 0x24, (byte) 0x6b, (byte) 0x5f, (byte) 0xd3, (byte) 0xec, (byte) 0xc1,
- (byte) 0x58, (byte) 0x64, (byte) 0xbd, (byte) 0x30, (byte) 0x98, (byte) 0x5e, (byte) 0x33, (byte) 0xce,
- (byte) 0x87, (byte) 0x64, (byte) 0x14, (byte) 0x07, (byte) 0x85, (byte) 0x43, (byte) 0x3e, (byte) 0x9f,
- (byte) 0x27, (byte) 0x9f, (byte) 0x63, (byte) 0x66, (byte) 0x9d, (byte) 0x26, (byte) 0x19, (byte) 0xc0,
- (byte) 0x02, (byte) 0x08, (byte) 0x15, (byte) 0xcb, (byte) 0xb4, (byte) 0xaa, (byte) 0x4a, (byte) 0xc8,
- (byte) 0xc0, (byte) 0x09, (byte) 0x15, (byte) 0x7d, (byte) 0x8a, (byte) 0x21, (byte) 0xbc, (byte) 0xa3,
- };
-
- /*
- * echo 'Android.' | openssl dgst -sha224 -binary -sign privkey.pem | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA224withRSA_Vector2Signature = new byte[] {
- (byte) 0xBD, (byte) 0x3F, (byte) 0xD4, (byte) 0x20, (byte) 0x5B, (byte) 0xC0, (byte) 0x89, (byte) 0x4F,
- (byte) 0x99, (byte) 0x6C, (byte) 0xF4, (byte) 0xA4, (byte) 0x70, (byte) 0xE3, (byte) 0x5B, (byte) 0x33,
- (byte) 0xB3, (byte) 0xCA, (byte) 0xFE, (byte) 0x1F, (byte) 0xB9, (byte) 0x3A, (byte) 0xD6, (byte) 0x9B,
- (byte) 0x1E, (byte) 0xDA, (byte) 0x65, (byte) 0x06, (byte) 0xBD, (byte) 0xC3, (byte) 0x2B, (byte) 0xF8,
- (byte) 0x0E, (byte) 0xA0, (byte) 0xB5, (byte) 0x33, (byte) 0x7F, (byte) 0x15, (byte) 0xDC, (byte) 0xBB,
- (byte) 0xDC, (byte) 0x98, (byte) 0x96, (byte) 0xF5, (byte) 0xF8, (byte) 0xE5, (byte) 0x55, (byte) 0x7D,
- (byte) 0x48, (byte) 0x51, (byte) 0xC5, (byte) 0xAE, (byte) 0x12, (byte) 0xA2, (byte) 0x61, (byte) 0xC7,
- (byte) 0xA2, (byte) 0x00, (byte) 0x0F, (byte) 0x35, (byte) 0x54, (byte) 0x3C, (byte) 0x7E, (byte) 0x97,
- (byte) 0x19, (byte) 0x2D, (byte) 0x8F, (byte) 0xFD, (byte) 0x51, (byte) 0x04, (byte) 0x72, (byte) 0x23,
- (byte) 0x65, (byte) 0x16, (byte) 0x41, (byte) 0x12, (byte) 0x46, (byte) 0xD6, (byte) 0x20, (byte) 0xB6,
- (byte) 0x4E, (byte) 0xD6, (byte) 0xE8, (byte) 0x60, (byte) 0x91, (byte) 0x05, (byte) 0xCA, (byte) 0x57,
- (byte) 0x6F, (byte) 0x53, (byte) 0xA4, (byte) 0x05, (byte) 0x2A, (byte) 0x37, (byte) 0xDD, (byte) 0x2E,
- (byte) 0xA4, (byte) 0xC7, (byte) 0xBF, (byte) 0x9E, (byte) 0xF6, (byte) 0xD5, (byte) 0xD4, (byte) 0x34,
- (byte) 0xB8, (byte) 0xB3, (byte) 0x8B, (byte) 0x66, (byte) 0x2C, (byte) 0xB6, (byte) 0x5F, (byte) 0xA4,
- (byte) 0xB7, (byte) 0x77, (byte) 0xF8, (byte) 0x9A, (byte) 0x9C, (byte) 0x44, (byte) 0x9F, (byte) 0xF0,
- (byte) 0xCA, (byte) 0x53, (byte) 0x56, (byte) 0x2F, (byte) 0x99, (byte) 0x2E, (byte) 0x4B, (byte) 0xA2,
- (byte) 0x26, (byte) 0x50, (byte) 0x30, (byte) 0x97, (byte) 0x2B, (byte) 0x4B, (byte) 0x0C, (byte) 0x3E,
- (byte) 0x28, (byte) 0x0B, (byte) 0x88, (byte) 0x87, (byte) 0x9E, (byte) 0xCE, (byte) 0xCB, (byte) 0x57,
- (byte) 0x72, (byte) 0x6B, (byte) 0xF6, (byte) 0xD6, (byte) 0xAA, (byte) 0x4D, (byte) 0x5F, (byte) 0x19,
- (byte) 0x7A, (byte) 0xAD, (byte) 0x44, (byte) 0x09, (byte) 0x33, (byte) 0x62, (byte) 0xC8, (byte) 0x56,
- (byte) 0x82, (byte) 0x84, (byte) 0xBF, (byte) 0x52, (byte) 0xC6, (byte) 0xA2, (byte) 0x2B, (byte) 0xE3,
- (byte) 0xC2, (byte) 0x7F, (byte) 0xE3, (byte) 0x06, (byte) 0xC3, (byte) 0x30, (byte) 0xB8, (byte) 0xD4,
- (byte) 0x01, (byte) 0xE6, (byte) 0x3D, (byte) 0xDB, (byte) 0xCA, (byte) 0xE4, (byte) 0xFB, (byte) 0xA8,
- (byte) 0x7B, (byte) 0x2D, (byte) 0x8F, (byte) 0x39, (byte) 0x7A, (byte) 0x63, (byte) 0x9F, (byte) 0x02,
- (byte) 0xE8, (byte) 0x91, (byte) 0xD1, (byte) 0xEE, (byte) 0x60, (byte) 0xEE, (byte) 0xCA, (byte) 0xF2,
- (byte) 0x33, (byte) 0x7D, (byte) 0xF2, (byte) 0x41, (byte) 0x52, (byte) 0x0B, (byte) 0x9B, (byte) 0x1B,
- (byte) 0x2D, (byte) 0x89, (byte) 0x38, (byte) 0xEC, (byte) 0x24, (byte) 0x60, (byte) 0x40, (byte) 0x40,
- (byte) 0x6F, (byte) 0xB6, (byte) 0x6F, (byte) 0x86, (byte) 0xB5, (byte) 0x0A, (byte) 0x3D, (byte) 0x98,
- (byte) 0x77, (byte) 0x3F, (byte) 0x59, (byte) 0x41, (byte) 0x3E, (byte) 0x4D, (byte) 0xE4, (byte) 0x4E,
- (byte) 0x91, (byte) 0xCD, (byte) 0x8E, (byte) 0x33, (byte) 0x60, (byte) 0x16, (byte) 0x8D, (byte) 0xAB,
- (byte) 0x04, (byte) 0x14, (byte) 0xE8, (byte) 0x76, (byte) 0xF1, (byte) 0x06, (byte) 0xCD, (byte) 0x4A,
- (byte) 0x88, (byte) 0xC7, (byte) 0x69, (byte) 0x6B, (byte) 0xC6, (byte) 0xDA, (byte) 0x9E, (byte) 0x09
- };
-
- private static final byte[] SHA256withRSA_Vector2Signature = new byte[] {
- (byte) 0x18, (byte) 0x6e, (byte) 0x31, (byte) 0x1f, (byte) 0x1d, (byte) 0x44, (byte) 0x09, (byte) 0x3e,
- (byte) 0xa0, (byte) 0xc4, (byte) 0x3d, (byte) 0xb4, (byte) 0x1b, (byte) 0xf2, (byte) 0xd8, (byte) 0xa4,
- (byte) 0x59, (byte) 0xab, (byte) 0xb5, (byte) 0x37, (byte) 0x28, (byte) 0xb8, (byte) 0x94, (byte) 0x6b,
- (byte) 0x6f, (byte) 0x13, (byte) 0x54, (byte) 0xff, (byte) 0xac, (byte) 0x15, (byte) 0x84, (byte) 0xd0,
- (byte) 0xc9, (byte) 0x15, (byte) 0x5b, (byte) 0x69, (byte) 0x05, (byte) 0xf1, (byte) 0x44, (byte) 0xfd,
- (byte) 0xde, (byte) 0xe8, (byte) 0xb4, (byte) 0x12, (byte) 0x59, (byte) 0x9e, (byte) 0x4c, (byte) 0x0b,
- (byte) 0xd5, (byte) 0x49, (byte) 0x33, (byte) 0x28, (byte) 0xe0, (byte) 0xcb, (byte) 0x87, (byte) 0x85,
- (byte) 0xd8, (byte) 0x18, (byte) 0x6f, (byte) 0xfe, (byte) 0xa2, (byte) 0x23, (byte) 0x82, (byte) 0xf0,
- (byte) 0xe5, (byte) 0x39, (byte) 0x1b, (byte) 0x8c, (byte) 0x93, (byte) 0x11, (byte) 0x49, (byte) 0x72,
- (byte) 0x2a, (byte) 0x5b, (byte) 0x25, (byte) 0xff, (byte) 0x4e, (byte) 0x88, (byte) 0x70, (byte) 0x9d,
- (byte) 0x9d, (byte) 0xff, (byte) 0xe2, (byte) 0xc0, (byte) 0x7e, (byte) 0xc8, (byte) 0x03, (byte) 0x40,
- (byte) 0xbe, (byte) 0x44, (byte) 0x09, (byte) 0xeb, (byte) 0x9e, (byte) 0x8e, (byte) 0x88, (byte) 0xe4,
- (byte) 0x98, (byte) 0x82, (byte) 0x06, (byte) 0xa4, (byte) 0x9d, (byte) 0x63, (byte) 0x88, (byte) 0x65,
- (byte) 0xa3, (byte) 0x8e, (byte) 0x0d, (byte) 0x22, (byte) 0xf3, (byte) 0x33, (byte) 0xf2, (byte) 0x40,
- (byte) 0xe8, (byte) 0x91, (byte) 0x67, (byte) 0x72, (byte) 0x29, (byte) 0x1c, (byte) 0x08, (byte) 0xff,
- (byte) 0x54, (byte) 0xa0, (byte) 0xcc, (byte) 0xad, (byte) 0x84, (byte) 0x88, (byte) 0x4b, (byte) 0x3b,
- (byte) 0xef, (byte) 0xf9, (byte) 0x5e, (byte) 0xb3, (byte) 0x41, (byte) 0x6a, (byte) 0xbd, (byte) 0x94,
- (byte) 0x16, (byte) 0x7d, (byte) 0x9d, (byte) 0x53, (byte) 0x77, (byte) 0xf1, (byte) 0x6a, (byte) 0x95,
- (byte) 0x57, (byte) 0xad, (byte) 0x65, (byte) 0x9d, (byte) 0x75, (byte) 0x95, (byte) 0xf6, (byte) 0x6a,
- (byte) 0xd2, (byte) 0x88, (byte) 0xea, (byte) 0x5b, (byte) 0xa2, (byte) 0x94, (byte) 0x8f, (byte) 0x5e,
- (byte) 0x84, (byte) 0x18, (byte) 0x19, (byte) 0x46, (byte) 0x83, (byte) 0x0b, (byte) 0x6d, (byte) 0x5b,
- (byte) 0xb9, (byte) 0xdb, (byte) 0xa4, (byte) 0xe5, (byte) 0x17, (byte) 0x02, (byte) 0x9e, (byte) 0x11,
- (byte) 0xed, (byte) 0xd9, (byte) 0x7b, (byte) 0x83, (byte) 0x87, (byte) 0x89, (byte) 0xf3, (byte) 0xe4,
- (byte) 0xbf, (byte) 0x0e, (byte) 0xe8, (byte) 0xdc, (byte) 0x55, (byte) 0x9c, (byte) 0xf7, (byte) 0xc9,
- (byte) 0xc3, (byte) 0xe2, (byte) 0x2c, (byte) 0xf7, (byte) 0x8c, (byte) 0xaa, (byte) 0x17, (byte) 0x1f,
- (byte) 0xd1, (byte) 0xc7, (byte) 0x74, (byte) 0xc7, (byte) 0x8e, (byte) 0x1c, (byte) 0x5b, (byte) 0xd2,
- (byte) 0x31, (byte) 0x74, (byte) 0x43, (byte) 0x9a, (byte) 0x52, (byte) 0xbf, (byte) 0x89, (byte) 0xc5,
- (byte) 0xb4, (byte) 0x80, (byte) 0x6a, (byte) 0x9e, (byte) 0x05, (byte) 0xdb, (byte) 0xbb, (byte) 0x07,
- (byte) 0x8c, (byte) 0x08, (byte) 0x61, (byte) 0xba, (byte) 0xa4, (byte) 0xbc, (byte) 0x80, (byte) 0x3a,
- (byte) 0xdd, (byte) 0x3b, (byte) 0x1a, (byte) 0x8c, (byte) 0x21, (byte) 0xd8, (byte) 0xa3, (byte) 0xc0,
- (byte) 0xc7, (byte) 0xd1, (byte) 0x08, (byte) 0xe1, (byte) 0x34, (byte) 0x99, (byte) 0xc0, (byte) 0xcf,
- (byte) 0x80, (byte) 0xff, (byte) 0xfa, (byte) 0x07, (byte) 0xef, (byte) 0x5c, (byte) 0x45, (byte) 0xe5,
- };
-
- private static final byte[] SHA384withRSA_Vector2Signature = new byte[] {
- (byte) 0xaf, (byte) 0xf7, (byte) 0x7a, (byte) 0xc2, (byte) 0xbb, (byte) 0xb8, (byte) 0xbd, (byte) 0xe3,
- (byte) 0x42, (byte) 0xaa, (byte) 0x16, (byte) 0x8a, (byte) 0x52, (byte) 0x6c, (byte) 0x99, (byte) 0x66,
- (byte) 0x08, (byte) 0xbe, (byte) 0x15, (byte) 0xd9, (byte) 0x7c, (byte) 0x60, (byte) 0x2c, (byte) 0xac,
- (byte) 0x4d, (byte) 0x4c, (byte) 0xf4, (byte) 0xdf, (byte) 0xbc, (byte) 0x16, (byte) 0x58, (byte) 0x0a,
- (byte) 0x4e, (byte) 0xde, (byte) 0x8d, (byte) 0xb3, (byte) 0xbd, (byte) 0x03, (byte) 0x4e, (byte) 0x23,
- (byte) 0x40, (byte) 0xa5, (byte) 0x80, (byte) 0xae, (byte) 0x83, (byte) 0xb4, (byte) 0x0f, (byte) 0x99,
- (byte) 0x44, (byte) 0xc3, (byte) 0x5e, (byte) 0xdb, (byte) 0x59, (byte) 0x1d, (byte) 0xea, (byte) 0x7b,
- (byte) 0x4d, (byte) 0xf3, (byte) 0xd2, (byte) 0xad, (byte) 0xbd, (byte) 0x21, (byte) 0x9f, (byte) 0x8e,
- (byte) 0x87, (byte) 0x8f, (byte) 0x12, (byte) 0x13, (byte) 0x33, (byte) 0xf1, (byte) 0xc0, (byte) 0x9d,
- (byte) 0xe7, (byte) 0xec, (byte) 0x6e, (byte) 0xad, (byte) 0xea, (byte) 0x5d, (byte) 0x69, (byte) 0xbb,
- (byte) 0xab, (byte) 0x5b, (byte) 0xd8, (byte) 0x55, (byte) 0x56, (byte) 0xc8, (byte) 0xda, (byte) 0x81,
- (byte) 0x41, (byte) 0xfb, (byte) 0xd3, (byte) 0x11, (byte) 0x6c, (byte) 0x97, (byte) 0xa7, (byte) 0xc3,
- (byte) 0xf1, (byte) 0x31, (byte) 0xbf, (byte) 0xbe, (byte) 0x3f, (byte) 0xdb, (byte) 0x35, (byte) 0x85,
- (byte) 0xb7, (byte) 0xb0, (byte) 0x75, (byte) 0x7f, (byte) 0xaf, (byte) 0xfb, (byte) 0x65, (byte) 0x61,
- (byte) 0xc7, (byte) 0x0e, (byte) 0x63, (byte) 0xb5, (byte) 0x7d, (byte) 0x95, (byte) 0xe9, (byte) 0x16,
- (byte) 0x9d, (byte) 0x6a, (byte) 0x00, (byte) 0x9f, (byte) 0x5e, (byte) 0xcd, (byte) 0xff, (byte) 0xa6,
- (byte) 0xbc, (byte) 0x71, (byte) 0xf2, (byte) 0x2c, (byte) 0xd3, (byte) 0x68, (byte) 0xb9, (byte) 0x3f,
- (byte) 0xaa, (byte) 0x06, (byte) 0xf1, (byte) 0x9c, (byte) 0x7e, (byte) 0xca, (byte) 0x4a, (byte) 0xfe,
- (byte) 0xb1, (byte) 0x73, (byte) 0x19, (byte) 0x80, (byte) 0x05, (byte) 0xa6, (byte) 0x85, (byte) 0x14,
- (byte) 0xda, (byte) 0x7a, (byte) 0x16, (byte) 0x7a, (byte) 0xc2, (byte) 0x46, (byte) 0x57, (byte) 0xa7,
- (byte) 0xc0, (byte) 0xbf, (byte) 0xcd, (byte) 0xdc, (byte) 0x2f, (byte) 0x64, (byte) 0xf6, (byte) 0x6d,
- (byte) 0xdc, (byte) 0xcb, (byte) 0x5a, (byte) 0x29, (byte) 0x95, (byte) 0x1c, (byte) 0xfe, (byte) 0xf2,
- (byte) 0xda, (byte) 0x7e, (byte) 0xcb, (byte) 0x26, (byte) 0x12, (byte) 0xc6, (byte) 0xb0, (byte) 0xba,
- (byte) 0x84, (byte) 0x9b, (byte) 0x4f, (byte) 0xba, (byte) 0x1b, (byte) 0x78, (byte) 0x25, (byte) 0xb8,
- (byte) 0x8f, (byte) 0x2e, (byte) 0x51, (byte) 0x5f, (byte) 0x9e, (byte) 0xfc, (byte) 0x40, (byte) 0xbc,
- (byte) 0x85, (byte) 0xcd, (byte) 0x86, (byte) 0x7f, (byte) 0x88, (byte) 0xc5, (byte) 0xaa, (byte) 0x2b,
- (byte) 0x78, (byte) 0xb1, (byte) 0x9c, (byte) 0x51, (byte) 0x9a, (byte) 0xe1, (byte) 0xe1, (byte) 0xc0,
- (byte) 0x40, (byte) 0x47, (byte) 0xcb, (byte) 0xa4, (byte) 0xb7, (byte) 0x6c, (byte) 0x31, (byte) 0xf2,
- (byte) 0xc8, (byte) 0x9a, (byte) 0xad, (byte) 0x0b, (byte) 0xd3, (byte) 0xf6, (byte) 0x85, (byte) 0x9a,
- (byte) 0x8f, (byte) 0x4f, (byte) 0xc9, (byte) 0xd8, (byte) 0x33, (byte) 0x7c, (byte) 0x45, (byte) 0x30,
- (byte) 0xea, (byte) 0x17, (byte) 0xd3, (byte) 0xe3, (byte) 0x90, (byte) 0x2c, (byte) 0xda, (byte) 0xde,
- (byte) 0x41, (byte) 0x17, (byte) 0x3f, (byte) 0x08, (byte) 0xb9, (byte) 0x34, (byte) 0xc0, (byte) 0xd1,
- };
-
- private static final byte[] SHA512withRSA_Vector2Signature = new byte[] {
- (byte) 0x19, (byte) 0xe2, (byte) 0xe5, (byte) 0xf3, (byte) 0x18, (byte) 0x83, (byte) 0xec, (byte) 0xf0,
- (byte) 0xab, (byte) 0x50, (byte) 0x05, (byte) 0x4b, (byte) 0x5f, (byte) 0x22, (byte) 0xfc, (byte) 0x82,
- (byte) 0x6d, (byte) 0xca, (byte) 0xe7, (byte) 0xbe, (byte) 0x23, (byte) 0x94, (byte) 0xfa, (byte) 0xf9,
- (byte) 0xa4, (byte) 0x8a, (byte) 0x95, (byte) 0x4d, (byte) 0x14, (byte) 0x08, (byte) 0x8b, (byte) 0x5e,
- (byte) 0x03, (byte) 0x1b, (byte) 0x74, (byte) 0xde, (byte) 0xc1, (byte) 0x45, (byte) 0x9c, (byte) 0xce,
- (byte) 0x1d, (byte) 0xac, (byte) 0xab, (byte) 0xd3, (byte) 0xa8, (byte) 0xc3, (byte) 0xca, (byte) 0x67,
- (byte) 0x80, (byte) 0xf6, (byte) 0x03, (byte) 0x46, (byte) 0x65, (byte) 0x77, (byte) 0x59, (byte) 0xbb,
- (byte) 0xb8, (byte) 0x83, (byte) 0xee, (byte) 0xc2, (byte) 0x3e, (byte) 0x78, (byte) 0xdd, (byte) 0x89,
- (byte) 0xcd, (byte) 0x9b, (byte) 0x78, (byte) 0x35, (byte) 0xa9, (byte) 0x09, (byte) 0xc8, (byte) 0x77,
- (byte) 0xdd, (byte) 0xd3, (byte) 0xa0, (byte) 0x64, (byte) 0xb0, (byte) 0x74, (byte) 0x48, (byte) 0x51,
- (byte) 0x4f, (byte) 0xa0, (byte) 0xae, (byte) 0x33, (byte) 0xb3, (byte) 0x28, (byte) 0xb0, (byte) 0xa8,
- (byte) 0x78, (byte) 0x8f, (byte) 0xa2, (byte) 0x32, (byte) 0xa6, (byte) 0x0a, (byte) 0xaa, (byte) 0x09,
- (byte) 0xb5, (byte) 0x8d, (byte) 0x4c, (byte) 0x44, (byte) 0x46, (byte) 0xb4, (byte) 0xd2, (byte) 0x06,
- (byte) 0x6b, (byte) 0x8c, (byte) 0x51, (byte) 0x6e, (byte) 0x9c, (byte) 0xfa, (byte) 0x1f, (byte) 0x94,
- (byte) 0x3e, (byte) 0x19, (byte) 0x9c, (byte) 0x63, (byte) 0xfe, (byte) 0xa9, (byte) 0x9a, (byte) 0xe3,
- (byte) 0x6c, (byte) 0x82, (byte) 0x64, (byte) 0x5f, (byte) 0xca, (byte) 0xc2, (byte) 0x8d, (byte) 0x66,
- (byte) 0xbe, (byte) 0x12, (byte) 0x6e, (byte) 0xb6, (byte) 0x35, (byte) 0x6d, (byte) 0xaa, (byte) 0xed,
- (byte) 0x4b, (byte) 0x50, (byte) 0x08, (byte) 0x1c, (byte) 0xbf, (byte) 0x07, (byte) 0x70, (byte) 0x78,
- (byte) 0xc0, (byte) 0xbb, (byte) 0xc5, (byte) 0x8d, (byte) 0x6c, (byte) 0x8d, (byte) 0x35, (byte) 0xff,
- (byte) 0x04, (byte) 0x81, (byte) 0xd8, (byte) 0xf4, (byte) 0xd2, (byte) 0x4a, (byte) 0xc3, (byte) 0x05,
- (byte) 0x23, (byte) 0xcb, (byte) 0xeb, (byte) 0x20, (byte) 0xb1, (byte) 0xd4, (byte) 0x2d, (byte) 0xd8,
- (byte) 0x7a, (byte) 0xd4, (byte) 0x7e, (byte) 0xf6, (byte) 0xa9, (byte) 0xe8, (byte) 0x72, (byte) 0x69,
- (byte) 0xfe, (byte) 0xab, (byte) 0x54, (byte) 0x4d, (byte) 0xd1, (byte) 0xf4, (byte) 0x6b, (byte) 0x83,
- (byte) 0x31, (byte) 0x17, (byte) 0xed, (byte) 0x26, (byte) 0xe9, (byte) 0xd2, (byte) 0x5b, (byte) 0xad,
- (byte) 0x42, (byte) 0x42, (byte) 0xa5, (byte) 0x8f, (byte) 0x98, (byte) 0x7c, (byte) 0x1b, (byte) 0x5c,
- (byte) 0x8e, (byte) 0x88, (byte) 0x56, (byte) 0x20, (byte) 0x8e, (byte) 0x48, (byte) 0xf9, (byte) 0x4d,
- (byte) 0x82, (byte) 0x91, (byte) 0xcb, (byte) 0xc8, (byte) 0x1c, (byte) 0x7c, (byte) 0xa5, (byte) 0x69,
- (byte) 0x1b, (byte) 0x40, (byte) 0xc2, (byte) 0x4c, (byte) 0x25, (byte) 0x16, (byte) 0x4f, (byte) 0xfa,
- (byte) 0x09, (byte) 0xeb, (byte) 0xf5, (byte) 0x6c, (byte) 0x55, (byte) 0x3c, (byte) 0x6e, (byte) 0xf7,
- (byte) 0xc0, (byte) 0xc1, (byte) 0x34, (byte) 0xd1, (byte) 0x53, (byte) 0xa3, (byte) 0x69, (byte) 0x64,
- (byte) 0xee, (byte) 0xf4, (byte) 0xf9, (byte) 0xc7, (byte) 0x96, (byte) 0x60, (byte) 0x84, (byte) 0x87,
- (byte) 0xb4, (byte) 0xc7, (byte) 0x3c, (byte) 0x26, (byte) 0xa7, (byte) 0x3a, (byte) 0xbf, (byte) 0x95,
- };
-
- private static final byte[] MD5withRSA_Vector2Signature = new byte[] {
- (byte) 0x04, (byte) 0x17, (byte) 0x83, (byte) 0x10, (byte) 0xe2, (byte) 0x6e, (byte) 0xdf, (byte) 0xa9,
- (byte) 0xae, (byte) 0xd2, (byte) 0xdc, (byte) 0x5f, (byte) 0x70, (byte) 0x1d, (byte) 0xaf, (byte) 0x54,
- (byte) 0xc0, (byte) 0x5f, (byte) 0x0b, (byte) 0x2c, (byte) 0xe6, (byte) 0xd0, (byte) 0x00, (byte) 0x18,
- (byte) 0x4c, (byte) 0xf6, (byte) 0x8f, (byte) 0x18, (byte) 0x10, (byte) 0x74, (byte) 0x90, (byte) 0x99,
- (byte) 0xa9, (byte) 0x90, (byte) 0x3c, (byte) 0x5a, (byte) 0x38, (byte) 0xd3, (byte) 0x3d, (byte) 0x48,
- (byte) 0xcf, (byte) 0x31, (byte) 0xaf, (byte) 0x12, (byte) 0x98, (byte) 0xfb, (byte) 0x66, (byte) 0xe8,
- (byte) 0x58, (byte) 0xec, (byte) 0xca, (byte) 0xe1, (byte) 0x42, (byte) 0xf9, (byte) 0x84, (byte) 0x17,
- (byte) 0x6f, (byte) 0x4c, (byte) 0x3e, (byte) 0xc4, (byte) 0x40, (byte) 0xc6, (byte) 0x70, (byte) 0xb0,
- (byte) 0x38, (byte) 0xf3, (byte) 0x47, (byte) 0xeb, (byte) 0x6f, (byte) 0xcb, (byte) 0xea, (byte) 0x21,
- (byte) 0x41, (byte) 0xf3, (byte) 0xa0, (byte) 0x3e, (byte) 0x42, (byte) 0xad, (byte) 0xa5, (byte) 0xad,
- (byte) 0x5d, (byte) 0x2c, (byte) 0x1a, (byte) 0x8e, (byte) 0x3e, (byte) 0xb3, (byte) 0xa5, (byte) 0x78,
- (byte) 0x3d, (byte) 0x56, (byte) 0x09, (byte) 0x93, (byte) 0xc9, (byte) 0x93, (byte) 0xd3, (byte) 0xd2,
- (byte) 0x9a, (byte) 0xc5, (byte) 0xa5, (byte) 0x2e, (byte) 0xb2, (byte) 0xd8, (byte) 0x37, (byte) 0xc7,
- (byte) 0x13, (byte) 0x1a, (byte) 0x0b, (byte) 0xda, (byte) 0x50, (byte) 0x28, (byte) 0x6d, (byte) 0x47,
- (byte) 0x65, (byte) 0x52, (byte) 0xcd, (byte) 0xe7, (byte) 0xec, (byte) 0x57, (byte) 0x00, (byte) 0x41,
- (byte) 0x34, (byte) 0x28, (byte) 0xb9, (byte) 0x8b, (byte) 0x03, (byte) 0x41, (byte) 0xb6, (byte) 0xd5,
- (byte) 0xa8, (byte) 0xef, (byte) 0xd3, (byte) 0xdd, (byte) 0x80, (byte) 0xd5, (byte) 0x69, (byte) 0xe4,
- (byte) 0xf0, (byte) 0x4d, (byte) 0xa4, (byte) 0x7d, (byte) 0x60, (byte) 0x2f, (byte) 0xef, (byte) 0x79,
- (byte) 0x07, (byte) 0x75, (byte) 0xeb, (byte) 0xf7, (byte) 0x4b, (byte) 0x43, (byte) 0x41, (byte) 0xdb,
- (byte) 0x33, (byte) 0xad, (byte) 0x9c, (byte) 0x7b, (byte) 0x78, (byte) 0x83, (byte) 0x34, (byte) 0x77,
- (byte) 0xe4, (byte) 0x80, (byte) 0xbe, (byte) 0xe6, (byte) 0x6f, (byte) 0xdd, (byte) 0xac, (byte) 0xa5,
- (byte) 0x37, (byte) 0xcf, (byte) 0xb5, (byte) 0x44, (byte) 0x11, (byte) 0x77, (byte) 0x96, (byte) 0x45,
- (byte) 0xf9, (byte) 0xae, (byte) 0x48, (byte) 0xa6, (byte) 0xbe, (byte) 0x30, (byte) 0x32, (byte) 0xeb,
- (byte) 0x43, (byte) 0x6f, (byte) 0x66, (byte) 0x39, (byte) 0x57, (byte) 0xf8, (byte) 0xe6, (byte) 0x60,
- (byte) 0x31, (byte) 0xd0, (byte) 0xfc, (byte) 0xcf, (byte) 0x9f, (byte) 0xe5, (byte) 0x3d, (byte) 0xcf,
- (byte) 0xbd, (byte) 0x7b, (byte) 0x13, (byte) 0x20, (byte) 0xce, (byte) 0x11, (byte) 0xfd, (byte) 0xe5,
- (byte) 0xff, (byte) 0x90, (byte) 0x85, (byte) 0xdf, (byte) 0xca, (byte) 0x3d, (byte) 0xd9, (byte) 0x44,
- (byte) 0x16, (byte) 0xc2, (byte) 0x32, (byte) 0x28, (byte) 0xc7, (byte) 0x01, (byte) 0x6d, (byte) 0xea,
- (byte) 0xcb, (byte) 0x0d, (byte) 0x85, (byte) 0x08, (byte) 0x6f, (byte) 0xcb, (byte) 0x41, (byte) 0x6a,
- (byte) 0x3c, (byte) 0x0f, (byte) 0x3d, (byte) 0x38, (byte) 0xb5, (byte) 0x61, (byte) 0xc5, (byte) 0x64,
- (byte) 0x64, (byte) 0x81, (byte) 0x4c, (byte) 0xcd, (byte) 0xd1, (byte) 0x6a, (byte) 0x87, (byte) 0x28,
- (byte) 0x02, (byte) 0xaf, (byte) 0x8f, (byte) 0x59, (byte) 0xe5, (byte) 0x67, (byte) 0x25, (byte) 0x00,
- };
-
- /*
- * openssl rsautl -raw -sign -inkey rsa.key | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] NONEwithRSA_Vector1Signature = new byte[] {
- (byte) 0x35, (byte) 0x43, (byte) 0x38, (byte) 0x44, (byte) 0xAD, (byte) 0x3F,
- (byte) 0x97, (byte) 0x02, (byte) 0xFB, (byte) 0x59, (byte) 0x1F, (byte) 0x4A,
- (byte) 0x2B, (byte) 0xB9, (byte) 0x06, (byte) 0xEC, (byte) 0x66, (byte) 0xE6,
- (byte) 0xD2, (byte) 0xC5, (byte) 0x8B, (byte) 0x7B, (byte) 0xE3, (byte) 0x18,
- (byte) 0xBF, (byte) 0x07, (byte) 0xD6, (byte) 0x01, (byte) 0xF9, (byte) 0xD9,
- (byte) 0x89, (byte) 0xC4, (byte) 0xDB, (byte) 0x00, (byte) 0x68, (byte) 0xFF,
- (byte) 0x9B, (byte) 0x43, (byte) 0x90, (byte) 0xF2, (byte) 0xDB, (byte) 0x83,
- (byte) 0xF4, (byte) 0x7E, (byte) 0xC6, (byte) 0x81, (byte) 0x01, (byte) 0x3A,
- (byte) 0x0B, (byte) 0xE5, (byte) 0xED, (byte) 0x08, (byte) 0x73, (byte) 0x3E,
- (byte) 0xE1, (byte) 0x3F, (byte) 0xDF, (byte) 0x1F, (byte) 0x07, (byte) 0x6D,
- (byte) 0x22, (byte) 0x8D, (byte) 0xCC, (byte) 0x4E, (byte) 0xE3, (byte) 0x9A,
- (byte) 0xBC, (byte) 0xCC, (byte) 0x8F, (byte) 0x9E, (byte) 0x9B, (byte) 0x02,
- (byte) 0x48, (byte) 0x00, (byte) 0xAC, (byte) 0x9F, (byte) 0xA4, (byte) 0x8F,
- (byte) 0x87, (byte) 0xA1, (byte) 0xA8, (byte) 0xE6, (byte) 0x9D, (byte) 0xCD,
- (byte) 0x8B, (byte) 0x05, (byte) 0xE9, (byte) 0xD2, (byte) 0x05, (byte) 0x8D,
- (byte) 0xC9, (byte) 0x95, (byte) 0x16, (byte) 0xD0, (byte) 0xCD, (byte) 0x43,
- (byte) 0x25, (byte) 0x8A, (byte) 0x11, (byte) 0x46, (byte) 0xD7, (byte) 0x74,
- (byte) 0x4C, (byte) 0xCF, (byte) 0x58, (byte) 0xF9, (byte) 0xA1, (byte) 0x30,
- (byte) 0x84, (byte) 0x52, (byte) 0xC9, (byte) 0x01, (byte) 0x5F, (byte) 0x24,
- (byte) 0x4C, (byte) 0xB1, (byte) 0x9F, (byte) 0x7D, (byte) 0x12, (byte) 0x38,
- (byte) 0x27, (byte) 0x0F, (byte) 0x5E, (byte) 0xFF, (byte) 0xE0, (byte) 0x55,
- (byte) 0x8B, (byte) 0xA3, (byte) 0xAD, (byte) 0x60, (byte) 0x35, (byte) 0x83,
- (byte) 0x58, (byte) 0xAF, (byte) 0x99, (byte) 0xDE, (byte) 0x3F, (byte) 0x5D,
- (byte) 0x80, (byte) 0x80, (byte) 0xFF, (byte) 0x9B, (byte) 0xDE, (byte) 0x5C,
- (byte) 0xAB, (byte) 0x97, (byte) 0x43, (byte) 0x64, (byte) 0xD9, (byte) 0x9F,
- (byte) 0xFB, (byte) 0x67, (byte) 0x65, (byte) 0xA5, (byte) 0x99, (byte) 0xE7,
- (byte) 0xE6, (byte) 0xEB, (byte) 0x05, (byte) 0x95, (byte) 0xFC, (byte) 0x46,
- (byte) 0x28, (byte) 0x4B, (byte) 0xD8, (byte) 0x8C, (byte) 0xF5, (byte) 0x0A,
- (byte) 0xEB, (byte) 0x1F, (byte) 0x30, (byte) 0xEA, (byte) 0xE7, (byte) 0x67,
- (byte) 0x11, (byte) 0x25, (byte) 0xF0, (byte) 0x44, (byte) 0x75, (byte) 0x74,
- (byte) 0x94, (byte) 0x06, (byte) 0x78, (byte) 0xD0, (byte) 0x21, (byte) 0xF4,
- (byte) 0x3F, (byte) 0xC8, (byte) 0xC4, (byte) 0x4A, (byte) 0x57, (byte) 0xBE,
- (byte) 0x02, (byte) 0x3C, (byte) 0x93, (byte) 0xF6, (byte) 0x95, (byte) 0xFB,
- (byte) 0xD1, (byte) 0x77, (byte) 0x8B, (byte) 0x43, (byte) 0xF0, (byte) 0xB9,
- (byte) 0x7D, (byte) 0xE0, (byte) 0x32, (byte) 0xE1, (byte) 0x72, (byte) 0xB5,
- (byte) 0x62, (byte) 0x3F, (byte) 0x86, (byte) 0xC3, (byte) 0xD4, (byte) 0x5F,
- (byte) 0x5E, (byte) 0x54, (byte) 0x1B, (byte) 0x5B, (byte) 0xE6, (byte) 0x74,
- (byte) 0xA1, (byte) 0x0B, (byte) 0xE5, (byte) 0x18, (byte) 0xD2, (byte) 0x4F,
- (byte) 0x93, (byte) 0xF3, (byte) 0x09, (byte) 0x58, (byte) 0xCE, (byte) 0xF0,
- (byte) 0xA3, (byte) 0x61, (byte) 0xE4, (byte) 0x6E, (byte) 0x46, (byte) 0x45,
- (byte) 0x89, (byte) 0x50, (byte) 0xBD, (byte) 0x03, (byte) 0x3F, (byte) 0x38,
- (byte) 0xDA, (byte) 0x5D, (byte) 0xD0, (byte) 0x1B, (byte) 0x1F, (byte) 0xB1,
- (byte) 0xEE, (byte) 0x89, (byte) 0x59, (byte) 0xC5,
- };
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha1 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha1 -pkeyopt rsa_pss_saltlen:20 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA1withRSAPSS_Vector2Signature = new byte[] {
- (byte) 0x66, (byte) 0xE3, (byte) 0xA5, (byte) 0x20, (byte) 0xE9, (byte) 0x5D,
- (byte) 0xDF, (byte) 0x99, (byte) 0xA6, (byte) 0x04, (byte) 0x77, (byte) 0xF8,
- (byte) 0x39, (byte) 0x78, (byte) 0x74, (byte) 0xF5, (byte) 0xC2, (byte) 0x4E,
- (byte) 0x9E, (byte) 0xEB, (byte) 0x24, (byte) 0xDE, (byte) 0xB4, (byte) 0x36,
- (byte) 0x69, (byte) 0x1F, (byte) 0xAC, (byte) 0x01, (byte) 0xFF, (byte) 0x5A,
- (byte) 0xE3, (byte) 0x89, (byte) 0x8A, (byte) 0xE9, (byte) 0x92, (byte) 0x32,
- (byte) 0xA7, (byte) 0xA4, (byte) 0xC0, (byte) 0x25, (byte) 0x00, (byte) 0x14,
- (byte) 0xFF, (byte) 0x38, (byte) 0x19, (byte) 0x37, (byte) 0x84, (byte) 0x1A,
- (byte) 0x3D, (byte) 0xCA, (byte) 0xEE, (byte) 0xF3, (byte) 0xC6, (byte) 0x91,
- (byte) 0xED, (byte) 0x02, (byte) 0xE6, (byte) 0x1D, (byte) 0x73, (byte) 0xDA,
- (byte) 0xD4, (byte) 0x55, (byte) 0x93, (byte) 0x54, (byte) 0x9A, (byte) 0xE6,
- (byte) 0x2E, (byte) 0x7D, (byte) 0x5C, (byte) 0x41, (byte) 0xAF, (byte) 0xED,
- (byte) 0xAD, (byte) 0x8E, (byte) 0x7F, (byte) 0x47, (byte) 0x3B, (byte) 0x23,
- (byte) 0xC3, (byte) 0xB8, (byte) 0xBB, (byte) 0xCD, (byte) 0x87, (byte) 0xC4,
- (byte) 0xA3, (byte) 0x32, (byte) 0x16, (byte) 0x57, (byte) 0xCC, (byte) 0xB8,
- (byte) 0xB6, (byte) 0x96, (byte) 0x84, (byte) 0x1A, (byte) 0xBC, (byte) 0xF8,
- (byte) 0x09, (byte) 0x53, (byte) 0xB0, (byte) 0x9D, (byte) 0xE1, (byte) 0x6F,
- (byte) 0xB2, (byte) 0xEB, (byte) 0x83, (byte) 0xDC, (byte) 0x61, (byte) 0x31,
- (byte) 0xD7, (byte) 0x02, (byte) 0xB4, (byte) 0xD1, (byte) 0xBA, (byte) 0xBD,
- (byte) 0xF0, (byte) 0x78, (byte) 0xC6, (byte) 0xBE, (byte) 0x1F, (byte) 0xB0,
- (byte) 0xE1, (byte) 0xCA, (byte) 0x32, (byte) 0x57, (byte) 0x9F, (byte) 0x8C,
- (byte) 0xD3, (byte) 0xBB, (byte) 0x04, (byte) 0x1B, (byte) 0x30, (byte) 0x74,
- (byte) 0x5D, (byte) 0xEA, (byte) 0xD3, (byte) 0x6B, (byte) 0x74, (byte) 0x31,
- (byte) 0x6F, (byte) 0x33, (byte) 0x5A, (byte) 0x70, (byte) 0x96, (byte) 0x8B,
- (byte) 0xCB, (byte) 0x22, (byte) 0xF3, (byte) 0xAA, (byte) 0x74, (byte) 0x82,
- (byte) 0xB2, (byte) 0x82, (byte) 0x71, (byte) 0x4D, (byte) 0x42, (byte) 0x13,
- (byte) 0x3F, (byte) 0xEA, (byte) 0xE3, (byte) 0x39, (byte) 0xC5, (byte) 0x03,
- (byte) 0x27, (byte) 0xFF, (byte) 0x78, (byte) 0xB2, (byte) 0xA6, (byte) 0x71,
- (byte) 0x07, (byte) 0x1C, (byte) 0xB3, (byte) 0x97, (byte) 0xFB, (byte) 0xE8,
- (byte) 0x85, (byte) 0x6D, (byte) 0x14, (byte) 0xDF, (byte) 0xF9, (byte) 0x7D,
- (byte) 0x0D, (byte) 0x0C, (byte) 0x9F, (byte) 0xC3, (byte) 0xE2, (byte) 0xDB,
- (byte) 0xE0, (byte) 0xA5, (byte) 0x05, (byte) 0xBC, (byte) 0x47, (byte) 0x36,
- (byte) 0xEB, (byte) 0x1E, (byte) 0xBA, (byte) 0x60, (byte) 0x12, (byte) 0x19,
- (byte) 0xA5, (byte) 0x7E, (byte) 0x55, (byte) 0x0C, (byte) 0x9B, (byte) 0xD4,
- (byte) 0x9A, (byte) 0xE9, (byte) 0x72, (byte) 0x5C, (byte) 0x5B, (byte) 0xF4,
- (byte) 0xAA, (byte) 0x4A, (byte) 0x12, (byte) 0x8B, (byte) 0xC2, (byte) 0x8E,
- (byte) 0xC2, (byte) 0x9A, (byte) 0x3E, (byte) 0x0C, (byte) 0x40, (byte) 0xA4,
- (byte) 0x0A, (byte) 0xFF, (byte) 0xF8, (byte) 0xC1, (byte) 0x85, (byte) 0x59,
- (byte) 0xDA, (byte) 0xC6, (byte) 0x8C, (byte) 0x83, (byte) 0x2A, (byte) 0x68,
- (byte) 0x84, (byte) 0x53, (byte) 0x17, (byte) 0x28, (byte) 0x78, (byte) 0x3F,
- (byte) 0x5A, (byte) 0xA4, (byte) 0x04, (byte) 0xE6, (byte) 0x23, (byte) 0x8D,
- (byte) 0x2A, (byte) 0x71, (byte) 0xC1, (byte) 0xBC, (byte) 0x1C, (byte) 0xFD,
- (byte) 0x75, (byte) 0x16, (byte) 0x6E, (byte) 0x85,
- };
- private static final PSSParameterSpec SHA1withRSAPSS_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 20, 1);
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha1 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha1 -pkeyopt rsa_pss_saltlen:0 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA1withRSAPSS_NoSalt_Vector2Signature = new byte[] {
- (byte) 0x31, (byte) 0x61, (byte) 0xA5, (byte) 0x47, (byte) 0x28, (byte) 0x44,
- (byte) 0x48, (byte) 0x5A, (byte) 0xDA, (byte) 0x78, (byte) 0xA7, (byte) 0x85,
- (byte) 0xE9, (byte) 0x64, (byte) 0x69, (byte) 0xCF, (byte) 0x14, (byte) 0x07,
- (byte) 0x3F, (byte) 0xA8, (byte) 0xDB, (byte) 0xFC, (byte) 0xB7, (byte) 0x89,
- (byte) 0x87, (byte) 0x74, (byte) 0xB9, (byte) 0x81, (byte) 0x37, (byte) 0x62,
- (byte) 0xD1, (byte) 0x07, (byte) 0x0F, (byte) 0x3D, (byte) 0xDF, (byte) 0xA8,
- (byte) 0x84, (byte) 0x38, (byte) 0x31, (byte) 0xEB, (byte) 0x17, (byte) 0x3F,
- (byte) 0xE0, (byte) 0x28, (byte) 0x75, (byte) 0x1F, (byte) 0xE9, (byte) 0x4D,
- (byte) 0xD3, (byte) 0x62, (byte) 0xFA, (byte) 0xCF, (byte) 0xCC, (byte) 0x2E,
- (byte) 0xC7, (byte) 0x81, (byte) 0xE1, (byte) 0xEA, (byte) 0xEC, (byte) 0x78,
- (byte) 0xFE, (byte) 0x19, (byte) 0x59, (byte) 0x54, (byte) 0x1D, (byte) 0x27,
- (byte) 0xED, (byte) 0x0C, (byte) 0x54, (byte) 0xDF, (byte) 0xE3, (byte) 0x44,
- (byte) 0x31, (byte) 0x21, (byte) 0x31, (byte) 0xA7, (byte) 0x23, (byte) 0xC4,
- (byte) 0xE2, (byte) 0x69, (byte) 0x8A, (byte) 0xB3, (byte) 0x1A, (byte) 0x72,
- (byte) 0x4F, (byte) 0x4E, (byte) 0x82, (byte) 0x86, (byte) 0x2D, (byte) 0x2B,
- (byte) 0x85, (byte) 0xFE, (byte) 0x4A, (byte) 0x28, (byte) 0x90, (byte) 0xF7,
- (byte) 0xDF, (byte) 0xD6, (byte) 0xB1, (byte) 0x3E, (byte) 0xC6, (byte) 0xFB,
- (byte) 0x76, (byte) 0x7B, (byte) 0x3D, (byte) 0x12, (byte) 0x81, (byte) 0x6E,
- (byte) 0xFD, (byte) 0x00, (byte) 0x7D, (byte) 0xD0, (byte) 0xDC, (byte) 0x25,
- (byte) 0xD0, (byte) 0x86, (byte) 0x6C, (byte) 0xE8, (byte) 0x0F, (byte) 0x09,
- (byte) 0x82, (byte) 0x74, (byte) 0x89, (byte) 0x79, (byte) 0x69, (byte) 0x73,
- (byte) 0x37, (byte) 0x64, (byte) 0xEE, (byte) 0x53, (byte) 0x57, (byte) 0x20,
- (byte) 0xFA, (byte) 0x0B, (byte) 0x4A, (byte) 0x5A, (byte) 0x4D, (byte) 0x33,
- (byte) 0xAC, (byte) 0x8B, (byte) 0x04, (byte) 0xA5, (byte) 0x4A, (byte) 0x1A,
- (byte) 0x9B, (byte) 0x66, (byte) 0xAA, (byte) 0x0B, (byte) 0x3D, (byte) 0x15,
- (byte) 0xD9, (byte) 0x3E, (byte) 0x2F, (byte) 0xD2, (byte) 0xA1, (byte) 0x28,
- (byte) 0x13, (byte) 0x59, (byte) 0x98, (byte) 0xC3, (byte) 0x45, (byte) 0x7C,
- (byte) 0xEE, (byte) 0x60, (byte) 0xD0, (byte) 0xBD, (byte) 0x42, (byte) 0x16,
- (byte) 0x84, (byte) 0x19, (byte) 0xF6, (byte) 0xD9, (byte) 0xF7, (byte) 0x7D,
- (byte) 0x77, (byte) 0xAD, (byte) 0x60, (byte) 0xE2, (byte) 0xE3, (byte) 0x22,
- (byte) 0xB9, (byte) 0xFA, (byte) 0xD5, (byte) 0xFA, (byte) 0x6E, (byte) 0x1F,
- (byte) 0x69, (byte) 0x3F, (byte) 0xB1, (byte) 0xA7, (byte) 0x1A, (byte) 0x22,
- (byte) 0xF7, (byte) 0x31, (byte) 0x97, (byte) 0x68, (byte) 0x62, (byte) 0x0F,
- (byte) 0x39, (byte) 0xB0, (byte) 0xE7, (byte) 0x63, (byte) 0xAE, (byte) 0x65,
- (byte) 0x69, (byte) 0xD0, (byte) 0xD3, (byte) 0x56, (byte) 0xC9, (byte) 0xA6,
- (byte) 0xA4, (byte) 0xA5, (byte) 0xA4, (byte) 0x61, (byte) 0xA9, (byte) 0xC4,
- (byte) 0x45, (byte) 0xCD, (byte) 0x49, (byte) 0x76, (byte) 0xC8, (byte) 0x53,
- (byte) 0x46, (byte) 0xD0, (byte) 0x63, (byte) 0x35, (byte) 0x89, (byte) 0x04,
- (byte) 0x22, (byte) 0xD7, (byte) 0xB6, (byte) 0x63, (byte) 0xAF, (byte) 0xC2,
- (byte) 0x97, (byte) 0x10, (byte) 0xDF, (byte) 0xDE, (byte) 0xE6, (byte) 0x39,
- (byte) 0x25, (byte) 0x2F, (byte) 0xEA, (byte) 0xD8, (byte) 0x56, (byte) 0x5A,
- (byte) 0xC1, (byte) 0xB8, (byte) 0xCA, (byte) 0xC1, (byte) 0x8A, (byte) 0xB8,
- (byte) 0x87, (byte) 0x2F, (byte) 0xCD, (byte) 0x21,
- };
- private static final PSSParameterSpec SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 0, 1);
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha1 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha1 -pkeyopt rsa_pss_saltlen:234 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA1withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
- (byte) 0x49, (byte) 0xDB, (byte) 0xAD, (byte) 0x48, (byte) 0x7C, (byte) 0x06,
- (byte) 0x03, (byte) 0x7C, (byte) 0x58, (byte) 0xE1, (byte) 0x38, (byte) 0x20,
- (byte) 0x46, (byte) 0x28, (byte) 0x60, (byte) 0x64, (byte) 0x94, (byte) 0x51,
- (byte) 0xA3, (byte) 0xD1, (byte) 0xC9, (byte) 0x52, (byte) 0xC6, (byte) 0x2A,
- (byte) 0xB3, (byte) 0xCC, (byte) 0xD6, (byte) 0x19, (byte) 0x50, (byte) 0x99,
- (byte) 0x60, (byte) 0x58, (byte) 0xA2, (byte) 0x86, (byte) 0xA8, (byte) 0x74,
- (byte) 0x50, (byte) 0x8C, (byte) 0x0E, (byte) 0x32, (byte) 0x58, (byte) 0x56,
- (byte) 0x6D, (byte) 0x30, (byte) 0x38, (byte) 0xFB, (byte) 0x26, (byte) 0xC3,
- (byte) 0xFD, (byte) 0x8E, (byte) 0x36, (byte) 0x73, (byte) 0x82, (byte) 0x9A,
- (byte) 0xB4, (byte) 0xE5, (byte) 0x22, (byte) 0x96, (byte) 0x55, (byte) 0x3C,
- (byte) 0x18, (byte) 0xD7, (byte) 0x46, (byte) 0xF1, (byte) 0x7C, (byte) 0xE6,
- (byte) 0x8E, (byte) 0x0A, (byte) 0x18, (byte) 0xA7, (byte) 0x29, (byte) 0x96,
- (byte) 0x8D, (byte) 0xFC, (byte) 0x0E, (byte) 0xBE, (byte) 0x91, (byte) 0xA0,
- (byte) 0xF8, (byte) 0xE2, (byte) 0x70, (byte) 0x5A, (byte) 0xE3, (byte) 0x76,
- (byte) 0xAC, (byte) 0x18, (byte) 0x10, (byte) 0xB4, (byte) 0xB1, (byte) 0xFF,
- (byte) 0x58, (byte) 0xBC, (byte) 0x10, (byte) 0xF5, (byte) 0x88, (byte) 0x2F,
- (byte) 0x0B, (byte) 0x10, (byte) 0x9D, (byte) 0x52, (byte) 0x2D, (byte) 0x42,
- (byte) 0xDB, (byte) 0xFD, (byte) 0xA7, (byte) 0x23, (byte) 0x3C, (byte) 0x4B,
- (byte) 0xB3, (byte) 0xD2, (byte) 0x96, (byte) 0x1B, (byte) 0xCE, (byte) 0xB3,
- (byte) 0xA3, (byte) 0xC3, (byte) 0x42, (byte) 0xA4, (byte) 0x0E, (byte) 0x35,
- (byte) 0x5C, (byte) 0xC2, (byte) 0x32, (byte) 0xC7, (byte) 0x8C, (byte) 0xFC,
- (byte) 0x7F, (byte) 0xE0, (byte) 0xF7, (byte) 0x1D, (byte) 0x38, (byte) 0x21,
- (byte) 0x3C, (byte) 0xDF, (byte) 0x82, (byte) 0x1A, (byte) 0xBD, (byte) 0x83,
- (byte) 0xE9, (byte) 0x56, (byte) 0xF0, (byte) 0xF1, (byte) 0x54, (byte) 0x76,
- (byte) 0xE3, (byte) 0xCE, (byte) 0x86, (byte) 0x69, (byte) 0xC2, (byte) 0x61,
- (byte) 0x6D, (byte) 0x8E, (byte) 0xF5, (byte) 0xA3, (byte) 0x61, (byte) 0xCA,
- (byte) 0x16, (byte) 0xCB, (byte) 0x7A, (byte) 0xF5, (byte) 0xBF, (byte) 0x36,
- (byte) 0xCB, (byte) 0x7D, (byte) 0xB1, (byte) 0xE9, (byte) 0x70, (byte) 0x41,
- (byte) 0xCF, (byte) 0x89, (byte) 0x51, (byte) 0x13, (byte) 0xCC, (byte) 0x95,
- (byte) 0x50, (byte) 0xC8, (byte) 0xB6, (byte) 0x30, (byte) 0x35, (byte) 0xE3,
- (byte) 0x13, (byte) 0x08, (byte) 0xF6, (byte) 0xBE, (byte) 0x20, (byte) 0xF1,
- (byte) 0x48, (byte) 0x4D, (byte) 0x46, (byte) 0x95, (byte) 0xFE, (byte) 0x9E,
- (byte) 0xD2, (byte) 0xD5, (byte) 0x29, (byte) 0x81, (byte) 0x2E, (byte) 0x0F,
- (byte) 0x6F, (byte) 0xA7, (byte) 0x02, (byte) 0x15, (byte) 0xCA, (byte) 0x75,
- (byte) 0x77, (byte) 0x29, (byte) 0x7C, (byte) 0x3A, (byte) 0xE3, (byte) 0x2B,
- (byte) 0xD7, (byte) 0x3D, (byte) 0x5C, (byte) 0x94, (byte) 0x3B, (byte) 0x2A,
- (byte) 0x91, (byte) 0xDB, (byte) 0xFA, (byte) 0x69, (byte) 0x47, (byte) 0x1C,
- (byte) 0x2C, (byte) 0x46, (byte) 0x49, (byte) 0xE6, (byte) 0x37, (byte) 0x5D,
- (byte) 0x78, (byte) 0x71, (byte) 0x76, (byte) 0xC1, (byte) 0xB6, (byte) 0x2E,
- (byte) 0x4E, (byte) 0x3C, (byte) 0x83, (byte) 0x6F, (byte) 0x82, (byte) 0xC3,
- (byte) 0xD8, (byte) 0x50, (byte) 0xD7, (byte) 0x1B, (byte) 0xAF, (byte) 0xF9,
- (byte) 0xE3, (byte) 0xF1, (byte) 0x47, (byte) 0xC8, (byte) 0x12, (byte) 0x86,
- (byte) 0x82, (byte) 0x9D, (byte) 0x3F, (byte) 0xCE,
- };
- private static final PSSParameterSpec SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 234, 1);
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha224 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha224 -pkeyopt rsa_pss_saltlen:28 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA224withRSAPSS_Vector2Signature = new byte[] {
- (byte) 0x86, (byte) 0x41, (byte) 0xCC, (byte) 0x4B, (byte) 0x82, (byte) 0x74,
- (byte) 0x04, (byte) 0x43, (byte) 0x8C, (byte) 0xAB, (byte) 0xF6, (byte) 0x3B,
- (byte) 0xFB, (byte) 0x94, (byte) 0xBC, (byte) 0x4C, (byte) 0x0A, (byte) 0xFE,
- (byte) 0x0F, (byte) 0x4F, (byte) 0x0F, (byte) 0x9F, (byte) 0x84, (byte) 0x35,
- (byte) 0x57, (byte) 0x8B, (byte) 0x8D, (byte) 0xC3, (byte) 0x58, (byte) 0xA6,
- (byte) 0x70, (byte) 0xAC, (byte) 0x40, (byte) 0x6D, (byte) 0xBC, (byte) 0xC1,
- (byte) 0x6A, (byte) 0xFA, (byte) 0x31, (byte) 0x3B, (byte) 0x7A, (byte) 0x23,
- (byte) 0xCA, (byte) 0x1F, (byte) 0xCD, (byte) 0xA7, (byte) 0xE3, (byte) 0xD6,
- (byte) 0x7C, (byte) 0x2C, (byte) 0xF3, (byte) 0x6F, (byte) 0xF5, (byte) 0x82,
- (byte) 0x9E, (byte) 0x18, (byte) 0x70, (byte) 0x90, (byte) 0xE6, (byte) 0xA3,
- (byte) 0x44, (byte) 0x61, (byte) 0xB6, (byte) 0x46, (byte) 0x9B, (byte) 0x0D,
- (byte) 0xE5, (byte) 0x3C, (byte) 0xAE, (byte) 0x22, (byte) 0xF4, (byte) 0x87,
- (byte) 0xB7, (byte) 0x03, (byte) 0xD8, (byte) 0x42, (byte) 0x33, (byte) 0x4E,
- (byte) 0xCC, (byte) 0x7A, (byte) 0xDF, (byte) 0xD7, (byte) 0x57, (byte) 0xEB,
- (byte) 0x51, (byte) 0x6C, (byte) 0xB1, (byte) 0x99, (byte) 0x4D, (byte) 0x94,
- (byte) 0x82, (byte) 0xA7, (byte) 0x69, (byte) 0x85, (byte) 0x8D, (byte) 0x82,
- (byte) 0x18, (byte) 0xE4, (byte) 0x53, (byte) 0xF5, (byte) 0x9F, (byte) 0x82,
- (byte) 0x1C, (byte) 0xE1, (byte) 0x25, (byte) 0x1C, (byte) 0x8E, (byte) 0xE7,
- (byte) 0xC1, (byte) 0xEC, (byte) 0xBE, (byte) 0x3F, (byte) 0xC3, (byte) 0xED,
- (byte) 0x41, (byte) 0x89, (byte) 0x94, (byte) 0x13, (byte) 0x11, (byte) 0x75,
- (byte) 0x3F, (byte) 0x38, (byte) 0x52, (byte) 0x58, (byte) 0xAB, (byte) 0x88,
- (byte) 0x01, (byte) 0x30, (byte) 0xB4, (byte) 0xCD, (byte) 0x45, (byte) 0x3E,
- (byte) 0x1A, (byte) 0x5F, (byte) 0x36, (byte) 0xF8, (byte) 0x51, (byte) 0x90,
- (byte) 0x6E, (byte) 0x6F, (byte) 0x31, (byte) 0x9D, (byte) 0x40, (byte) 0x90,
- (byte) 0x1A, (byte) 0xA8, (byte) 0x10, (byte) 0xEF, (byte) 0x9D, (byte) 0xF8,
- (byte) 0xB0, (byte) 0x03, (byte) 0x01, (byte) 0xFB, (byte) 0xD8, (byte) 0x3D,
- (byte) 0x83, (byte) 0x79, (byte) 0x01, (byte) 0xA7, (byte) 0x82, (byte) 0xC2,
- (byte) 0x46, (byte) 0x35, (byte) 0x68, (byte) 0xD2, (byte) 0x08, (byte) 0x81,
- (byte) 0x31, (byte) 0x14, (byte) 0xE8, (byte) 0x13, (byte) 0x8C, (byte) 0xD4,
- (byte) 0xC4, (byte) 0xCB, (byte) 0xB9, (byte) 0x85, (byte) 0x25, (byte) 0x93,
- (byte) 0x40, (byte) 0x88, (byte) 0x34, (byte) 0x11, (byte) 0xDA, (byte) 0xFF,
- (byte) 0xEF, (byte) 0x4D, (byte) 0xDC, (byte) 0x31, (byte) 0x74, (byte) 0x7B,
- (byte) 0x5E, (byte) 0xA7, (byte) 0x51, (byte) 0x15, (byte) 0x13, (byte) 0xB1,
- (byte) 0x9E, (byte) 0x06, (byte) 0x51, (byte) 0xBA, (byte) 0x11, (byte) 0xDA,
- (byte) 0x64, (byte) 0x1B, (byte) 0x78, (byte) 0x76, (byte) 0x57, (byte) 0x96,
- (byte) 0xF3, (byte) 0x1B, (byte) 0x86, (byte) 0xB2, (byte) 0xF3, (byte) 0x66,
- (byte) 0x64, (byte) 0x2B, (byte) 0x04, (byte) 0x81, (byte) 0x8C, (byte) 0xDC,
- (byte) 0xE0, (byte) 0xEA, (byte) 0x66, (byte) 0x62, (byte) 0x44, (byte) 0x31,
- (byte) 0xA2, (byte) 0x19, (byte) 0xF1, (byte) 0x77, (byte) 0x67, (byte) 0x58,
- (byte) 0x18, (byte) 0x5B, (byte) 0xCB, (byte) 0xBA, (byte) 0x28, (byte) 0x91,
- (byte) 0x47, (byte) 0x5B, (byte) 0x4F, (byte) 0x17, (byte) 0x23, (byte) 0x2A,
- (byte) 0xE4, (byte) 0xB0, (byte) 0xAE, (byte) 0x82, (byte) 0x4E, (byte) 0xCA,
- (byte) 0xA6, (byte) 0x12, (byte) 0xCA, (byte) 0x70,
- };
- private static final PSSParameterSpec SHA224withRSAPSS_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA-224"), 28, 1);
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha224 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha224 -pkeyopt rsa_pss_saltlen:0 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA224withRSAPSS_NoSalt_Vector2Signature = new byte[] {
- (byte) 0xD8, (byte) 0x38, (byte) 0x48, (byte) 0xCD, (byte) 0xA4, (byte) 0x09,
- (byte) 0x36, (byte) 0x35, (byte) 0x47, (byte) 0x55, (byte) 0xDB, (byte) 0x6C,
- (byte) 0x2D, (byte) 0x83, (byte) 0x17, (byte) 0x10, (byte) 0x3E, (byte) 0xCE,
- (byte) 0x95, (byte) 0x02, (byte) 0x58, (byte) 0xCE, (byte) 0xA8, (byte) 0x02,
- (byte) 0x44, (byte) 0xB7, (byte) 0xE4, (byte) 0x32, (byte) 0x3D, (byte) 0x50,
- (byte) 0xE1, (byte) 0x8C, (byte) 0xF3, (byte) 0x24, (byte) 0x6F, (byte) 0xA4,
- (byte) 0x2D, (byte) 0xD7, (byte) 0xFB, (byte) 0x70, (byte) 0x97, (byte) 0xBE,
- (byte) 0xED, (byte) 0x27, (byte) 0x2D, (byte) 0x22, (byte) 0xDC, (byte) 0x62,
- (byte) 0x97, (byte) 0x66, (byte) 0x39, (byte) 0xE0, (byte) 0x36, (byte) 0x5F,
- (byte) 0x07, (byte) 0x78, (byte) 0xAF, (byte) 0x5E, (byte) 0xDC, (byte) 0xFD,
- (byte) 0x21, (byte) 0xA8, (byte) 0xD5, (byte) 0xA7, (byte) 0xD1, (byte) 0xBA,
- (byte) 0x1C, (byte) 0xDA, (byte) 0xCA, (byte) 0x80, (byte) 0x72, (byte) 0x8A,
- (byte) 0xDD, (byte) 0x5C, (byte) 0x16, (byte) 0x6A, (byte) 0x47, (byte) 0xFC,
- (byte) 0x11, (byte) 0x42, (byte) 0x7E, (byte) 0x4E, (byte) 0x3F, (byte) 0x49,
- (byte) 0xCF, (byte) 0x2F, (byte) 0x54, (byte) 0xD7, (byte) 0x13, (byte) 0x76,
- (byte) 0x5D, (byte) 0xE9, (byte) 0x2A, (byte) 0x29, (byte) 0xCC, (byte) 0x73,
- (byte) 0xDB, (byte) 0xE5, (byte) 0xDE, (byte) 0x48, (byte) 0xA2, (byte) 0xE9,
- (byte) 0xD1, (byte) 0xD0, (byte) 0x35, (byte) 0xFE, (byte) 0xA1, (byte) 0x1C,
- (byte) 0x13, (byte) 0x04, (byte) 0x75, (byte) 0x77, (byte) 0xF4, (byte) 0x55,
- (byte) 0x03, (byte) 0xC4, (byte) 0x6D, (byte) 0xAC, (byte) 0x25, (byte) 0x1D,
- (byte) 0x57, (byte) 0xFF, (byte) 0x0D, (byte) 0xE0, (byte) 0x91, (byte) 0xEA,
- (byte) 0xF6, (byte) 0x1F, (byte) 0x3F, (byte) 0x69, (byte) 0xD6, (byte) 0x00,
- (byte) 0xBD, (byte) 0x89, (byte) 0xEA, (byte) 0xD3, (byte) 0x31, (byte) 0x80,
- (byte) 0x5E, (byte) 0x04, (byte) 0x4C, (byte) 0x59, (byte) 0xDE, (byte) 0xD0,
- (byte) 0x62, (byte) 0x93, (byte) 0x3B, (byte) 0xC9, (byte) 0x9F, (byte) 0xE7,
- (byte) 0x69, (byte) 0xC0, (byte) 0xB8, (byte) 0xED, (byte) 0xBF, (byte) 0x0D,
- (byte) 0x60, (byte) 0x28, (byte) 0x55, (byte) 0x20, (byte) 0x0C, (byte) 0x9F,
- (byte) 0xA2, (byte) 0x42, (byte) 0x34, (byte) 0x95, (byte) 0xAE, (byte) 0xF8,
- (byte) 0x67, (byte) 0x7C, (byte) 0xF1, (byte) 0xA0, (byte) 0xC0, (byte) 0x74,
- (byte) 0xF2, (byte) 0xDF, (byte) 0x75, (byte) 0x5B, (byte) 0x6E, (byte) 0x2F,
- (byte) 0xFB, (byte) 0x1F, (byte) 0xDD, (byte) 0xC3, (byte) 0xD3, (byte) 0x90,
- (byte) 0x0A, (byte) 0x33, (byte) 0xF6, (byte) 0x03, (byte) 0x16, (byte) 0xC4,
- (byte) 0xF8, (byte) 0xED, (byte) 0xB7, (byte) 0x45, (byte) 0x39, (byte) 0x5D,
- (byte) 0x7C, (byte) 0xF8, (byte) 0x82, (byte) 0xCE, (byte) 0x7D, (byte) 0xFB,
- (byte) 0x02, (byte) 0x2D, (byte) 0xE0, (byte) 0x96, (byte) 0x35, (byte) 0x60,
- (byte) 0x5D, (byte) 0xBC, (byte) 0x35, (byte) 0x80, (byte) 0x4C, (byte) 0x39,
- (byte) 0x7C, (byte) 0xE7, (byte) 0xD4, (byte) 0xB4, (byte) 0x19, (byte) 0xD1,
- (byte) 0xE5, (byte) 0x8E, (byte) 0x6D, (byte) 0x25, (byte) 0x0C, (byte) 0xB9,
- (byte) 0x0C, (byte) 0x8D, (byte) 0x45, (byte) 0xE4, (byte) 0x67, (byte) 0x73,
- (byte) 0xCF, (byte) 0x87, (byte) 0x7C, (byte) 0x78, (byte) 0xAA, (byte) 0xB9,
- (byte) 0x42, (byte) 0xAE, (byte) 0x7F, (byte) 0xB8, (byte) 0xEC, (byte) 0x4F,
- (byte) 0xD2, (byte) 0x85, (byte) 0x01, (byte) 0x80, (byte) 0x00, (byte) 0xBD,
- (byte) 0xF5, (byte) 0xEA, (byte) 0x44, (byte) 0x6D,
- };
- private static final PSSParameterSpec SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA-224"), 0, 1);
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha224 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha224 -pkeyopt rsa_pss_saltlen:226 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA224withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
- (byte) 0x2C, (byte) 0x19, (byte) 0x5E, (byte) 0x63, (byte) 0xC5, (byte) 0x32,
- (byte) 0xC3, (byte) 0xC7, (byte) 0x52, (byte) 0xE9, (byte) 0x69, (byte) 0x4C,
- (byte) 0x04, (byte) 0xE5, (byte) 0x4A, (byte) 0xF2, (byte) 0x72, (byte) 0x78,
- (byte) 0xBF, (byte) 0xC5, (byte) 0x8D, (byte) 0x5A, (byte) 0x71, (byte) 0xEF,
- (byte) 0xA9, (byte) 0x58, (byte) 0x77, (byte) 0x94, (byte) 0x49, (byte) 0x71,
- (byte) 0xBF, (byte) 0x45, (byte) 0x3E, (byte) 0xA4, (byte) 0x2E, (byte) 0x33,
- (byte) 0x9B, (byte) 0x4E, (byte) 0xA4, (byte) 0x95, (byte) 0x07, (byte) 0x9C,
- (byte) 0xAA, (byte) 0xC4, (byte) 0xA8, (byte) 0x60, (byte) 0xBC, (byte) 0xCD,
- (byte) 0xC3, (byte) 0x45, (byte) 0xE6, (byte) 0xBC, (byte) 0xAD, (byte) 0xB6,
- (byte) 0xF3, (byte) 0x0E, (byte) 0xF6, (byte) 0xD5, (byte) 0xCF, (byte) 0x33,
- (byte) 0xA3, (byte) 0x82, (byte) 0x62, (byte) 0x52, (byte) 0x95, (byte) 0xA8,
- (byte) 0x0E, (byte) 0xD4, (byte) 0xAC, (byte) 0x1F, (byte) 0x9A, (byte) 0xDC,
- (byte) 0x00, (byte) 0xD6, (byte) 0x78, (byte) 0xEA, (byte) 0x53, (byte) 0x00,
- (byte) 0x19, (byte) 0xE3, (byte) 0x81, (byte) 0x7C, (byte) 0x7A, (byte) 0x8E,
- (byte) 0x30, (byte) 0x57, (byte) 0xB7, (byte) 0x81, (byte) 0xD7, (byte) 0x4D,
- (byte) 0x1D, (byte) 0xCB, (byte) 0x99, (byte) 0x8D, (byte) 0xE4, (byte) 0xFA,
- (byte) 0x6E, (byte) 0x4E, (byte) 0xA6, (byte) 0xDA, (byte) 0x13, (byte) 0x92,
- (byte) 0x31, (byte) 0x7C, (byte) 0x2B, (byte) 0x3A, (byte) 0xA0, (byte) 0xF1,
- (byte) 0x03, (byte) 0x83, (byte) 0x12, (byte) 0xD1, (byte) 0x23, (byte) 0xED,
- (byte) 0xC4, (byte) 0x01, (byte) 0x57, (byte) 0x63, (byte) 0xAF, (byte) 0x40,
- (byte) 0x15, (byte) 0xEC, (byte) 0xB8, (byte) 0x5A, (byte) 0xCE, (byte) 0x3D,
- (byte) 0x3E, (byte) 0xCD, (byte) 0xD8, (byte) 0xF3, (byte) 0x76, (byte) 0xCA,
- (byte) 0x23, (byte) 0x20, (byte) 0x68, (byte) 0x17, (byte) 0x5B, (byte) 0x7F,
- (byte) 0xBC, (byte) 0x22, (byte) 0x67, (byte) 0x2A, (byte) 0x91, (byte) 0x05,
- (byte) 0xB3, (byte) 0x85, (byte) 0x60, (byte) 0xD8, (byte) 0x76, (byte) 0xD5,
- (byte) 0x2B, (byte) 0x9C, (byte) 0x80, (byte) 0xB6, (byte) 0xEA, (byte) 0x1E,
- (byte) 0x05, (byte) 0xC7, (byte) 0x95, (byte) 0x2C, (byte) 0x4F, (byte) 0x14,
- (byte) 0x5F, (byte) 0xEE, (byte) 0x08, (byte) 0x32, (byte) 0xF7, (byte) 0x12,
- (byte) 0x2B, (byte) 0xCD, (byte) 0xF3, (byte) 0x83, (byte) 0x7C, (byte) 0xCE,
- (byte) 0x04, (byte) 0x8A, (byte) 0x36, (byte) 0x3D, (byte) 0xB2, (byte) 0x97,
- (byte) 0x15, (byte) 0xDB, (byte) 0xD6, (byte) 0xFA, (byte) 0x53, (byte) 0x29,
- (byte) 0xD1, (byte) 0x43, (byte) 0x55, (byte) 0xDD, (byte) 0xAE, (byte) 0xA7,
- (byte) 0xB4, (byte) 0x2C, (byte) 0xD9, (byte) 0xA7, (byte) 0x74, (byte) 0xA8,
- (byte) 0x08, (byte) 0xD6, (byte) 0xC2, (byte) 0x05, (byte) 0xBF, (byte) 0x67,
- (byte) 0x3B, (byte) 0xBA, (byte) 0x8D, (byte) 0x99, (byte) 0xC1, (byte) 0x14,
- (byte) 0x1A, (byte) 0x32, (byte) 0xCA, (byte) 0xD5, (byte) 0xCC, (byte) 0xF9,
- (byte) 0x64, (byte) 0x07, (byte) 0x5B, (byte) 0xB8, (byte) 0xA9, (byte) 0x69,
- (byte) 0xED, (byte) 0x01, (byte) 0xCD, (byte) 0xD2, (byte) 0x88, (byte) 0x67,
- (byte) 0xFF, (byte) 0x92, (byte) 0xA3, (byte) 0xC6, (byte) 0x97, (byte) 0x97,
- (byte) 0xA1, (byte) 0xC5, (byte) 0x15, (byte) 0xC8, (byte) 0xB6, (byte) 0xFE,
- (byte) 0x4A, (byte) 0x07, (byte) 0x2E, (byte) 0x46, (byte) 0x3F, (byte) 0x27,
- (byte) 0xB8, (byte) 0xEE, (byte) 0x69, (byte) 0xCB, (byte) 0xDC, (byte) 0x30,
- (byte) 0x19, (byte) 0x77, (byte) 0xC5, (byte) 0xEF,
- };
- private static final PSSParameterSpec SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA-224"), 226, 1);
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha256 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha256 -pkeyopt rsa_pss_saltlen:32 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA256withRSAPSS_Vector2Signature = new byte[] {
- (byte) 0x94, (byte) 0x33, (byte) 0xCB, (byte) 0x9E, (byte) 0x2C, (byte) 0x17,
- (byte) 0x46, (byte) 0xB3, (byte) 0x8F, (byte) 0xB7, (byte) 0x93, (byte) 0x98,
- (byte) 0xA3, (byte) 0x45, (byte) 0xEA, (byte) 0xD4, (byte) 0x51, (byte) 0x60,
- (byte) 0x3E, (byte) 0x00, (byte) 0xA3, (byte) 0x93, (byte) 0x05, (byte) 0x0F,
- (byte) 0xCB, (byte) 0x6E, (byte) 0xFF, (byte) 0xA5, (byte) 0x97, (byte) 0x18,
- (byte) 0xF6, (byte) 0xED, (byte) 0x6B, (byte) 0x6C, (byte) 0xAD, (byte) 0x9C,
- (byte) 0x73, (byte) 0x63, (byte) 0x9C, (byte) 0x5B, (byte) 0xA5, (byte) 0xA1,
- (byte) 0x42, (byte) 0xA3, (byte) 0x0E, (byte) 0x32, (byte) 0xF5, (byte) 0xF0,
- (byte) 0x55, (byte) 0xEE, (byte) 0x58, (byte) 0xC1, (byte) 0xBD, (byte) 0x99,
- (byte) 0x0A, (byte) 0x2B, (byte) 0xFD, (byte) 0xBD, (byte) 0x1E, (byte) 0x23,
- (byte) 0xEF, (byte) 0x99, (byte) 0x7D, (byte) 0xC1, (byte) 0xE2, (byte) 0xD5,
- (byte) 0x71, (byte) 0x6C, (byte) 0x96, (byte) 0x70, (byte) 0xC3, (byte) 0x75,
- (byte) 0x48, (byte) 0x83, (byte) 0x85, (byte) 0x5E, (byte) 0xC6, (byte) 0x3A,
- (byte) 0xFF, (byte) 0xE5, (byte) 0xF1, (byte) 0x6B, (byte) 0x85, (byte) 0x7B,
- (byte) 0x61, (byte) 0xA6, (byte) 0xB1, (byte) 0xCF, (byte) 0x60, (byte) 0x09,
- (byte) 0x32, (byte) 0xAF, (byte) 0xEF, (byte) 0x95, (byte) 0xA4, (byte) 0x1B,
- (byte) 0xD6, (byte) 0xFA, (byte) 0xD0, (byte) 0xD7, (byte) 0x17, (byte) 0xCA,
- (byte) 0xB0, (byte) 0x19, (byte) 0x21, (byte) 0x7F, (byte) 0x5E, (byte) 0x9B,
- (byte) 0xBB, (byte) 0xB8, (byte) 0xE0, (byte) 0xB1, (byte) 0x95, (byte) 0xB3,
- (byte) 0xDA, (byte) 0x0B, (byte) 0xB8, (byte) 0xFA, (byte) 0x15, (byte) 0x75,
- (byte) 0x73, (byte) 0x88, (byte) 0xC8, (byte) 0x45, (byte) 0x33, (byte) 0xD1,
- (byte) 0x5C, (byte) 0xB7, (byte) 0xFB, (byte) 0x38, (byte) 0x05, (byte) 0xA0,
- (byte) 0x85, (byte) 0x99, (byte) 0x2C, (byte) 0xB1, (byte) 0xC2, (byte) 0xFE,
- (byte) 0xAC, (byte) 0x5D, (byte) 0x2C, (byte) 0x1B, (byte) 0xD3, (byte) 0x42,
- (byte) 0x81, (byte) 0xC8, (byte) 0x1C, (byte) 0xB7, (byte) 0x53, (byte) 0x7E,
- (byte) 0xC5, (byte) 0x9F, (byte) 0x84, (byte) 0x97, (byte) 0x6F, (byte) 0x00,
- (byte) 0xC3, (byte) 0x5E, (byte) 0x8B, (byte) 0x67, (byte) 0x3D, (byte) 0x9A,
- (byte) 0xD0, (byte) 0xE2, (byte) 0x9B, (byte) 0x2D, (byte) 0xC6, (byte) 0xD8,
- (byte) 0xEF, (byte) 0x19, (byte) 0x14, (byte) 0x49, (byte) 0x88, (byte) 0x52,
- (byte) 0xF7, (byte) 0x93, (byte) 0xEB, (byte) 0xDB, (byte) 0xB6, (byte) 0x55,
- (byte) 0x05, (byte) 0xB6, (byte) 0xE7, (byte) 0x70, (byte) 0xE4, (byte) 0x5A,
- (byte) 0x9E, (byte) 0x80, (byte) 0x78, (byte) 0x48, (byte) 0xA8, (byte) 0xE5,
- (byte) 0x59, (byte) 0x8D, (byte) 0x1C, (byte) 0x5D, (byte) 0x95, (byte) 0x38,
- (byte) 0x25, (byte) 0xFC, (byte) 0x38, (byte) 0xC3, (byte) 0xFF, (byte) 0xE2,
- (byte) 0x6F, (byte) 0xE4, (byte) 0xFC, (byte) 0x64, (byte) 0x8B, (byte) 0xCA,
- (byte) 0x91, (byte) 0x5F, (byte) 0x0B, (byte) 0x4E, (byte) 0x9A, (byte) 0xB5,
- (byte) 0x22, (byte) 0x5D, (byte) 0xC5, (byte) 0x5A, (byte) 0x77, (byte) 0xED,
- (byte) 0x23, (byte) 0xE0, (byte) 0x13, (byte) 0x8F, (byte) 0xAC, (byte) 0x13,
- (byte) 0xE5, (byte) 0x81, (byte) 0xEE, (byte) 0xD1, (byte) 0xAD, (byte) 0x8A,
- (byte) 0x0F, (byte) 0x2B, (byte) 0x4C, (byte) 0xB2, (byte) 0x13, (byte) 0x54,
- (byte) 0x44, (byte) 0x8E, (byte) 0x53, (byte) 0xE2, (byte) 0x33, (byte) 0x14,
- (byte) 0x7F, (byte) 0x9B, (byte) 0xA9, (byte) 0xD3, (byte) 0xBB, (byte) 0xFC,
- (byte) 0xAC, (byte) 0xC9, (byte) 0x31, (byte) 0xB6,
- };
- private static final PSSParameterSpec SHA256withRSAPSS_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1);
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha256 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha256 -pkeyopt rsa_pss_saltlen:0 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA256withRSAPSS_NoSalt_Vector2Signature = new byte[] {
- (byte) 0x4C, (byte) 0xB7, (byte) 0x33, (byte) 0x78, (byte) 0x0A, (byte) 0xA7,
- (byte) 0xEB, (byte) 0x35, (byte) 0x5E, (byte) 0x99, (byte) 0x8F, (byte) 0xE9,
- (byte) 0x2A, (byte) 0x3D, (byte) 0x8C, (byte) 0x9B, (byte) 0x19, (byte) 0xC7,
- (byte) 0xC8, (byte) 0xB8, (byte) 0x10, (byte) 0xC5, (byte) 0x6D, (byte) 0xA4,
- (byte) 0x44, (byte) 0x3E, (byte) 0xAB, (byte) 0x90, (byte) 0x82, (byte) 0x70,
- (byte) 0xFA, (byte) 0x7B, (byte) 0xE6, (byte) 0x06, (byte) 0x36, (byte) 0x06,
- (byte) 0x93, (byte) 0x54, (byte) 0x50, (byte) 0xCD, (byte) 0x5F, (byte) 0xAA,
- (byte) 0x01, (byte) 0x42, (byte) 0xAD, (byte) 0xB9, (byte) 0x02, (byte) 0x6E,
- (byte) 0xAE, (byte) 0x60, (byte) 0x00, (byte) 0x60, (byte) 0x55, (byte) 0x1B,
- (byte) 0xBB, (byte) 0x9E, (byte) 0x03, (byte) 0xB7, (byte) 0x86, (byte) 0x3D,
- (byte) 0xCC, (byte) 0xFA, (byte) 0x6E, (byte) 0x20, (byte) 0x07, (byte) 0x61,
- (byte) 0x8F, (byte) 0x53, (byte) 0xC6, (byte) 0x2B, (byte) 0xEF, (byte) 0x8F,
- (byte) 0x0F, (byte) 0x8B, (byte) 0x80, (byte) 0x22, (byte) 0xDC, (byte) 0x9E,
- (byte) 0x20, (byte) 0x4A, (byte) 0x57, (byte) 0xA1, (byte) 0x15, (byte) 0xE0,
- (byte) 0x01, (byte) 0x95, (byte) 0xDB, (byte) 0x46, (byte) 0x85, (byte) 0x6D,
- (byte) 0x27, (byte) 0x9F, (byte) 0x44, (byte) 0x3B, (byte) 0xB1, (byte) 0x35,
- (byte) 0x04, (byte) 0x9D, (byte) 0xF8, (byte) 0xC6, (byte) 0xD7, (byte) 0xD7,
- (byte) 0xEF, (byte) 0x9A, (byte) 0x53, (byte) 0x5A, (byte) 0x73, (byte) 0xB3,
- (byte) 0xD0, (byte) 0x32, (byte) 0x39, (byte) 0xE1, (byte) 0x28, (byte) 0x3A,
- (byte) 0x9D, (byte) 0x69, (byte) 0x4E, (byte) 0x57, (byte) 0xC1, (byte) 0xDF,
- (byte) 0xFE, (byte) 0x5F, (byte) 0xA8, (byte) 0xFF, (byte) 0xE8, (byte) 0x75,
- (byte) 0x85, (byte) 0x33, (byte) 0x90, (byte) 0x83, (byte) 0x3D, (byte) 0x8F,
- (byte) 0x15, (byte) 0x47, (byte) 0x16, (byte) 0xF2, (byte) 0x32, (byte) 0xF9,
- (byte) 0x46, (byte) 0x96, (byte) 0xCC, (byte) 0x2E, (byte) 0x8F, (byte) 0x27,
- (byte) 0x3F, (byte) 0xCF, (byte) 0x91, (byte) 0xA6, (byte) 0x9E, (byte) 0xBF,
- (byte) 0x42, (byte) 0x2F, (byte) 0xD6, (byte) 0x52, (byte) 0xD7, (byte) 0x3B,
- (byte) 0xCD, (byte) 0xFE, (byte) 0x0B, (byte) 0x4A, (byte) 0x3B, (byte) 0x19,
- (byte) 0x57, (byte) 0x47, (byte) 0x65, (byte) 0x33, (byte) 0xD9, (byte) 0xF7,
- (byte) 0xE4, (byte) 0xC3, (byte) 0x05, (byte) 0x49, (byte) 0x3C, (byte) 0xC0,
- (byte) 0xDF, (byte) 0xC1, (byte) 0x54, (byte) 0x18, (byte) 0x8D, (byte) 0xDA,
- (byte) 0xE4, (byte) 0x59, (byte) 0xE9, (byte) 0x3B, (byte) 0xD6, (byte) 0x89,
- (byte) 0x07, (byte) 0x99, (byte) 0xB0, (byte) 0xF4, (byte) 0x09, (byte) 0x0A,
- (byte) 0x2C, (byte) 0xBA, (byte) 0x0B, (byte) 0xE4, (byte) 0x79, (byte) 0xB1,
- (byte) 0xDB, (byte) 0xAD, (byte) 0xAB, (byte) 0x5D, (byte) 0xA2, (byte) 0x1E,
- (byte) 0x76, (byte) 0x7F, (byte) 0x74, (byte) 0x62, (byte) 0x49, (byte) 0x07,
- (byte) 0x7A, (byte) 0x5B, (byte) 0xD7, (byte) 0x0F, (byte) 0xA4, (byte) 0x2C,
- (byte) 0x36, (byte) 0x13, (byte) 0x42, (byte) 0xBA, (byte) 0xCF, (byte) 0x0A,
- (byte) 0xFC, (byte) 0xC3, (byte) 0x31, (byte) 0x5E, (byte) 0x06, (byte) 0x84,
- (byte) 0x8A, (byte) 0x8A, (byte) 0x84, (byte) 0x0D, (byte) 0x48, (byte) 0xBD,
- (byte) 0x67, (byte) 0xCF, (byte) 0x04, (byte) 0xB4, (byte) 0xFB, (byte) 0xBB,
- (byte) 0x04, (byte) 0x91, (byte) 0xB1, (byte) 0x0A, (byte) 0xA4, (byte) 0x70,
- (byte) 0x58, (byte) 0x1A, (byte) 0x9B, (byte) 0x02, (byte) 0x86, (byte) 0xBD,
- (byte) 0xAE, (byte) 0x77, (byte) 0x97, (byte) 0x1C,
- };
- private static final PSSParameterSpec SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 0, 1);
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha256 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha256 -pkeyopt rsa_pss_saltlen:222 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA256withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
- (byte) 0x3B, (byte) 0x43, (byte) 0xA8, (byte) 0xB5, (byte) 0x34, (byte) 0xD8,
- (byte) 0xF9, (byte) 0xAD, (byte) 0xDD, (byte) 0x1F, (byte) 0x7A, (byte) 0x73,
- (byte) 0xBF, (byte) 0xFA, (byte) 0xED, (byte) 0x10, (byte) 0xF3, (byte) 0x16,
- (byte) 0xCC, (byte) 0xE5, (byte) 0x09, (byte) 0x0F, (byte) 0x68, (byte) 0x02,
- (byte) 0xE7, (byte) 0x55, (byte) 0x0D, (byte) 0xCF, (byte) 0x1B, (byte) 0x83,
- (byte) 0xCD, (byte) 0xA2, (byte) 0xD6, (byte) 0x02, (byte) 0xDD, (byte) 0x72,
- (byte) 0xA6, (byte) 0x5F, (byte) 0x05, (byte) 0x8A, (byte) 0x1E, (byte) 0xA1,
- (byte) 0x4F, (byte) 0x92, (byte) 0xD9, (byte) 0x09, (byte) 0x19, (byte) 0x6E,
- (byte) 0x80, (byte) 0xA0, (byte) 0x47, (byte) 0x98, (byte) 0x5C, (byte) 0xF7,
- (byte) 0x34, (byte) 0x52, (byte) 0x7D, (byte) 0x85, (byte) 0xCF, (byte) 0x9F,
- (byte) 0xEB, (byte) 0xAF, (byte) 0xB4, (byte) 0x53, (byte) 0xF0, (byte) 0x5D,
- (byte) 0x28, (byte) 0x87, (byte) 0xAC, (byte) 0xA7, (byte) 0xB4, (byte) 0xCF,
- (byte) 0xDD, (byte) 0x8B, (byte) 0xA4, (byte) 0xC9, (byte) 0xCA, (byte) 0xAA,
- (byte) 0xF4, (byte) 0xA8, (byte) 0x25, (byte) 0x26, (byte) 0x34, (byte) 0x11,
- (byte) 0x14, (byte) 0x24, (byte) 0x1C, (byte) 0x1C, (byte) 0x50, (byte) 0xC8,
- (byte) 0xFF, (byte) 0x7E, (byte) 0xFF, (byte) 0x6F, (byte) 0x4F, (byte) 0x14,
- (byte) 0xB3, (byte) 0x57, (byte) 0x48, (byte) 0x0A, (byte) 0x5A, (byte) 0x95,
- (byte) 0x5D, (byte) 0xEB, (byte) 0x71, (byte) 0x4E, (byte) 0x86, (byte) 0xFC,
- (byte) 0x38, (byte) 0x1B, (byte) 0x93, (byte) 0x45, (byte) 0x09, (byte) 0x15,
- (byte) 0xD3, (byte) 0x06, (byte) 0x6B, (byte) 0x9D, (byte) 0x05, (byte) 0x5C,
- (byte) 0x4A, (byte) 0xB3, (byte) 0x93, (byte) 0xD1, (byte) 0x01, (byte) 0x54,
- (byte) 0xCC, (byte) 0xED, (byte) 0xBF, (byte) 0x0E, (byte) 0x7E, (byte) 0x33,
- (byte) 0x32, (byte) 0xA6, (byte) 0xA5, (byte) 0xF7, (byte) 0x3D, (byte) 0x2E,
- (byte) 0xCB, (byte) 0x76, (byte) 0xA7, (byte) 0x22, (byte) 0x64, (byte) 0xB8,
- (byte) 0x19, (byte) 0x53, (byte) 0xFE, (byte) 0x8C, (byte) 0xC8, (byte) 0x1E,
- (byte) 0x6C, (byte) 0xEE, (byte) 0x08, (byte) 0x07, (byte) 0x7E, (byte) 0x93,
- (byte) 0x43, (byte) 0x1B, (byte) 0xCF, (byte) 0x37, (byte) 0xE4, (byte) 0xAB,
- (byte) 0xE7, (byte) 0xD7, (byte) 0x83, (byte) 0x8E, (byte) 0x19, (byte) 0xAE,
- (byte) 0x05, (byte) 0x51, (byte) 0x91, (byte) 0x10, (byte) 0x7B, (byte) 0x70,
- (byte) 0xFC, (byte) 0x73, (byte) 0x12, (byte) 0x96, (byte) 0xFA, (byte) 0xD0,
- (byte) 0xCA, (byte) 0xA3, (byte) 0x59, (byte) 0xA7, (byte) 0xDD, (byte) 0xC3,
- (byte) 0x1D, (byte) 0x9C, (byte) 0x7B, (byte) 0x50, (byte) 0xBB, (byte) 0x57,
- (byte) 0xB8, (byte) 0x86, (byte) 0xF2, (byte) 0xCA, (byte) 0xC4, (byte) 0x86,
- (byte) 0x7A, (byte) 0x96, (byte) 0x90, (byte) 0x02, (byte) 0xDF, (byte) 0xA0,
- (byte) 0x88, (byte) 0x0E, (byte) 0x89, (byte) 0x45, (byte) 0x27, (byte) 0x52,
- (byte) 0xDA, (byte) 0x86, (byte) 0x42, (byte) 0x4B, (byte) 0x90, (byte) 0xC3,
- (byte) 0xC1, (byte) 0x41, (byte) 0x60, (byte) 0x5C, (byte) 0x29, (byte) 0x15,
- (byte) 0xE5, (byte) 0x5C, (byte) 0x43, (byte) 0x9B, (byte) 0x40, (byte) 0xE5,
- (byte) 0x04, (byte) 0x1B, (byte) 0x4A, (byte) 0x93, (byte) 0xDD, (byte) 0x55,
- (byte) 0xC4, (byte) 0xFC, (byte) 0xFE, (byte) 0x0C, (byte) 0x65, (byte) 0x96,
- (byte) 0x98, (byte) 0xDE, (byte) 0xC5, (byte) 0x05, (byte) 0xC5, (byte) 0x3E,
- (byte) 0xB0, (byte) 0x25, (byte) 0x4E, (byte) 0x65, (byte) 0x24, (byte) 0x8D,
- (byte) 0x4E, (byte) 0x9D, (byte) 0x94, (byte) 0x01,
- };
- private static final PSSParameterSpec SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 222, 1);
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha384 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha384 -pkeyopt rsa_pss_saltlen:48 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA384withRSAPSS_Vector2Signature = new byte[] {
- (byte) 0x20, (byte) 0xCB, (byte) 0x97, (byte) 0x9C, (byte) 0x2E, (byte) 0x51,
- (byte) 0x59, (byte) 0x56, (byte) 0x9F, (byte) 0x04, (byte) 0x47, (byte) 0x7C,
- (byte) 0x5C, (byte) 0x57, (byte) 0x59, (byte) 0xBC, (byte) 0x43, (byte) 0xD9,
- (byte) 0x4B, (byte) 0xEC, (byte) 0xAC, (byte) 0xB9, (byte) 0x88, (byte) 0xA2,
- (byte) 0x30, (byte) 0x8B, (byte) 0xEE, (byte) 0x2F, (byte) 0xC1, (byte) 0x73,
- (byte) 0xF1, (byte) 0x13, (byte) 0xB2, (byte) 0x5E, (byte) 0x1A, (byte) 0xC8,
- (byte) 0xD2, (byte) 0xAA, (byte) 0x27, (byte) 0x16, (byte) 0xA1, (byte) 0x14,
- (byte) 0xAB, (byte) 0x45, (byte) 0x8A, (byte) 0x7E, (byte) 0x22, (byte) 0x22,
- (byte) 0x2A, (byte) 0x2E, (byte) 0xDA, (byte) 0x6A, (byte) 0x7E, (byte) 0x3F,
- (byte) 0x66, (byte) 0x99, (byte) 0x55, (byte) 0xAF, (byte) 0x2B, (byte) 0x94,
- (byte) 0xD8, (byte) 0x6B, (byte) 0xC2, (byte) 0x60, (byte) 0xB5, (byte) 0x55,
- (byte) 0xA9, (byte) 0x26, (byte) 0x29, (byte) 0xFC, (byte) 0x17, (byte) 0x56,
- (byte) 0x05, (byte) 0xB7, (byte) 0x48, (byte) 0x2F, (byte) 0xAB, (byte) 0x68,
- (byte) 0xCF, (byte) 0x37, (byte) 0x62, (byte) 0x79, (byte) 0x4F, (byte) 0x32,
- (byte) 0x04, (byte) 0xF6, (byte) 0xEA, (byte) 0xBE, (byte) 0x79, (byte) 0x84,
- (byte) 0x73, (byte) 0xEE, (byte) 0x1C, (byte) 0xEE, (byte) 0x9F, (byte) 0x72,
- (byte) 0x7A, (byte) 0xC6, (byte) 0x64, (byte) 0xB4, (byte) 0x4F, (byte) 0xDE,
- (byte) 0x0B, (byte) 0x38, (byte) 0x47, (byte) 0x62, (byte) 0xA9, (byte) 0xFD,
- (byte) 0x1B, (byte) 0x75, (byte) 0xEC, (byte) 0xFE, (byte) 0x2D, (byte) 0x04,
- (byte) 0x2D, (byte) 0x0A, (byte) 0xCE, (byte) 0x13, (byte) 0xFA, (byte) 0xDA,
- (byte) 0x3F, (byte) 0x4C, (byte) 0x11, (byte) 0xEA, (byte) 0x02, (byte) 0x00,
- (byte) 0x0A, (byte) 0x93, (byte) 0x12, (byte) 0xDC, (byte) 0x60, (byte) 0xE7,
- (byte) 0x52, (byte) 0x90, (byte) 0x8A, (byte) 0xA3, (byte) 0xAE, (byte) 0xC5,
- (byte) 0x9A, (byte) 0xD7, (byte) 0xD5, (byte) 0x0D, (byte) 0xBC, (byte) 0x7A,
- (byte) 0xDB, (byte) 0xF4, (byte) 0x10, (byte) 0xE0, (byte) 0xDB, (byte) 0xC0,
- (byte) 0x97, (byte) 0xF1, (byte) 0x84, (byte) 0xCF, (byte) 0x66, (byte) 0xB2,
- (byte) 0x04, (byte) 0x58, (byte) 0x81, (byte) 0xB5, (byte) 0x9B, (byte) 0x4A,
- (byte) 0xF9, (byte) 0xD7, (byte) 0xCA, (byte) 0x51, (byte) 0x09, (byte) 0x67,
- (byte) 0x48, (byte) 0x7B, (byte) 0xE5, (byte) 0xE9, (byte) 0x07, (byte) 0x4E,
- (byte) 0x6A, (byte) 0xC1, (byte) 0xA6, (byte) 0x68, (byte) 0x90, (byte) 0x17,
- (byte) 0xAB, (byte) 0x0E, (byte) 0xFB, (byte) 0x3E, (byte) 0x39, (byte) 0x74,
- (byte) 0x85, (byte) 0x04, (byte) 0x42, (byte) 0x0A, (byte) 0x9E, (byte) 0x02,
- (byte) 0xA9, (byte) 0x50, (byte) 0xFF, (byte) 0x23, (byte) 0x2D, (byte) 0x30,
- (byte) 0xDD, (byte) 0x17, (byte) 0xC0, (byte) 0x82, (byte) 0xF7, (byte) 0xBB,
- (byte) 0x3B, (byte) 0x03, (byte) 0xBD, (byte) 0xB1, (byte) 0x96, (byte) 0xCD,
- (byte) 0x71, (byte) 0x3F, (byte) 0x67, (byte) 0x59, (byte) 0x5E, (byte) 0x45,
- (byte) 0xE0, (byte) 0x1C, (byte) 0x80, (byte) 0x52, (byte) 0xD7, (byte) 0xF0,
- (byte) 0xC1, (byte) 0xE6, (byte) 0xCF, (byte) 0x59, (byte) 0x13, (byte) 0x25,
- (byte) 0x6F, (byte) 0x9F, (byte) 0xBB, (byte) 0xB9, (byte) 0x7F, (byte) 0x7E,
- (byte) 0x7D, (byte) 0x93, (byte) 0xD9, (byte) 0x3F, (byte) 0x95, (byte) 0xB7,
- (byte) 0x9A, (byte) 0xDB, (byte) 0xE2, (byte) 0x2C, (byte) 0x53, (byte) 0x83,
- (byte) 0x9A, (byte) 0x06, (byte) 0x6D, (byte) 0x22, (byte) 0x81, (byte) 0xB5,
- (byte) 0x63, (byte) 0xAE, (byte) 0x4A, (byte) 0xEE,
- };
- private static final PSSParameterSpec SHA384withRSAPSS_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384, 48, 1);
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha384 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha384 -pkeyopt rsa_pss_saltlen:0 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA384withRSAPSS_NoSalt_Vector2Signature = new byte[] {
- (byte) 0x41, (byte) 0x0C, (byte) 0x3A, (byte) 0xEC, (byte) 0xF6, (byte) 0xD9,
- (byte) 0x8F, (byte) 0xA3, (byte) 0x61, (byte) 0xBB, (byte) 0x03, (byte) 0xED,
- (byte) 0xD9, (byte) 0x69, (byte) 0x7D, (byte) 0xE1, (byte) 0xE1, (byte) 0x4E,
- (byte) 0x5E, (byte) 0x71, (byte) 0x4E, (byte) 0x88, (byte) 0x9C, (byte) 0x79,
- (byte) 0xD3, (byte) 0x71, (byte) 0x28, (byte) 0x07, (byte) 0x28, (byte) 0x19,
- (byte) 0x96, (byte) 0x55, (byte) 0x30, (byte) 0x81, (byte) 0x29, (byte) 0x5C,
- (byte) 0x4A, (byte) 0x18, (byte) 0x69, (byte) 0x36, (byte) 0x74, (byte) 0xAC,
- (byte) 0x99, (byte) 0xB1, (byte) 0xBC, (byte) 0xA0, (byte) 0xFC, (byte) 0x17,
- (byte) 0xA4, (byte) 0xD1, (byte) 0xAE, (byte) 0x84, (byte) 0xA6, (byte) 0x09,
- (byte) 0x6B, (byte) 0xB3, (byte) 0x02, (byte) 0xB2, (byte) 0x81, (byte) 0x04,
- (byte) 0x59, (byte) 0x8C, (byte) 0xCF, (byte) 0xAD, (byte) 0xFB, (byte) 0x76,
- (byte) 0x6F, (byte) 0xE2, (byte) 0x5E, (byte) 0x09, (byte) 0xE5, (byte) 0xBC,
- (byte) 0x54, (byte) 0xBD, (byte) 0x08, (byte) 0xA8, (byte) 0x18, (byte) 0x60,
- (byte) 0xAF, (byte) 0x09, (byte) 0x67, (byte) 0x15, (byte) 0x03, (byte) 0xA8,
- (byte) 0x8B, (byte) 0x3F, (byte) 0x31, (byte) 0xB7, (byte) 0x76, (byte) 0xFD,
- (byte) 0xF6, (byte) 0x82, (byte) 0xC7, (byte) 0x89, (byte) 0xC2, (byte) 0x47,
- (byte) 0x80, (byte) 0x06, (byte) 0x4F, (byte) 0x8C, (byte) 0x9C, (byte) 0xD7,
- (byte) 0x4F, (byte) 0x63, (byte) 0x1E, (byte) 0xF0, (byte) 0x34, (byte) 0xD7,
- (byte) 0x91, (byte) 0xD2, (byte) 0x96, (byte) 0x62, (byte) 0xFD, (byte) 0x68,
- (byte) 0xE3, (byte) 0xE0, (byte) 0xFB, (byte) 0x7D, (byte) 0x0A, (byte) 0xD7,
- (byte) 0x52, (byte) 0xFE, (byte) 0xD1, (byte) 0x95, (byte) 0x9E, (byte) 0xD2,
- (byte) 0x84, (byte) 0xBE, (byte) 0x3D, (byte) 0x1F, (byte) 0x8C, (byte) 0xC4,
- (byte) 0xD6, (byte) 0xE3, (byte) 0xCF, (byte) 0xE8, (byte) 0xB3, (byte) 0x82,
- (byte) 0x2E, (byte) 0xFA, (byte) 0x39, (byte) 0xA3, (byte) 0x20, (byte) 0x3C,
- (byte) 0xBE, (byte) 0x6A, (byte) 0xFA, (byte) 0x04, (byte) 0xD2, (byte) 0x74,
- (byte) 0x41, (byte) 0xDC, (byte) 0xE8, (byte) 0x0E, (byte) 0xE7, (byte) 0xF2,
- (byte) 0x36, (byte) 0xD4, (byte) 0x2E, (byte) 0x6A, (byte) 0xCF, (byte) 0xDF,
- (byte) 0x8B, (byte) 0x4B, (byte) 0x77, (byte) 0xE8, (byte) 0x0A, (byte) 0x64,
- (byte) 0x86, (byte) 0x2C, (byte) 0xCA, (byte) 0x92, (byte) 0x01, (byte) 0xB2,
- (byte) 0x8A, (byte) 0xB8, (byte) 0xB2, (byte) 0x6C, (byte) 0x0B, (byte) 0x18,
- (byte) 0x90, (byte) 0x31, (byte) 0x93, (byte) 0x29, (byte) 0xBA, (byte) 0xB1,
- (byte) 0x88, (byte) 0x94, (byte) 0x44, (byte) 0x0B, (byte) 0x38, (byte) 0x64,
- (byte) 0xC1, (byte) 0xDE, (byte) 0x0B, (byte) 0xD8, (byte) 0xE4, (byte) 0xBA,
- (byte) 0x0A, (byte) 0x41, (byte) 0x24, (byte) 0x35, (byte) 0xAA, (byte) 0xE3,
- (byte) 0x59, (byte) 0x8E, (byte) 0x57, (byte) 0x51, (byte) 0x43, (byte) 0xE1,
- (byte) 0x9C, (byte) 0xF6, (byte) 0xF8, (byte) 0x16, (byte) 0x68, (byte) 0x83,
- (byte) 0x08, (byte) 0x8C, (byte) 0x2D, (byte) 0x40, (byte) 0xD2, (byte) 0xEF,
- (byte) 0xD6, (byte) 0xAE, (byte) 0x98, (byte) 0x77, (byte) 0xE8, (byte) 0xF2,
- (byte) 0xC7, (byte) 0x19, (byte) 0x61, (byte) 0xD6, (byte) 0x43, (byte) 0xCD,
- (byte) 0x76, (byte) 0x2E, (byte) 0x7A, (byte) 0xCB, (byte) 0x1A, (byte) 0x5D,
- (byte) 0x73, (byte) 0x45, (byte) 0xF2, (byte) 0x7C, (byte) 0xD0, (byte) 0x88,
- (byte) 0x83, (byte) 0x51, (byte) 0xF3, (byte) 0x19, (byte) 0x0F, (byte) 0xD5,
- (byte) 0x40, (byte) 0x3F, (byte) 0xD9, (byte) 0xBF,
- };
- private static final PSSParameterSpec SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384, 0, 1);
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha384 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha384 -pkeyopt rsa_pss_saltlen:206 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA384withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
- (byte) 0xDE, (byte) 0xF7, (byte) 0xC3, (byte) 0x21, (byte) 0x79, (byte) 0x0F,
- (byte) 0x55, (byte) 0xD1, (byte) 0x56, (byte) 0x9A, (byte) 0xB0, (byte) 0x08,
- (byte) 0xA1, (byte) 0x27, (byte) 0xC9, (byte) 0x5E, (byte) 0x64, (byte) 0xF4,
- (byte) 0xC7, (byte) 0x83, (byte) 0x94, (byte) 0xCA, (byte) 0xBD, (byte) 0x50,
- (byte) 0xD6, (byte) 0xC5, (byte) 0x56, (byte) 0x94, (byte) 0xBD, (byte) 0x0B,
- (byte) 0x55, (byte) 0xE6, (byte) 0x04, (byte) 0xAD, (byte) 0xAF, (byte) 0xAF,
- (byte) 0x4F, (byte) 0x2D, (byte) 0x91, (byte) 0x7F, (byte) 0xF1, (byte) 0x60,
- (byte) 0x0C, (byte) 0xEE, (byte) 0xE8, (byte) 0x44, (byte) 0xFC, (byte) 0x69,
- (byte) 0x80, (byte) 0x43, (byte) 0xBC, (byte) 0xAB, (byte) 0x83, (byte) 0x35,
- (byte) 0xB0, (byte) 0xC6, (byte) 0xCB, (byte) 0xE6, (byte) 0x92, (byte) 0x29,
- (byte) 0x09, (byte) 0xCF, (byte) 0xDB, (byte) 0xAD, (byte) 0x16, (byte) 0x93,
- (byte) 0xC7, (byte) 0xBE, (byte) 0x81, (byte) 0x68, (byte) 0x0F, (byte) 0x7B,
- (byte) 0xC1, (byte) 0xC2, (byte) 0x8C, (byte) 0xBA, (byte) 0x59, (byte) 0x80,
- (byte) 0xAE, (byte) 0xFB, (byte) 0x60, (byte) 0x22, (byte) 0x28, (byte) 0x36,
- (byte) 0xBE, (byte) 0x37, (byte) 0x72, (byte) 0x86, (byte) 0x02, (byte) 0x4B,
- (byte) 0xF9, (byte) 0x14, (byte) 0x5A, (byte) 0x6B, (byte) 0x32, (byte) 0x44,
- (byte) 0x72, (byte) 0x33, (byte) 0x2E, (byte) 0x7F, (byte) 0xA1, (byte) 0xFD,
- (byte) 0x07, (byte) 0xF2, (byte) 0xD9, (byte) 0x9D, (byte) 0x03, (byte) 0x77,
- (byte) 0x17, (byte) 0xFB, (byte) 0x0E, (byte) 0xFF, (byte) 0xF7, (byte) 0x37,
- (byte) 0x68, (byte) 0xF6, (byte) 0x8F, (byte) 0x9B, (byte) 0x2C, (byte) 0xEB,
- (byte) 0xAF, (byte) 0x6C, (byte) 0x50, (byte) 0x9F, (byte) 0x34, (byte) 0xB2,
- (byte) 0x52, (byte) 0x3B, (byte) 0x94, (byte) 0x6F, (byte) 0x60, (byte) 0x16,
- (byte) 0x52, (byte) 0x0A, (byte) 0xBF, (byte) 0x95, (byte) 0x41, (byte) 0x44,
- (byte) 0x83, (byte) 0x91, (byte) 0x85, (byte) 0xA1, (byte) 0xF7, (byte) 0xF9,
- (byte) 0x17, (byte) 0x4A, (byte) 0xF7, (byte) 0xF1, (byte) 0xE8, (byte) 0x9C,
- (byte) 0x75, (byte) 0x86, (byte) 0x12, (byte) 0x44, (byte) 0x19, (byte) 0x5C,
- (byte) 0x65, (byte) 0x31, (byte) 0x89, (byte) 0x2A, (byte) 0xFC, (byte) 0xBE,
- (byte) 0xE8, (byte) 0xEC, (byte) 0xC9, (byte) 0xD7, (byte) 0x41, (byte) 0xDA,
- (byte) 0xD9, (byte) 0xC9, (byte) 0x8B, (byte) 0x90, (byte) 0x60, (byte) 0xCC,
- (byte) 0xB2, (byte) 0x7A, (byte) 0xBA, (byte) 0xA0, (byte) 0xEE, (byte) 0xBE,
- (byte) 0x9C, (byte) 0xE7, (byte) 0xF2, (byte) 0x27, (byte) 0x92, (byte) 0x9C,
- (byte) 0x3C, (byte) 0x0F, (byte) 0x5C, (byte) 0xEE, (byte) 0x38, (byte) 0x48,
- (byte) 0xCF, (byte) 0xFF, (byte) 0x33, (byte) 0x35, (byte) 0x80, (byte) 0x99,
- (byte) 0x5D, (byte) 0xA7, (byte) 0x5A, (byte) 0x7A, (byte) 0xEA, (byte) 0x96,
- (byte) 0x74, (byte) 0x28, (byte) 0x36, (byte) 0x7B, (byte) 0xE1, (byte) 0x33,
- (byte) 0x7C, (byte) 0x78, (byte) 0xEC, (byte) 0x05, (byte) 0x72, (byte) 0x0E,
- (byte) 0x5D, (byte) 0x16, (byte) 0x5C, (byte) 0x77, (byte) 0x58, (byte) 0xA7,
- (byte) 0x31, (byte) 0x3F, (byte) 0xBA, (byte) 0x91, (byte) 0xA7, (byte) 0x16,
- (byte) 0xFC, (byte) 0x31, (byte) 0xCA, (byte) 0x30, (byte) 0xE0, (byte) 0xF4,
- (byte) 0x5D, (byte) 0x07, (byte) 0x4A, (byte) 0x9C, (byte) 0x1D, (byte) 0x2B,
- (byte) 0x4E, (byte) 0xB8, (byte) 0x7C, (byte) 0x67, (byte) 0xCB, (byte) 0x34,
- (byte) 0x69, (byte) 0x85, (byte) 0x4E, (byte) 0x99, (byte) 0x41, (byte) 0x8A,
- (byte) 0x35, (byte) 0x85, (byte) 0xF2, (byte) 0x1A,
- };
- private static final PSSParameterSpec SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384, 206, 1);
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha512 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha512 -pkeyopt rsa_pss_saltlen:64 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA512withRSAPSS_Vector2Signature = new byte[] {
- (byte) 0x9F, (byte) 0xED, (byte) 0xF8, (byte) 0xEE, (byte) 0x30, (byte) 0x5F,
- (byte) 0x30, (byte) 0x63, (byte) 0x1D, (byte) 0x86, (byte) 0xD3, (byte) 0xAD,
- (byte) 0x1D, (byte) 0xD8, (byte) 0xD2, (byte) 0x67, (byte) 0xE2, (byte) 0x43,
- (byte) 0x64, (byte) 0x71, (byte) 0x98, (byte) 0x82, (byte) 0x00, (byte) 0x84,
- (byte) 0x2C, (byte) 0x88, (byte) 0x1A, (byte) 0x28, (byte) 0xCD, (byte) 0xA2,
- (byte) 0x34, (byte) 0x17, (byte) 0x0F, (byte) 0x34, (byte) 0x8A, (byte) 0x10,
- (byte) 0x79, (byte) 0x6C, (byte) 0xCB, (byte) 0xDA, (byte) 0x2F, (byte) 0xDF,
- (byte) 0x4D, (byte) 0x98, (byte) 0x01, (byte) 0xE8, (byte) 0xB3, (byte) 0xF5,
- (byte) 0xCD, (byte) 0x60, (byte) 0xEA, (byte) 0xDE, (byte) 0xA5, (byte) 0x0C,
- (byte) 0x09, (byte) 0xA1, (byte) 0x4A, (byte) 0xC4, (byte) 0x6B, (byte) 0x09,
- (byte) 0xB3, (byte) 0x37, (byte) 0x1F, (byte) 0x8A, (byte) 0x64, (byte) 0x81,
- (byte) 0x2E, (byte) 0x22, (byte) 0x75, (byte) 0x24, (byte) 0x3B, (byte) 0xC0,
- (byte) 0x0E, (byte) 0x1F, (byte) 0x37, (byte) 0xC9, (byte) 0x1E, (byte) 0x6F,
- (byte) 0xAF, (byte) 0x3E, (byte) 0x9B, (byte) 0x3F, (byte) 0xA3, (byte) 0xC3,
- (byte) 0x0B, (byte) 0xB9, (byte) 0x83, (byte) 0x60, (byte) 0x02, (byte) 0xC6,
- (byte) 0x29, (byte) 0x83, (byte) 0x09, (byte) 0x16, (byte) 0xD9, (byte) 0x3D,
- (byte) 0x84, (byte) 0x02, (byte) 0x81, (byte) 0x20, (byte) 0xE9, (byte) 0x01,
- (byte) 0x5B, (byte) 0x85, (byte) 0xC8, (byte) 0x81, (byte) 0x25, (byte) 0x6B,
- (byte) 0xCB, (byte) 0x78, (byte) 0x48, (byte) 0x65, (byte) 0x3A, (byte) 0xD6,
- (byte) 0x95, (byte) 0x9B, (byte) 0x62, (byte) 0x2D, (byte) 0x84, (byte) 0x54,
- (byte) 0x12, (byte) 0x94, (byte) 0xB7, (byte) 0xF0, (byte) 0x1C, (byte) 0xB6,
- (byte) 0x59, (byte) 0xCD, (byte) 0xC3, (byte) 0x86, (byte) 0xE6, (byte) 0x63,
- (byte) 0xD7, (byte) 0x99, (byte) 0x9A, (byte) 0xC4, (byte) 0xBF, (byte) 0x8E,
- (byte) 0xDD, (byte) 0x46, (byte) 0x10, (byte) 0xBE, (byte) 0xAB, (byte) 0x78,
- (byte) 0xC6, (byte) 0x30, (byte) 0x47, (byte) 0x23, (byte) 0xB6, (byte) 0x2C,
- (byte) 0x02, (byte) 0x5E, (byte) 0x1F, (byte) 0x07, (byte) 0x96, (byte) 0x54,
- (byte) 0xEE, (byte) 0x28, (byte) 0xC7, (byte) 0xEC, (byte) 0x57, (byte) 0xDB,
- (byte) 0x9E, (byte) 0xEF, (byte) 0xE4, (byte) 0x11, (byte) 0xF8, (byte) 0x04,
- (byte) 0xA9, (byte) 0x26, (byte) 0xC2, (byte) 0x61, (byte) 0xF1, (byte) 0x84,
- (byte) 0xEB, (byte) 0x94, (byte) 0xBD, (byte) 0x48, (byte) 0xCA, (byte) 0xD1,
- (byte) 0x84, (byte) 0xCE, (byte) 0x82, (byte) 0x2E, (byte) 0xF6, (byte) 0x4E,
- (byte) 0x17, (byte) 0x6F, (byte) 0x78, (byte) 0xB9, (byte) 0x0B, (byte) 0xA9,
- (byte) 0x7D, (byte) 0xBC, (byte) 0xE5, (byte) 0xF8, (byte) 0x7D, (byte) 0xA8,
- (byte) 0x76, (byte) 0x7A, (byte) 0x8B, (byte) 0xB5, (byte) 0x05, (byte) 0x42,
- (byte) 0x37, (byte) 0xDA, (byte) 0x15, (byte) 0xE2, (byte) 0xC4, (byte) 0x70,
- (byte) 0x6E, (byte) 0x95, (byte) 0x60, (byte) 0x47, (byte) 0xF9, (byte) 0x0F,
- (byte) 0xF4, (byte) 0xA2, (byte) 0x73, (byte) 0xF1, (byte) 0x73, (byte) 0xBD,
- (byte) 0x0B, (byte) 0x9B, (byte) 0x44, (byte) 0xB6, (byte) 0xA9, (byte) 0xAF,
- (byte) 0x50, (byte) 0x2D, (byte) 0x5C, (byte) 0xA3, (byte) 0x72, (byte) 0x6F,
- (byte) 0x85, (byte) 0xE8, (byte) 0x0C, (byte) 0xF9, (byte) 0xE1, (byte) 0xE8,
- (byte) 0xF7, (byte) 0xC0, (byte) 0x85, (byte) 0x14, (byte) 0x53, (byte) 0x95,
- (byte) 0xF9, (byte) 0x9E, (byte) 0x65, (byte) 0x05, (byte) 0xF0, (byte) 0x22,
- (byte) 0x7F, (byte) 0x4F, (byte) 0x40, (byte) 0x45,
- };
- private static final PSSParameterSpec SHA512withRSAPSS_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 64, 1);
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha512 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha512 -pkeyopt rsa_pss_saltlen:64 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA512withRSAPSS_NoSalt_Vector2Signature = new byte[] {
- (byte) 0x49, (byte) 0xA3, (byte) 0xBC, (byte) 0x2E, (byte) 0x67, (byte) 0x96,
- (byte) 0xA5, (byte) 0x3E, (byte) 0x39, (byte) 0x46, (byte) 0xD6, (byte) 0xA1,
- (byte) 0xA0, (byte) 0x4F, (byte) 0x3A, (byte) 0x03, (byte) 0x8F, (byte) 0x62,
- (byte) 0xF2, (byte) 0xD8, (byte) 0x90, (byte) 0xAD, (byte) 0xE2, (byte) 0x3B,
- (byte) 0x4F, (byte) 0x98, (byte) 0x88, (byte) 0x51, (byte) 0x41, (byte) 0x09,
- (byte) 0x23, (byte) 0xEB, (byte) 0xF4, (byte) 0x5D, (byte) 0x6A, (byte) 0x22,
- (byte) 0x12, (byte) 0x12, (byte) 0xDC, (byte) 0x27, (byte) 0xE9, (byte) 0xF7,
- (byte) 0x64, (byte) 0xA3, (byte) 0xDE, (byte) 0x3A, (byte) 0xB0, (byte) 0xD6,
- (byte) 0xF2, (byte) 0xC6, (byte) 0xBC, (byte) 0x0B, (byte) 0xA2, (byte) 0xA1,
- (byte) 0xAA, (byte) 0xB0, (byte) 0x51, (byte) 0xDA, (byte) 0x4F, (byte) 0x28,
- (byte) 0xA8, (byte) 0xEB, (byte) 0x34, (byte) 0x60, (byte) 0x37, (byte) 0xF7,
- (byte) 0x50, (byte) 0x7D, (byte) 0xB8, (byte) 0xE7, (byte) 0x24, (byte) 0x8E,
- (byte) 0xAC, (byte) 0x03, (byte) 0x31, (byte) 0xB8, (byte) 0xE0, (byte) 0xDB,
- (byte) 0x97, (byte) 0xE9, (byte) 0x1B, (byte) 0x7E, (byte) 0x27, (byte) 0x99,
- (byte) 0x93, (byte) 0x4D, (byte) 0x46, (byte) 0xB3, (byte) 0xFE, (byte) 0xD6,
- (byte) 0x23, (byte) 0xB3, (byte) 0xAB, (byte) 0x3E, (byte) 0x33, (byte) 0xA1,
- (byte) 0x10, (byte) 0x4E, (byte) 0x34, (byte) 0x27, (byte) 0x58, (byte) 0x25,
- (byte) 0xB7, (byte) 0xBA, (byte) 0xEE, (byte) 0xBE, (byte) 0xE0, (byte) 0x6E,
- (byte) 0x54, (byte) 0xF7, (byte) 0x73, (byte) 0x7B, (byte) 0x5A, (byte) 0x9C,
- (byte) 0x74, (byte) 0xEA, (byte) 0xC7, (byte) 0x7E, (byte) 0xC6, (byte) 0xF7,
- (byte) 0xD5, (byte) 0x32, (byte) 0x0E, (byte) 0x28, (byte) 0x99, (byte) 0xD8,
- (byte) 0xEF, (byte) 0x97, (byte) 0x62, (byte) 0x8A, (byte) 0xE3, (byte) 0x16,
- (byte) 0xAD, (byte) 0xE2, (byte) 0xF4, (byte) 0x11, (byte) 0x91, (byte) 0x17,
- (byte) 0xF3, (byte) 0x32, (byte) 0x90, (byte) 0xCB, (byte) 0x3C, (byte) 0x89,
- (byte) 0xF4, (byte) 0x20, (byte) 0xF1, (byte) 0x2D, (byte) 0x74, (byte) 0x22,
- (byte) 0x50, (byte) 0x64, (byte) 0xC2, (byte) 0xF4, (byte) 0xC4, (byte) 0x0D,
- (byte) 0x18, (byte) 0x6A, (byte) 0x02, (byte) 0x52, (byte) 0x14, (byte) 0x85,
- (byte) 0x67, (byte) 0xA4, (byte) 0x08, (byte) 0xE5, (byte) 0xBF, (byte) 0x65,
- (byte) 0x15, (byte) 0xB3, (byte) 0x5A, (byte) 0x88, (byte) 0xEB, (byte) 0xD4,
- (byte) 0x75, (byte) 0xF9, (byte) 0x52, (byte) 0x73, (byte) 0xA0, (byte) 0x5E,
- (byte) 0xBA, (byte) 0x37, (byte) 0x6A, (byte) 0x61, (byte) 0x2B, (byte) 0x16,
- (byte) 0x8A, (byte) 0xA8, (byte) 0x00, (byte) 0xBB, (byte) 0x4D, (byte) 0xFA,
- (byte) 0x04, (byte) 0xB8, (byte) 0xAB, (byte) 0x4D, (byte) 0xA4, (byte) 0xFC,
- (byte) 0x9D, (byte) 0xCF, (byte) 0x63, (byte) 0x83, (byte) 0x34, (byte) 0xAE,
- (byte) 0xAE, (byte) 0xA6, (byte) 0x77, (byte) 0x73, (byte) 0xA2, (byte) 0xB5,
- (byte) 0x77, (byte) 0xAC, (byte) 0x00, (byte) 0x03, (byte) 0x06, (byte) 0xD4,
- (byte) 0xDF, (byte) 0x81, (byte) 0x61, (byte) 0xCE, (byte) 0x8E, (byte) 0xC1,
- (byte) 0xD5, (byte) 0x99, (byte) 0xD5, (byte) 0x2F, (byte) 0xE8, (byte) 0x27,
- (byte) 0xFA, (byte) 0x84, (byte) 0x7E, (byte) 0x57, (byte) 0xF1, (byte) 0xC9,
- (byte) 0xEB, (byte) 0x4F, (byte) 0xF9, (byte) 0x92, (byte) 0xC6, (byte) 0xD0,
- (byte) 0x25, (byte) 0x8A, (byte) 0x16, (byte) 0xD0, (byte) 0xEC, (byte) 0xE5,
- (byte) 0x33, (byte) 0xA6, (byte) 0xF9, (byte) 0xD5, (byte) 0x0C, (byte) 0x7B,
- (byte) 0xEC, (byte) 0xC6, (byte) 0x58, (byte) 0x45,
- };
- private static final PSSParameterSpec SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 0, 1);
-
- /*
- * echo "This is a signed message from Kenny Root." | openssl sha512 -binary -out digest.bin \
- * && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
- * -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha512 -pkeyopt rsa_pss_saltlen:190 \
- * | recode ../x1 | sed 's/0x/(byte) 0x/g'
- */
- private static final byte[] SHA512withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
- (byte) 0x90, (byte) 0x92, (byte) 0x45, (byte) 0xA1, (byte) 0x1E, (byte) 0x0F,
- (byte) 0x5F, (byte) 0xF6, (byte) 0x8F, (byte) 0xA0, (byte) 0xBE, (byte) 0x34,
- (byte) 0x29, (byte) 0x62, (byte) 0xBE, (byte) 0x41, (byte) 0x80, (byte) 0xF0,
- (byte) 0xB8, (byte) 0x9F, (byte) 0x29, (byte) 0x63, (byte) 0x89, (byte) 0x26,
- (byte) 0xC2, (byte) 0x22, (byte) 0x1F, (byte) 0x60, (byte) 0xB6, (byte) 0xFC,
- (byte) 0x5A, (byte) 0x3E, (byte) 0x99, (byte) 0xB8, (byte) 0xC6, (byte) 0x3B,
- (byte) 0x67, (byte) 0x33, (byte) 0x97, (byte) 0x19, (byte) 0xC6, (byte) 0xFF,
- (byte) 0x0C, (byte) 0xA9, (byte) 0x04, (byte) 0x5A, (byte) 0xF0, (byte) 0x02,
- (byte) 0x9A, (byte) 0x19, (byte) 0x0F, (byte) 0xEA, (byte) 0x77, (byte) 0x0D,
- (byte) 0x56, (byte) 0x38, (byte) 0x0A, (byte) 0xED, (byte) 0x4E, (byte) 0xB7,
- (byte) 0x57, (byte) 0xBD, (byte) 0xC9, (byte) 0xA3, (byte) 0xE8, (byte) 0xC0,
- (byte) 0x7D, (byte) 0xF6, (byte) 0xA3, (byte) 0x4B, (byte) 0x61, (byte) 0x45,
- (byte) 0x06, (byte) 0x5E, (byte) 0x56, (byte) 0xF5, (byte) 0xEF, (byte) 0x76,
- (byte) 0x6B, (byte) 0xB7, (byte) 0xD4, (byte) 0xBB, (byte) 0xA4, (byte) 0x3C,
- (byte) 0x52, (byte) 0xF8, (byte) 0x06, (byte) 0x67, (byte) 0xF7, (byte) 0xC3,
- (byte) 0x8C, (byte) 0x5E, (byte) 0xDF, (byte) 0xFE, (byte) 0x30, (byte) 0x2E,
- (byte) 0xF8, (byte) 0x59, (byte) 0x3C, (byte) 0x3B, (byte) 0xEA, (byte) 0xA0,
- (byte) 0x5D, (byte) 0x8F, (byte) 0x18, (byte) 0x73, (byte) 0x1A, (byte) 0x2D,
- (byte) 0xB1, (byte) 0x55, (byte) 0x07, (byte) 0xC8, (byte) 0x33, (byte) 0xED,
- (byte) 0x8A, (byte) 0x5E, (byte) 0xC3, (byte) 0xAE, (byte) 0x51, (byte) 0x31,
- (byte) 0xC4, (byte) 0xFA, (byte) 0xE8, (byte) 0xE9, (byte) 0xBE, (byte) 0x2E,
- (byte) 0x28, (byte) 0xAA, (byte) 0xED, (byte) 0xA8, (byte) 0x4B, (byte) 0xA3,
- (byte) 0x13, (byte) 0xB9, (byte) 0x82, (byte) 0x57, (byte) 0xD1, (byte) 0x72,
- (byte) 0x0D, (byte) 0xA7, (byte) 0xF8, (byte) 0x67, (byte) 0xB8, (byte) 0x55,
- (byte) 0xF3, (byte) 0x06, (byte) 0xAE, (byte) 0xA7, (byte) 0x69, (byte) 0x66,
- (byte) 0x0B, (byte) 0x80, (byte) 0x56, (byte) 0x65, (byte) 0xC7, (byte) 0xE9,
- (byte) 0x60, (byte) 0xDC, (byte) 0x2D, (byte) 0x4B, (byte) 0x26, (byte) 0xA9,
- (byte) 0xED, (byte) 0x54, (byte) 0x79, (byte) 0x9E, (byte) 0x55, (byte) 0x1D,
- (byte) 0xEE, (byte) 0x78, (byte) 0x49, (byte) 0xA1, (byte) 0x1F, (byte) 0x9B,
- (byte) 0x37, (byte) 0xC0, (byte) 0xBA, (byte) 0xE6, (byte) 0x4B, (byte) 0x3B,
- (byte) 0xAF, (byte) 0x12, (byte) 0x99, (byte) 0x32, (byte) 0x14, (byte) 0x8C,
- (byte) 0x4D, (byte) 0xEB, (byte) 0x08, (byte) 0xA4, (byte) 0xE3, (byte) 0xC6,
- (byte) 0x37, (byte) 0x8B, (byte) 0x6E, (byte) 0x7C, (byte) 0xEC, (byte) 0xA3,
- (byte) 0x78, (byte) 0xED, (byte) 0x4E, (byte) 0x36, (byte) 0xBC, (byte) 0xA2,
- (byte) 0x7D, (byte) 0x11, (byte) 0x0E, (byte) 0xD0, (byte) 0x53, (byte) 0x14,
- (byte) 0x93, (byte) 0x16, (byte) 0x54, (byte) 0x45, (byte) 0x79, (byte) 0x7A,
- (byte) 0x1A, (byte) 0xA1, (byte) 0xEC, (byte) 0xF3, (byte) 0x12, (byte) 0x3F,
- (byte) 0xFE, (byte) 0x68, (byte) 0xFF, (byte) 0x5A, (byte) 0x3F, (byte) 0xE7,
- (byte) 0x13, (byte) 0x37, (byte) 0xEB, (byte) 0x60, (byte) 0x0A, (byte) 0x8E,
- (byte) 0x4F, (byte) 0x54, (byte) 0x46, (byte) 0x19, (byte) 0x82, (byte) 0xBF,
- (byte) 0xB7, (byte) 0xD2, (byte) 0x19, (byte) 0x71, (byte) 0x78, (byte) 0x38,
- (byte) 0x4C, (byte) 0xE3, (byte) 0xC4, (byte) 0xEA, (byte) 0x8F, (byte) 0x9B,
- (byte) 0xE5, (byte) 0xBA, (byte) 0x06, (byte) 0xFC,
- };
- private static final PSSParameterSpec SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
- new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 190, 1);
-
- public void testGetCommonInstances_Success() throws Exception {
- assertNotNull(Signature.getInstance("SHA1withRSA"));
- assertNotNull(Signature.getInstance("SHA256withRSA"));
- assertNotNull(Signature.getInstance("SHA384withRSA"));
- assertNotNull(Signature.getInstance("SHA512withRSA"));
- assertNotNull(Signature.getInstance("NONEwithRSA"));
- assertNotNull(Signature.getInstance("MD5withRSA"));
- assertNotNull(Signature.getInstance("SHA1withDSA"));
- }
-
- public void testVerify_SHA1withRSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA1withRSA");
- sig.initVerify(pubKey);
- sig.update(Vector1Data);
-
- assertTrue("Signature must match expected signature",
- sig.verify(SHA1withRSA_Vector1Signature));
- }
-
- public void testVerify_SHA256withRSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA256withRSA");
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
-
- assertTrue("Signature must match expected signature",
- sig.verify(SHA256withRSA_Vector2Signature));
- }
-
- public void testVerify_SHA384withRSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA384withRSA");
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
-
- assertTrue("Signature must match expected signature",
- sig.verify(SHA384withRSA_Vector2Signature));
- }
-
- public void testVerify_SHA512withRSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA512withRSA");
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
-
- assertTrue("Signature must match expected signature",
- sig.verify(SHA512withRSA_Vector2Signature));
- }
-
- public void testVerify_MD5withRSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("MD5withRSA");
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
-
- assertTrue("Signature must match expected signature",
- sig.verify(MD5withRSA_Vector2Signature));
- }
-
- public void testVerify_SHA1withRSAPSS_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA1withRSA/PSS");
- sig.initVerify(pubKey);
- assertPSSAlgorithmParametersEquals(
- SHA1withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA1withRSAPSS_Vector2Signature));
- }
-
- public void testVerify_SHA1withRSAPSS_NoSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA1withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA1withRSAPSS_NoSalt_Vector2Signature));
- }
-
- public void testVerify_SHA1withRSAPSS_MaxSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA1withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA1withRSAPSS_MaxSalt_Vector2Signature));
- }
-
- public void testVerify_SHA224withRSAPSS_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA224withRSA/PSS");
- sig.initVerify(pubKey);
- assertPSSAlgorithmParametersEquals(
- SHA224withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA224withRSAPSS_Vector2Signature));
- }
-
- public void testVerify_SHA224withRSAPSS_NoSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA224withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA224withRSAPSS_NoSalt_Vector2Signature));
- }
-
- public void testVerify_SHA224withRSAPSS_MaxSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA224withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA224withRSAPSS_MaxSalt_Vector2Signature));
- }
-
- public void testVerify_SHA256withRSAPSS_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA256withRSA/PSS");
- sig.initVerify(pubKey);
- assertPSSAlgorithmParametersEquals(
- SHA256withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA256withRSAPSS_Vector2Signature));
- }
-
- public void testVerify_SHA256withRSAPSS_NoSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA256withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA256withRSAPSS_NoSalt_Vector2Signature));
- }
-
- public void testVerify_SHA256withRSAPSS_MaxSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA256withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA256withRSAPSS_MaxSalt_Vector2Signature));
- }
-
- public void testVerify_SHA384withRSAPSS_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA384withRSA/PSS");
- sig.initVerify(pubKey);
- assertPSSAlgorithmParametersEquals(
- SHA384withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA384withRSAPSS_Vector2Signature));
- }
-
- public void testVerify_SHA384withRSAPSS_NoSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA384withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA384withRSAPSS_NoSalt_Vector2Signature));
- }
-
- public void testVerify_SHA384withRSAPSS_MaxSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA384withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA384withRSAPSS_MaxSalt_Vector2Signature));
- }
-
- public void testVerify_SHA512withRSAPSS_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA512withRSA/PSS");
- sig.initVerify(pubKey);
- assertPSSAlgorithmParametersEquals(
- SHA512withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA512withRSAPSS_Vector2Signature));
- }
-
- public void testVerify_SHA512withRSAPSS_NoSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA512withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA512withRSAPSS_NoSalt_Vector2Signature));
- }
-
- public void testVerify_SHA512withRSAPSS_MaxSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA512withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- assertTrue("Signature must verify",
- sig.verify(SHA512withRSAPSS_MaxSalt_Vector2Signature));
- }
-
- public void testVerify_SHA1withRSA_Key_InitSignThenInitVerify_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
- RSAPrivateKeySpec privKeySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(privKeySpec);
-
- Signature sig = Signature.getInstance("SHA1withRSA");
-
- // Start a signing operation
- sig.initSign(privKey);
- sig.update(Vector2Data);
-
- // Switch to verify
- sig.initVerify(pubKey);
- sig.update(Vector1Data);
-
- assertTrue("Signature must match expected signature",
- sig.verify(SHA1withRSA_Vector1Signature));
- }
-
- public void testVerify_SHA1withRSA_Key_TwoMessages_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA1withRSA");
- sig.initVerify(pubKey);
-
- sig.update(Vector1Data);
- assertTrue("First signature must match expected signature",
- sig.verify(SHA1withRSA_Vector1Signature));
-
- sig.update(Vector2Data);
- assertTrue("Second signature must match expected signature",
- sig.verify(SHA1withRSA_Vector2Signature));
- }
-
- public void testVerify_SHA1withRSA_Key_WrongExpectedSignature_Failure() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(keySpec);
-
- Signature sig = Signature.getInstance("SHA1withRSA");
- sig.initVerify(pubKey);
- sig.update(Vector1Data);
-
- assertFalse("Signature should fail to verify", sig.verify(SHA1withRSA_Vector2Signature));
- }
-
- public void testSign_SHA1withRSA_CrtKeyWithPublicExponent_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent, RSA_2048_privateExponent, null, null, null, null, null);
-
- // The RI fails on this key which is totally unreasonable.
- final PrivateKey privKey;
- try {
- privKey = kf.generatePrivate(keySpec);
- } catch (NullPointerException e) {
- if (StandardNames.IS_RI) {
- return;
- } else {
- fail("Private key should be created");
- return;
- }
- }
-
- Signature sig = Signature.getInstance("SHA1withRSA");
- sig.initSign(privKey);
- sig.update(Vector1Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertTrue("Signature should match expected",
- Arrays.equals(signature, SHA1withRSA_Vector1Signature));
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector1Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA1withRSA_CrtKey_NoPrivateExponent_Failure() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent, null, RSA_2048_primeP, RSA_2048_primeQ, null, null, null);
-
- // Failing on this key early is okay.
- final PrivateKey privKey;
- try {
- privKey = kf.generatePrivate(keySpec);
- } catch (NullPointerException e) {
- return;
- } catch (InvalidKeySpecException e) {
- return;
- }
-
- Signature sig = Signature.getInstance("SHA1withRSA");
-
- try {
- sig.initSign(privKey);
- fail("Should throw error when private exponent is not available");
- } catch (InvalidKeyException expected) {
- }
- }
-
- public void testSign_SHA1withRSA_CrtKey_NoModulus_Failure() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(null, RSA_2048_publicExponent,
- RSA_2048_privateExponent, RSA_2048_primeP, RSA_2048_primeQ, null, null, null);
-
- // Failing on this key early is okay.
- final PrivateKey privKey;
- try {
- privKey = kf.generatePrivate(keySpec);
- } catch (NullPointerException e) {
- return;
- } catch (InvalidKeySpecException e) {
- return;
- }
-
- Signature sig = Signature.getInstance("SHA1withRSA");
-
- try {
- sig.initSign(privKey);
- fail("Should throw error when modulus is not available");
- } catch (InvalidKeyException expected) {
- }
- }
-
- public void testSign_SHA1withRSA_Key_EmptyKey_Failure() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(null, null);
-
- // Failing on this key early is okay.
- final PrivateKey privKey;
- try {
- privKey = kf.generatePrivate(keySpec);
- } catch (NullPointerException e) {
- return;
- } catch (InvalidKeySpecException e) {
- return;
- }
-
- Signature sig = Signature.getInstance("SHA1withRSA");
-
- try {
- sig.initSign(privKey);
- fail("Should throw error when key is empty");
- } catch (InvalidKeyException expected) {
- }
- }
-
- public void testSign_SHA1withRSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA1withRSA");
- sig.initSign(privKey);
- sig.update(Vector1Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertTrue("Signature should match expected",
- Arrays.equals(signature, SHA1withRSA_Vector1Signature));
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector1Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA224withRSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
-
- final PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA224withRSA");
- sig.initSign(privKey);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertTrue("Signature should match expected",
- Arrays.equals(signature, SHA224withRSA_Vector2Signature));
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA256withRSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
-
- final PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA256withRSA");
- sig.initSign(privKey);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertTrue("Signature should match expected",
- Arrays.equals(signature, SHA256withRSA_Vector2Signature));
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA384withRSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA384withRSA");
- sig.initSign(privKey);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertTrue("Signature should match expected",
- Arrays.equals(signature, SHA384withRSA_Vector2Signature));
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA512withRSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA512withRSA");
- sig.initSign(privKey);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertTrue("Signature should match expected",
- Arrays.equals(signature, SHA512withRSA_Vector2Signature));
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_MD5withRSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("MD5withRSA");
- sig.initSign(privKey);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertTrue("Signature should match expected",
- Arrays.equals(signature, MD5withRSA_Vector2Signature));
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA1withRSAPSS_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA1withRSA/PSS");
- sig.initSign(privKey);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA1withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA1withRSAPSS_NoSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA1withRSA/PSS");
- sig.initSign(privKey);
- sig.setParameter(SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
- assertTrue("Signature should match expected",
- Arrays.equals(signature, SHA1withRSAPSS_NoSalt_Vector2Signature));
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.setParameter(SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA1withRSAPSS_MaxSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA1withRSA/PSS");
- sig.initSign(privKey);
- sig.setParameter(SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig = Signature.getInstance("SHA1withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA224withRSAPSS_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA224withRSA/PSS");
- sig.initSign(privKey);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA224withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA224withRSAPSS_NoSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA224withRSA/PSS");
- sig.initSign(privKey);
- sig.setParameter(SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
- assertTrue("Signature should match expected",
- Arrays.equals(signature, SHA224withRSAPSS_NoSalt_Vector2Signature));
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.setParameter(SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA224withRSAPSS_MaxSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA224withRSA/PSS");
- sig.initSign(privKey);
- sig.setParameter(SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig = Signature.getInstance("SHA224withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA256withRSAPSS_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA256withRSA/PSS");
- sig.initSign(privKey);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA256withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA256withRSAPSS_NoSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA256withRSA/PSS");
- sig.initSign(privKey);
- sig.setParameter(SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
- assertTrue("Signature should match expected",
- Arrays.equals(signature, SHA256withRSAPSS_NoSalt_Vector2Signature));
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.setParameter(SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA256withRSAPSS_MaxSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA256withRSA/PSS");
- sig.initSign(privKey);
- sig.setParameter(SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig = Signature.getInstance("SHA256withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA384withRSAPSS_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA384withRSA/PSS");
- sig.initSign(privKey);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA384withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA384withRSAPSS_NoSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA384withRSA/PSS");
- sig.initSign(privKey);
- sig.setParameter(SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
- assertTrue("Signature should match expected",
- Arrays.equals(signature, SHA384withRSAPSS_NoSalt_Vector2Signature));
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.setParameter(SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA384withRSAPSS_MaxSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA384withRSA/PSS");
- sig.initSign(privKey);
- sig.setParameter(SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig = Signature.getInstance("SHA384withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA512withRSAPSS_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA512withRSA/PSS");
- sig.initSign(privKey);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA512withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA512withRSAPSS_NoSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA512withRSA/PSS");
- sig.initSign(privKey);
- sig.setParameter(SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
- assertTrue("Signature should match expected",
- Arrays.equals(signature, SHA512withRSAPSS_NoSalt_Vector2Signature));
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.setParameter(SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_SHA512withRSAPSS_MaxSalt_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA512withRSA/PSS");
- sig.initSign(privKey);
- sig.setParameter(SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertPSSAlgorithmParametersEquals(
- SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig = Signature.getInstance("SHA512withRSA/PSS");
- sig.initVerify(pubKey);
- sig.setParameter(SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testSign_NONEwithRSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("NONEwithRSA");
- sig.initSign(privKey);
- sig.update(Vector1Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertTrue("Signature should match expected",
- Arrays.equals(signature, NONEwithRSA_Vector1Signature));
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector1Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testVerify_NONEwithRSA_Key_WrongSignature_Failure() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
- Signature sig = Signature.getInstance("NONEwithRSA");
- sig.initVerify(pubKey);
- sig.update(Vector1Data);
- assertFalse("Invalid signature must not verify",
- sig.verify("Invalid".getBytes(UTF_8)));
- }
-
- public void testSign_NONEwithRSA_Key_DataTooLarge_Failure() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("NONEwithRSA");
- sig.initSign(privKey);
-
- final int oneTooBig = RSA_2048_modulus.bitLength() - 10;
- for (int i = 0; i < oneTooBig; i++) {
- sig.update((byte) i);
- }
-
- try {
- sig.sign();
- fail("Should throw exception when data is too large");
- } catch (SignatureException expected) {
- }
- }
-
- public void testSign_NONEwithRSA_Key_DataTooLarge_SingleByte_Failure() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("NONEwithRSA");
- sig.initSign(privKey);
-
- // This should make it two bytes too big.
- final int oneTooBig = RSA_2048_modulus.bitLength() - 10;
- for (int i = 0; i < oneTooBig; i++) {
- sig.update((byte) i);
- }
-
- try {
- sig.sign();
- fail("Should throw exception when data is too large");
- } catch (SignatureException expected) {
- }
- }
-
- public void testVerify_NONEwithRSA_Key_DataTooLarge_Failure() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
- Signature sig = Signature.getInstance("NONEwithRSA");
- sig.initVerify(pubKey);
-
- // This should make it one bytes too big.
- final int oneTooBig = RSA_2048_modulus.bitLength() + 1;
- final byte[] vector = new byte[oneTooBig];
- for (int i = 0; i < oneTooBig; i++) {
- vector[i] = (byte) Vector1Data[i % Vector1Data.length];
- }
- sig.update(vector);
-
- assertFalse("Should not verify when signature is too large",
- sig.verify(NONEwithRSA_Vector1Signature));
- }
-
- public void testVerify_NONEwithRSA_Key_DataTooLarge_SingleByte_Failure() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
- Signature sig = Signature.getInstance("NONEwithRSA");
- sig.initVerify(pubKey);
-
- // This should make it twice as big as it should be.
- final int tooBig = RSA_2048_modulus.bitLength() * 2;
- for (int i = 0; i < tooBig; i++) {
- sig.update((byte) Vector1Data[i % Vector1Data.length]);
- }
-
- assertFalse("Should not verify when signature is too large",
- sig.verify(NONEwithRSA_Vector1Signature));
- }
-
- public void testVerify_NONEwithRSA_Key_SignatureTooSmall_Failure() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
- Signature sig = Signature.getInstance("NONEwithRSA");
- sig.initVerify(pubKey);
- sig.update(Vector1Data);
-
- assertFalse("Invalid signature should not verify",
- sig.verify("Invalid sig".getBytes(UTF_8)));
- }
-
- public void testVerify_NONEwithRSA_Key_SignatureTooLarge_Failure() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("RSA");
-
- RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
- Signature sig = Signature.getInstance("NONEwithRSA");
- sig.initVerify(pubKey);
- sig.update(Vector1Data);
-
- byte[] invalidSignature = new byte[NONEwithRSA_Vector1Signature.length * 2];
- System.arraycopy(NONEwithRSA_Vector1Signature, 0, invalidSignature, 0,
- NONEwithRSA_Vector1Signature.length);
- System.arraycopy(NONEwithRSA_Vector1Signature, 0, invalidSignature,
- NONEwithRSA_Vector1Signature.length, NONEwithRSA_Vector1Signature.length);
-
- try {
- sig.verify(invalidSignature);
- fail("Should throw exception when signature is too large");
- } catch (SignatureException expected) {
- }
- }
-
- public void testSign_NONEwithECDSA_Key_Success() throws Exception {
- KeyPair keys = keyPair("NONEwithECDSA", null);
- Signature sig = Signature.getInstance("NONEwithECDSA");
-
- sig.initSign(keys.getPrivate());
- sig.update(Vector1Data);
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
- assertTrue("Signature must not be empty", signature.length > 0);
-
- sig.initVerify(keys.getPublic());
- sig.update(Vector1Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testVerify_NONEwithECDSA_Key_Success() throws Exception {
- PublicKey pub = getNamedCurveEcPublicKey();
- MessageDigest sha1 = MessageDigest.getInstance("SHA1");
- Signature sig = Signature.getInstance("NONEwithECDSA");
-
- // NAMED_CURVE_SIGNATURE was signed using SHA1withECDSA, so NONEwithECDSA should
- // verify the digest
- sig.initVerify(pub);
- sig.update(sha1.digest(NAMED_CURVE_VECTOR));
- assertTrue(sig.verify(NAMED_CURVE_SIGNATURE));
- }
-
- public void testVerify_NONEwithECDSA_Key_WrongData_Failure() throws Exception {
- PublicKey pub = getNamedCurveEcPublicKey();
- Signature sig = Signature.getInstance("NONEwithECDSA");
-
- sig.initVerify(pub);
- sig.update(NAMED_CURVE_VECTOR);
- assertFalse(sig.verify(NAMED_CURVE_SIGNATURE));
- }
-
- public void testVerify_NONEwithECDSA_Key_SingleByte_Failure() throws Exception {
- PublicKey pub = getNamedCurveEcPublicKey();
- MessageDigest sha1 = MessageDigest.getInstance("SHA1");
- Signature sig = Signature.getInstance("NONEwithECDSA");
-
- byte[] corrupted = new byte[NAMED_CURVE_SIGNATURE.length];
- corrupted[0] ^= 1;
-
- sig.initVerify(pub);
- sig.update(sha1.digest(NAMED_CURVE_VECTOR));
- try {
- assertFalse(sig.verify(corrupted));
- } catch (SignatureException expected) {
- // It's valid to either return false or throw an exception, accept either
- }
- }
-
- /*
- * These tests were generated with this DSA private key:
- *
- * -----BEGIN DSA PRIVATE KEY-----
- * MIIBugIBAAKBgQCeYcKJ73epThNnZB8JAf4kE1Pgt5CoTnb+iYJ/esU8TgwgVTCV
- * QoXhQH0njwcN6NyZ77MHlDTWfP+cvmnT60Q3UO9J+OJb2NEQhJfq46UcwE5pynA9
- * eLkW5f5hXYpasyxhtgE70AF8Mo3h82kOi1jGzwCU+EkqS+raAP9L0L5AIwIVAL/u
- * qg8SNFBy+GAT2PFBARClL1dfAoGAd9R6EsyBfn7rOvvmhm1aEB2tqU+5A10hGuQw
- * lXWOzV7RvQpF7uf3a2UCYNAurz28B90rjjPAk4DZK6dxV3a8jrng1/QjjUEal08s
- * G9VLZuj60lANF6s0MT2kiNiOqKduFwO3D2h8ZHuSuGPkmmcYgSfUCxNI031O9qiP
- * VhctCFECgYAz7i1DhjRGUkCdYQd5tVaI42lhXOV71MTYPbuFOIxTL/hny7Z0PZWR
- * A1blmYE6vrArDEhzpmRvDJZSIMzMfJjUIGu1KO73zpo9siK0xY0/sw5r3QC9txP2
- * 2Mv3BUIl5TLrs9outQJ0VMwldY2fElgCLWcSVkH44qZwWir1cq+cIwIUEGPDardb
- * pNvWlWgTDD6a6ZTby+M=
- * -----END DSA PRIVATE KEY-----
- *
- */
-
- private static final BigInteger DSA_priv = new BigInteger(new byte[] {
- (byte) 0x10, (byte) 0x63, (byte) 0xc3, (byte) 0x6a, (byte) 0xb7, (byte) 0x5b, (byte) 0xa4, (byte) 0xdb,
- (byte) 0xd6, (byte) 0x95, (byte) 0x68, (byte) 0x13, (byte) 0x0c, (byte) 0x3e, (byte) 0x9a, (byte) 0xe9,
- (byte) 0x94, (byte) 0xdb, (byte) 0xcb, (byte) 0xe3,
- });
-
- private static final BigInteger DSA_pub = new BigInteger(new byte[] {
- (byte) 0x33, (byte) 0xee, (byte) 0x2d, (byte) 0x43, (byte) 0x86, (byte) 0x34, (byte) 0x46, (byte) 0x52,
- (byte) 0x40, (byte) 0x9d, (byte) 0x61, (byte) 0x07, (byte) 0x79, (byte) 0xb5, (byte) 0x56, (byte) 0x88,
- (byte) 0xe3, (byte) 0x69, (byte) 0x61, (byte) 0x5c, (byte) 0xe5, (byte) 0x7b, (byte) 0xd4, (byte) 0xc4,
- (byte) 0xd8, (byte) 0x3d, (byte) 0xbb, (byte) 0x85, (byte) 0x38, (byte) 0x8c, (byte) 0x53, (byte) 0x2f,
- (byte) 0xf8, (byte) 0x67, (byte) 0xcb, (byte) 0xb6, (byte) 0x74, (byte) 0x3d, (byte) 0x95, (byte) 0x91,
- (byte) 0x03, (byte) 0x56, (byte) 0xe5, (byte) 0x99, (byte) 0x81, (byte) 0x3a, (byte) 0xbe, (byte) 0xb0,
- (byte) 0x2b, (byte) 0x0c, (byte) 0x48, (byte) 0x73, (byte) 0xa6, (byte) 0x64, (byte) 0x6f, (byte) 0x0c,
- (byte) 0x96, (byte) 0x52, (byte) 0x20, (byte) 0xcc, (byte) 0xcc, (byte) 0x7c, (byte) 0x98, (byte) 0xd4,
- (byte) 0x20, (byte) 0x6b, (byte) 0xb5, (byte) 0x28, (byte) 0xee, (byte) 0xf7, (byte) 0xce, (byte) 0x9a,
- (byte) 0x3d, (byte) 0xb2, (byte) 0x22, (byte) 0xb4, (byte) 0xc5, (byte) 0x8d, (byte) 0x3f, (byte) 0xb3,
- (byte) 0x0e, (byte) 0x6b, (byte) 0xdd, (byte) 0x00, (byte) 0xbd, (byte) 0xb7, (byte) 0x13, (byte) 0xf6,
- (byte) 0xd8, (byte) 0xcb, (byte) 0xf7, (byte) 0x05, (byte) 0x42, (byte) 0x25, (byte) 0xe5, (byte) 0x32,
- (byte) 0xeb, (byte) 0xb3, (byte) 0xda, (byte) 0x2e, (byte) 0xb5, (byte) 0x02, (byte) 0x74, (byte) 0x54,
- (byte) 0xcc, (byte) 0x25, (byte) 0x75, (byte) 0x8d, (byte) 0x9f, (byte) 0x12, (byte) 0x58, (byte) 0x02,
- (byte) 0x2d, (byte) 0x67, (byte) 0x12, (byte) 0x56, (byte) 0x41, (byte) 0xf8, (byte) 0xe2, (byte) 0xa6,
- (byte) 0x70, (byte) 0x5a, (byte) 0x2a, (byte) 0xf5, (byte) 0x72, (byte) 0xaf, (byte) 0x9c, (byte) 0x23,
- });
-
- private static final BigInteger DSA_P = new BigInteger(new byte[] {
- (byte) 0x00, (byte) 0x9e, (byte) 0x61, (byte) 0xc2, (byte) 0x89, (byte) 0xef, (byte) 0x77, (byte) 0xa9,
- (byte) 0x4e, (byte) 0x13, (byte) 0x67, (byte) 0x64, (byte) 0x1f, (byte) 0x09, (byte) 0x01, (byte) 0xfe,
- (byte) 0x24, (byte) 0x13, (byte) 0x53, (byte) 0xe0, (byte) 0xb7, (byte) 0x90, (byte) 0xa8, (byte) 0x4e,
- (byte) 0x76, (byte) 0xfe, (byte) 0x89, (byte) 0x82, (byte) 0x7f, (byte) 0x7a, (byte) 0xc5, (byte) 0x3c,
- (byte) 0x4e, (byte) 0x0c, (byte) 0x20, (byte) 0x55, (byte) 0x30, (byte) 0x95, (byte) 0x42, (byte) 0x85,
- (byte) 0xe1, (byte) 0x40, (byte) 0x7d, (byte) 0x27, (byte) 0x8f, (byte) 0x07, (byte) 0x0d, (byte) 0xe8,
- (byte) 0xdc, (byte) 0x99, (byte) 0xef, (byte) 0xb3, (byte) 0x07, (byte) 0x94, (byte) 0x34, (byte) 0xd6,
- (byte) 0x7c, (byte) 0xff, (byte) 0x9c, (byte) 0xbe, (byte) 0x69, (byte) 0xd3, (byte) 0xeb, (byte) 0x44,
- (byte) 0x37, (byte) 0x50, (byte) 0xef, (byte) 0x49, (byte) 0xf8, (byte) 0xe2, (byte) 0x5b, (byte) 0xd8,
- (byte) 0xd1, (byte) 0x10, (byte) 0x84, (byte) 0x97, (byte) 0xea, (byte) 0xe3, (byte) 0xa5, (byte) 0x1c,
- (byte) 0xc0, (byte) 0x4e, (byte) 0x69, (byte) 0xca, (byte) 0x70, (byte) 0x3d, (byte) 0x78, (byte) 0xb9,
- (byte) 0x16, (byte) 0xe5, (byte) 0xfe, (byte) 0x61, (byte) 0x5d, (byte) 0x8a, (byte) 0x5a, (byte) 0xb3,
- (byte) 0x2c, (byte) 0x61, (byte) 0xb6, (byte) 0x01, (byte) 0x3b, (byte) 0xd0, (byte) 0x01, (byte) 0x7c,
- (byte) 0x32, (byte) 0x8d, (byte) 0xe1, (byte) 0xf3, (byte) 0x69, (byte) 0x0e, (byte) 0x8b, (byte) 0x58,
- (byte) 0xc6, (byte) 0xcf, (byte) 0x00, (byte) 0x94, (byte) 0xf8, (byte) 0x49, (byte) 0x2a, (byte) 0x4b,
- (byte) 0xea, (byte) 0xda, (byte) 0x00, (byte) 0xff, (byte) 0x4b, (byte) 0xd0, (byte) 0xbe, (byte) 0x40,
- (byte) 0x23,
- });
-
- private static final BigInteger DSA_Q = new BigInteger(new byte[] {
- (byte) 0x00, (byte) 0xbf, (byte) 0xee, (byte) 0xaa, (byte) 0x0f, (byte) 0x12, (byte) 0x34, (byte) 0x50,
- (byte) 0x72, (byte) 0xf8, (byte) 0x60, (byte) 0x13, (byte) 0xd8, (byte) 0xf1, (byte) 0x41, (byte) 0x01,
- (byte) 0x10, (byte) 0xa5, (byte) 0x2f, (byte) 0x57, (byte) 0x5f,
- });
-
- private static final BigInteger DSA_G = new BigInteger(new byte[] {
- (byte) 0x77, (byte) 0xd4, (byte) 0x7a, (byte) 0x12, (byte) 0xcc, (byte) 0x81, (byte) 0x7e, (byte) 0x7e,
- (byte) 0xeb, (byte) 0x3a, (byte) 0xfb, (byte) 0xe6, (byte) 0x86, (byte) 0x6d, (byte) 0x5a, (byte) 0x10,
- (byte) 0x1d, (byte) 0xad, (byte) 0xa9, (byte) 0x4f, (byte) 0xb9, (byte) 0x03, (byte) 0x5d, (byte) 0x21,
- (byte) 0x1a, (byte) 0xe4, (byte) 0x30, (byte) 0x95, (byte) 0x75, (byte) 0x8e, (byte) 0xcd, (byte) 0x5e,
- (byte) 0xd1, (byte) 0xbd, (byte) 0x0a, (byte) 0x45, (byte) 0xee, (byte) 0xe7, (byte) 0xf7, (byte) 0x6b,
- (byte) 0x65, (byte) 0x02, (byte) 0x60, (byte) 0xd0, (byte) 0x2e, (byte) 0xaf, (byte) 0x3d, (byte) 0xbc,
- (byte) 0x07, (byte) 0xdd, (byte) 0x2b, (byte) 0x8e, (byte) 0x33, (byte) 0xc0, (byte) 0x93, (byte) 0x80,
- (byte) 0xd9, (byte) 0x2b, (byte) 0xa7, (byte) 0x71, (byte) 0x57, (byte) 0x76, (byte) 0xbc, (byte) 0x8e,
- (byte) 0xb9, (byte) 0xe0, (byte) 0xd7, (byte) 0xf4, (byte) 0x23, (byte) 0x8d, (byte) 0x41, (byte) 0x1a,
- (byte) 0x97, (byte) 0x4f, (byte) 0x2c, (byte) 0x1b, (byte) 0xd5, (byte) 0x4b, (byte) 0x66, (byte) 0xe8,
- (byte) 0xfa, (byte) 0xd2, (byte) 0x50, (byte) 0x0d, (byte) 0x17, (byte) 0xab, (byte) 0x34, (byte) 0x31,
- (byte) 0x3d, (byte) 0xa4, (byte) 0x88, (byte) 0xd8, (byte) 0x8e, (byte) 0xa8, (byte) 0xa7, (byte) 0x6e,
- (byte) 0x17, (byte) 0x03, (byte) 0xb7, (byte) 0x0f, (byte) 0x68, (byte) 0x7c, (byte) 0x64, (byte) 0x7b,
- (byte) 0x92, (byte) 0xb8, (byte) 0x63, (byte) 0xe4, (byte) 0x9a, (byte) 0x67, (byte) 0x18, (byte) 0x81,
- (byte) 0x27, (byte) 0xd4, (byte) 0x0b, (byte) 0x13, (byte) 0x48, (byte) 0xd3, (byte) 0x7d, (byte) 0x4e,
- (byte) 0xf6, (byte) 0xa8, (byte) 0x8f, (byte) 0x56, (byte) 0x17, (byte) 0x2d, (byte) 0x08, (byte) 0x51,
- });
-
- /**
- * A possible signature using SHA1withDSA of Vector2Data. Note that DSS is
- * randomized, so this won't be the exact signature you'll get out of
- * another signing operation unless you use a fixed RNG.
- */
- public static final byte[] SHA1withDSA_Vector2Signature = new byte[] {
- (byte) 0x30, (byte) 0x2d, (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0x88, (byte) 0xef, (byte) 0xac,
- (byte) 0x2b, (byte) 0x8b, (byte) 0xe2, (byte) 0x61, (byte) 0xc6, (byte) 0x2b, (byte) 0xea, (byte) 0xd5,
- (byte) 0x96, (byte) 0xbc, (byte) 0xb0, (byte) 0xa1, (byte) 0x30, (byte) 0x0c, (byte) 0x1f, (byte) 0xed,
- (byte) 0x11, (byte) 0x02, (byte) 0x14, (byte) 0x15, (byte) 0xc4, (byte) 0xfc, (byte) 0x82, (byte) 0x6f,
- (byte) 0x17, (byte) 0xdc, (byte) 0x87, (byte) 0x82, (byte) 0x75, (byte) 0x23, (byte) 0xd4, (byte) 0x58,
- (byte) 0xdc, (byte) 0x73, (byte) 0x3d, (byte) 0xf3, (byte) 0x51, (byte) 0xc0, (byte) 0x57,
- };
-
- /**
- * A possible signature using SHA224withDSA of Vector2Data. Note that DSS is
- * randomized, so this won't be the exact signature you'll get out of
- * another signing operation unless you use a fixed RNG.
- */
- public static final byte[] SHA224withDSA_Vector2Signature = new byte[] {
- (byte) 0x30, (byte) 0x2D, (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0xAD, (byte) 0xE5, (byte) 0x6D,
- (byte) 0xF5, (byte) 0x11, (byte) 0x8D, (byte) 0x2E, (byte) 0x62, (byte) 0x5D, (byte) 0x98, (byte) 0x8A,
- (byte) 0xC4, (byte) 0x88, (byte) 0x7E, (byte) 0xE6, (byte) 0xA3, (byte) 0x44, (byte) 0x99, (byte) 0xEF,
- (byte) 0x49, (byte) 0x02, (byte) 0x14, (byte) 0x15, (byte) 0x3E, (byte) 0x32, (byte) 0xD6, (byte) 0xF9,
- (byte) 0x79, (byte) 0x2C, (byte) 0x60, (byte) 0x6E, (byte) 0xF9, (byte) 0xA9, (byte) 0x78, (byte) 0xE7,
- (byte) 0x4B, (byte) 0x87, (byte) 0x08, (byte) 0x96, (byte) 0x60, (byte) 0xDE, (byte) 0xB5
- };
-
- /**
- * A possible signature using SHA256withDSA of Vector2Data. Note that DSS is
- * randomized, so this won't be the exact signature you'll get out of
- * another signing operation unless you use a fixed RNG.
- */
- public static final byte[] SHA256withDSA_Vector2Signature = new byte[] {
- (byte) 0x30, (byte) 0x2D, (byte) 0x02, (byte) 0x14, (byte) 0x0A, (byte) 0xB1, (byte) 0x74, (byte) 0x45,
- (byte) 0xE1, (byte) 0x63, (byte) 0x43, (byte) 0x68, (byte) 0x65, (byte) 0xBC, (byte) 0xCA, (byte) 0x45,
- (byte) 0x27, (byte) 0x11, (byte) 0x4D, (byte) 0x52, (byte) 0xFB, (byte) 0x22, (byte) 0x93, (byte) 0xDD,
- (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0x98, (byte) 0x32, (byte) 0x1A, (byte) 0x16, (byte) 0x77,
- (byte) 0x49, (byte) 0xA7, (byte) 0x78, (byte) 0xFD, (byte) 0xE0, (byte) 0xF7, (byte) 0x71, (byte) 0xD4,
- (byte) 0x80, (byte) 0x50, (byte) 0xA7, (byte) 0xDD, (byte) 0x94, (byte) 0xD1, (byte) 0x6C
- };
-
- public void testSign_SHA1withDSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("DSA");
- DSAPrivateKeySpec keySpec = new DSAPrivateKeySpec(DSA_priv, DSA_P, DSA_Q, DSA_G);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA1withDSA");
- sig.initSign(privKey);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
-
- DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testVerify_SHA1withDSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("DSA");
- DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
- Signature sig = Signature.getInstance("SHA1withDSA");
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(SHA1withDSA_Vector2Signature));
- }
-
- public void testSign_SHA224withDSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("DSA");
- DSAPrivateKeySpec keySpec = new DSAPrivateKeySpec(DSA_priv, DSA_P, DSA_Q, DSA_G);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA224withDSA");
- sig.initSign(privKey);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
-
- DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testVerify_SHA224withDSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("DSA");
- DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
- Signature sig = Signature.getInstance("SHA224withDSA");
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(SHA224withDSA_Vector2Signature));
- }
-
- public void testSign_SHA256withDSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("DSA");
- DSAPrivateKeySpec keySpec = new DSAPrivateKeySpec(DSA_priv, DSA_P, DSA_Q, DSA_G);
- PrivateKey privKey = kf.generatePrivate(keySpec);
-
- Signature sig = Signature.getInstance("SHA256withDSA");
- sig.initSign(privKey);
- sig.update(Vector2Data);
-
- byte[] signature = sig.sign();
- assertNotNull("Signature must not be null", signature);
-
- DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(signature));
- }
-
- public void testVerify_SHA256withDSA_Key_Success() throws Exception {
- KeyFactory kf = KeyFactory.getInstance("DSA");
- DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
- PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
- Signature sig = Signature.getInstance("SHA256withDSA");
- sig.initVerify(pubKey);
- sig.update(Vector2Data);
- assertTrue("Signature must verify correctly", sig.verify(SHA256withDSA_Vector2Signature));
- }
-
// NetscapeCertRequest looks up Signature algorithms by OID from
// BC but BC version 1.47 had registration bugs and MD5withRSA was
// overlooked. http://b/7453821
@@ -3321,79 +469,6 @@
assertEquals(oid, signature.getAlgorithm());
}
- private final int THREAD_COUNT = 10;
-
- private void testSignature_MultipleThreads_Misuse(final Signature s) throws Exception {
- ExecutorService es = Executors.newFixedThreadPool(THREAD_COUNT);
-
- final CountDownLatch latch = new CountDownLatch(THREAD_COUNT);
- final byte[] message = new byte[64];
-
- for (int i = 0; i < THREAD_COUNT; i++) {
- es.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- // Try to make sure all the threads are ready first.
- latch.countDown();
- latch.await();
-
- for (int j = 0; j < 100; j++) {
- s.update(message);
- s.sign();
- }
-
- return null;
- }
- });
- }
- es.shutdown();
- assertTrue("Test should not timeout", es.awaitTermination(1, TimeUnit.MINUTES));
- }
-
- private static final byte[] NAMED_CURVE_VECTOR = "Satoshi Nakamoto".getBytes(UTF_8);
- // $ echo -n "Satoshi Nakamoto" > signed
- // $ openssl dgst -ecdsa-with-SHA1 -sign key.pem -out sig signed
- private static final byte[] NAMED_CURVE_SIGNATURE = HexEncoding.decode("304402205b41ece6dcc1c5bfcfdae74658d99c08c5e783f3926c11ecc1a8bea5d95cdf27022061a7d5fc687287e2e02dd7c6723e2e27fe0555f789590a37e96b1bb0355b4df0");
-
- private static PublicKey getNamedCurveEcPublicKey() throws Exception {
- // These are the parameters for the BitCoin curve (secp256k1). See
- // https://en.bitcoin.it/wiki/Secp256k1.
- final BigInteger p = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
- final BigInteger a = BigInteger.valueOf(0);
- final BigInteger b = BigInteger.valueOf(7);
- final BigInteger x = new BigInteger("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16);
- final BigInteger y = new BigInteger("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16);
- final BigInteger order = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16);
- final int cofactor = 1;
-
- final ECParameterSpec spec = new ECParameterSpec(new EllipticCurve(new ECFieldFp(p), a, b), new ECPoint(x, y), order, cofactor);
-
- // $ openssl ecparam -name secp256k1 -genkey > key.pem
- // $ openssl ec -text -noout < key.pem
- final BigInteger Px = new BigInteger("2d45572747a625db5fd23b30f97044a682f2d42d31959295043c1fa0034c8ed3", 16);
- final BigInteger Py = new BigInteger("4d330f52e4bba00145a331041c8bbcf300c4fbfdf3d63d8de7608155b2793808", 16);
-
- final KeyFactory factory = KeyFactory.getInstance("EC");
- ECPublicKeySpec keySpec = new ECPublicKeySpec(new ECPoint(Px, Py), spec);
- return factory.generatePublic(keySpec);
- }
-
- public void testArbitraryCurve() throws Exception {
- final PublicKey pub = getNamedCurveEcPublicKey();
-
- Signature ecdsaVerify = Signature.getInstance("SHA1withECDSA");
- ecdsaVerify.initVerify(pub);
- ecdsaVerify.update(NAMED_CURVE_VECTOR);
- boolean result = ecdsaVerify.verify(NAMED_CURVE_SIGNATURE);
- assertEquals(true, result);
-
- ecdsaVerify = Signature.getInstance("SHA1withECDSA");
- ecdsaVerify.initVerify(pub);
- ecdsaVerify.update("Not Satoshi Nakamoto".getBytes(UTF_8));
- result = ecdsaVerify.verify(NAMED_CURVE_SIGNATURE);
- assertEquals(false, result);
- }
-
/**
* When an instance of a Signature is obtained, it's actually wrapped in an
* implementation that makes sure the correct SPI is selected and then calls
@@ -3441,45 +516,6 @@
verify(signatureSpi).engineGetParameters();
}
- private static void assertPSSAlgorithmParametersEquals(
- PSSParameterSpec expectedSpec, AlgorithmParameters actual)
- throws InvalidParameterSpecException {
- assertNotNull(actual);
- assertEqualsIgnoreCase("PSS", actual.getAlgorithm());
- PSSParameterSpec actualSpec = actual.getParameterSpec(PSSParameterSpec.class);
- assertPSSParameterSpecEquals(expectedSpec, actualSpec);
- }
-
- private static void assertPSSParameterSpecEquals(
- PSSParameterSpec expected, PSSParameterSpec actual) {
- assertEqualsIgnoreCase(expected.getDigestAlgorithm(), actual.getDigestAlgorithm());
- assertEqualsIgnoreCase(expected.getMGFAlgorithm(), actual.getMGFAlgorithm());
- if (!"MGF1".equalsIgnoreCase(expected.getMGFAlgorithm())) {
- fail("Unsupported MGF algorithm: " + expected.getMGFAlgorithm());
- }
- MGF1ParameterSpec expectedMgfParams = (MGF1ParameterSpec) expected.getMGFParameters();
- MGF1ParameterSpec actualMgfParams = (MGF1ParameterSpec) actual.getMGFParameters();
- assertEqualsIgnoreCase(
- expectedMgfParams.getDigestAlgorithm(), actualMgfParams.getDigestAlgorithm());
- assertEquals(expected.getSaltLength(), actual.getSaltLength());
- assertEquals(expected.getTrailerField(), actual.getTrailerField());
- }
-
- private static void assertEqualsIgnoreCase(String expected, String actual) {
- if (expected == null) {
- if (actual == null) {
- return;
- }
- fail("Expected null, actual: <" + actual + ">");
- } else if (actual == null) {
- fail("Expected: <" + expected + ">, actual: null");
- } else {
- if (!expected.equalsIgnoreCase(actual)) {
- fail("Expected: <" + expected + ">, actual: <" + actual + ">");
- }
- }
- }
-
public static class MockableProvider extends Provider {
protected MockableProvider() {
super("MockableProvider", 1.0, "Used by Mockito");
diff --git a/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java b/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java
deleted file mode 100644
index 1c85b83..0000000
--- a/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java
+++ /dev/null
@@ -1,625 +0,0 @@
-/*
- * Copyright (C) 2010 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.java.security.cert;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import com.android.org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
-import com.android.org.bouncycastle.asn1.x509.BasicConstraints;
-import com.android.org.bouncycastle.asn1.x509.Extension;
-import com.android.org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
-import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
-import com.android.org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.Provider;
-import java.security.PublicKey;
-import java.security.Security;
-import java.security.cert.CertPath;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.List;
-import java.util.TimeZone;
-
-import javax.security.auth.x500.X500Principal;
-
-import junit.framework.TestCase;
-import libcore.java.security.StandardNames;
-
-import dalvik.system.VMRuntime;
-import sun.security.jca.Providers;
-
-public class CertificateFactoryTest extends TestCase {
-
- // Allow access to deprecated BC algorithms in this test, so we can ensure they
- // continue to work
- @Override
- public void setUp() throws Exception {
- super.setUp();
- Providers.setMaximumAllowableApiLevelForBcDeprecation(
- VMRuntime.getRuntime().getTargetSdkVersion());
- }
-
- @Override
- public void tearDown() throws Exception {
- Providers.setMaximumAllowableApiLevelForBcDeprecation(
- Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
- super.tearDown();
- }
-
- private static final String VALID_CERTIFICATE_PEM =
- "-----BEGIN CERTIFICATE-----\n"
- + "MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM\n"
- + "MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg\n"
- + "THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x\n"
- + "MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh\n"
- + "MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw\n"
- + "FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC\n"
- + "gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN\n"
- + "gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L\n"
- + "05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM\n"
- + "BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl\n"
- + "LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF\n"
- + "BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw\n"
- + "Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0\n"
- + "ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF\n"
- + "AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5\n"
- + "u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6\n"
- + "z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==\n"
- + "-----END CERTIFICATE-----\n";
-
- private static final String VALID_CERTIFICATE_PEM_CRLF =
- "-----BEGIN CERTIFICATE-----\r\n"
- + "MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM\r\n"
- + "MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg\r\n"
- + "THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x\r\n"
- + "MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh\r\n"
- + "MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw\r\n"
- + "FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC\r\n"
- + "gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN\r\n"
- + "gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L\r\n"
- + "05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM\r\n"
- + "BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl\r\n"
- + "LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF\r\n"
- + "BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw\r\n"
- + "Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0\r\n"
- + "ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF\r\n"
- + "AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5\r\n"
- + "u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6\r\n"
- + "z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==\r\n"
- + "-----END CERTIFICATE-----\r\n";
-
- private static final byte[] VALID_CERTIFICATE_PEM_HEADER = "-----BEGIN CERTIFICATE-----\n"
- .getBytes(UTF_8);
-
- private static final byte[] VALID_CERTIFICATE_PEM_DATA =
- ("MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM"
- + "MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg"
- + "THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x"
- + "MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh"
- + "MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw"
- + "FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC"
- + "gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN"
- + "gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L"
- + "05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM"
- + "BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl"
- + "LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF"
- + "BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw"
- + "Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0"
- + "ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF"
- + "AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5"
- + "u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6"
- + "z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==").getBytes(UTF_8);
-
- private static final byte[] VALID_CERTIFICATE_PEM_FOOTER = "\n-----END CERTIFICATE-----\n"
- .getBytes(UTF_8);
-
- private static final String INVALID_CERTIFICATE_PEM =
- "-----BEGIN CERTIFICATE-----\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
- + "AAAAAAAA\n"
- + "-----END CERTIFICATE-----";
-
- public void test_generateCertificate() throws Exception {
- Provider[] providers = Security.getProviders("CertificateFactory.X509");
- for (Provider p : providers) {
- CertificateFactory cf = CertificateFactory.getInstance("X509", p);
- try {
- test_generateCertificate(cf);
- test_generateCertificate_InputStream_Offset_Correct(cf);
- test_generateCertificate_InputStream_Empty(cf);
- test_generateCertificate_InputStream_InvalidStart_Failure(cf);
- test_generateCertificate_AnyLineLength_Success(cf);
- } catch (Throwable e) {
- throw new Exception("Problem testing " + p.getName(), e);
- }
- }
- }
-
- private void test_generateCertificate(CertificateFactory cf) throws Exception {
- {
- byte[] valid = VALID_CERTIFICATE_PEM.getBytes(UTF_8);
- Certificate c = cf.generateCertificate(new ByteArrayInputStream(valid));
- assertNotNull(c);
- }
-
- {
- byte[] valid = VALID_CERTIFICATE_PEM_CRLF.getBytes(UTF_8);
- Certificate c = cf.generateCertificate(new ByteArrayInputStream(valid));
- assertNotNull(c);
- }
-
- try {
- byte[] invalid = INVALID_CERTIFICATE_PEM.getBytes(UTF_8);
- cf.generateCertificate(new ByteArrayInputStream(invalid));
- fail();
- } catch (CertificateException expected) {
- }
- }
-
- /*
- * Checks all possible line lengths for PEM input data.
- */
- private void test_generateCertificate_AnyLineLength_Success(CertificateFactory cf)
- throws Exception {
- // RI barfs on this
- if (StandardNames.IS_RI) {
- return;
- }
-
- int lineLength = 1;
- int maxLineLength = VALID_CERTIFICATE_PEM_DATA.length;
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- baos.write(VALID_CERTIFICATE_PEM_HEADER);
- int offset = 0;
- while (lineLength < (maxLineLength - 4)) {
- int end = offset + lineLength;
- if (end > VALID_CERTIFICATE_PEM_DATA.length) {
- end = VALID_CERTIFICATE_PEM_DATA.length;
- }
- baos.write(Arrays.copyOfRange(VALID_CERTIFICATE_PEM_DATA, offset, end));
- baos.write('\n');
- offset += lineLength;
- if (offset >= maxLineLength) {
- baos.write(VALID_CERTIFICATE_PEM_FOOTER);
- try {
- Certificate c =
- cf.generateCertificate(new ByteArrayInputStream(baos.toByteArray()));
- assertNotNull(c);
- } catch (Exception e) {
- throw new Exception("Fail at line length " + lineLength, e);
- }
- baos.reset();
- baos.write(VALID_CERTIFICATE_PEM_HEADER);
- offset = 0;
- } else {
- lineLength++;
- }
- }
-
- }
-
- private void test_generateCertificate_InputStream_Empty(CertificateFactory cf) throws Exception {
- try {
- Certificate c = cf.generateCertificate(new ByteArrayInputStream(new byte[0]));
- if (!"BC".equals(cf.getProvider().getName())) {
- fail("should throw CertificateException: " + cf.getProvider().getName());
- }
- assertNull(c);
- } catch (CertificateException e) {
- if ("BC".equals(cf.getProvider().getName())) {
- fail("should return null: " + cf.getProvider().getName());
- }
- }
- }
-
- private void test_generateCertificate_InputStream_InvalidStart_Failure(CertificateFactory cf)
- throws Exception {
- try {
- Certificate c = cf.generateCertificate(new ByteArrayInputStream(
- "-----BEGIN CERTIFICATE-----".getBytes(UTF_8)));
- if (!"BC".equals(cf.getProvider().getName())) {
- fail("should throw CertificateException: " + cf.getProvider().getName());
- }
- assertNull(c);
- } catch (CertificateException expected) {
- if ("BC".equals(cf.getProvider().getName())) {
- fail("should return null: " + cf.getProvider().getName());
- }
- }
- }
-
- private void test_generateCertificate_InputStream_Offset_Correct(CertificateFactory cf)
- throws Exception {
- byte[] valid = VALID_CERTIFICATE_PEM.getBytes(UTF_8);
-
- byte[] doubleCertificateData = new byte[valid.length * 2];
- System.arraycopy(valid, 0, doubleCertificateData, 0, valid.length);
- System.arraycopy(valid, 0, doubleCertificateData, valid.length, valid.length);
- MeasuredInputStream certStream = new MeasuredInputStream(new ByteArrayInputStream(
- doubleCertificateData));
- Certificate certificate = cf.generateCertificate(certStream);
- assertNotNull(certificate);
- assertEquals(valid.length, certStream.getCount());
- }
-
- /**
- * Proxy that counts the number of bytes read from an InputStream.
- */
- private static class MeasuredInputStream extends InputStream {
- private long mCount = 0;
-
- private long mMarked = 0;
-
- private InputStream mStream;
-
- public MeasuredInputStream(InputStream is) {
- mStream = is;
- }
-
- public long getCount() {
- return mCount;
- }
-
- @Override
- public int read() throws IOException {
- int nextByte = mStream.read();
- mCount++;
- return nextByte;
- }
-
- @Override
- public int read(byte[] buffer) throws IOException {
- int count = mStream.read(buffer);
- mCount += count;
- return count;
- }
-
- @Override
- public int read(byte[] buffer, int offset, int length) throws IOException {
- int count = mStream.read(buffer, offset, length);
- mCount += count;
- return count;
- }
-
- @Override
- public long skip(long byteCount) throws IOException {
- long count = mStream.skip(byteCount);
- mCount += count;
- return count;
- }
-
- @Override
- public int available() throws IOException {
- return mStream.available();
- }
-
- @Override
- public void close() throws IOException {
- mStream.close();
- }
-
- @Override
- public void mark(int readlimit) {
- mMarked = mCount;
- mStream.mark(readlimit);
- }
-
- @Override
- public boolean markSupported() {
- return mStream.markSupported();
- }
-
- @Override
- public synchronized void reset() throws IOException {
- mCount = mMarked;
- mStream.reset();
- }
- }
-
- /* CertPath tests */
- public void testGenerateCertPath() throws Exception {
- KeyHolder ca = generateCertificate(true, null);
- KeyHolder cert1 = generateCertificate(true, ca);
- KeyHolder cert2 = generateCertificate(false, cert1);
- KeyHolder cert3 = generateCertificate(false, cert2);
-
- List<X509Certificate> certs = new ArrayList<X509Certificate>();
- certs.add(cert3.certificate);
- certs.add(cert2.certificate);
- certs.add(cert1.certificate);
-
- List<X509Certificate> duplicatedCerts = new ArrayList<X509Certificate>(certs);
- duplicatedCerts.add(cert2.certificate);
-
- Provider[] providers = Security.getProviders("CertificateFactory.X509");
- for (Provider p : providers) {
- final CertificateFactory cf = CertificateFactory.getInstance("X.509", p);
-
- // Duplicate certificates can cause an exception.
- {
- final CertPath duplicatedPath = cf.generateCertPath(duplicatedCerts);
- try {
- duplicatedPath.getEncoded();
- if (StandardNames.IS_RI) {
- fail("duplicate certificates should cause failure: " + p.getName());
- }
- } catch (CertificateEncodingException expected) {
- if (!StandardNames.IS_RI) {
- fail("duplicate certificates should pass: " + p.getName());
- }
- }
- }
-
- testCertPathEncoding(cf, certs, null);
-
- /* Make sure all encoding entries are the same. */
- final Iterator<String> it1 = cf.getCertPathEncodings();
- final Iterator<String> it2 = cf.generateCertPath(certs).getEncodings();
- for (;;) {
- assertEquals(p.getName(), it1.hasNext(), it2.hasNext());
- if (!it1.hasNext()) {
- break;
- }
-
- String encoding = it1.next();
- assertEquals(p.getName(), encoding, it2.next());
-
- try {
- it1.remove();
- fail("Should not be able to remove from iterator");
- } catch (UnsupportedOperationException expected) {
- }
-
- try {
- it2.remove();
- fail("Should not be able to remove from iterator");
- } catch (UnsupportedOperationException expected) {
- }
-
- /* Now test using this encoding. */
- testCertPathEncoding(cf, certs, encoding);
- }
- }
- }
-
- private void testCertPathEncoding(CertificateFactory cf, List<X509Certificate> expectedCerts,
- String encoding) throws Exception {
- final String providerName = cf.getProvider().getName() + "[" + encoding + "]";
-
- final CertPath pathFromList = cf.generateCertPath(expectedCerts);
-
- // Create a copy we can modify and discard.
- final byte[] encodedCopy;
- if (encoding == null) {
- encodedCopy = pathFromList.getEncoded();
- assertNotNull(providerName, encodedCopy);
-
- // check idempotence
- assertEquals(providerName, Arrays.toString(pathFromList.getEncoded()),
- Arrays.toString(encodedCopy));
- } else {
- encodedCopy = pathFromList.getEncoded(encoding);
- assertNotNull(providerName, encodedCopy);
-
- // check idempotence
- assertEquals(providerName, Arrays.toString(pathFromList.getEncoded(encoding)),
- Arrays.toString(encodedCopy));
- }
-
- // Try to modify byte array.
- encodedCopy[0] ^= (byte) 0xFF;
-
- // Get a real copy we will use if the test proceeds.
- final byte[] encoded;
- if (encoding == null) {
- encoded = pathFromList.getEncoded();
- assertNotNull(providerName, encodedCopy);
-
- // check idempotence
- assertEquals(providerName, Arrays.toString(pathFromList.getEncoded()),
- Arrays.toString(encoded));
- } else {
- encoded = pathFromList.getEncoded(encoding);
- assertNotNull(providerName, encodedCopy);
-
- // check idempotence
- assertEquals(providerName, Arrays.toString(pathFromList.getEncoded(encoding)),
- Arrays.toString(encoded));
- }
- assertFalse(providerName, Arrays.toString(encoded).equals(Arrays.toString(encodedCopy)));
-
- encodedCopy[0] ^= (byte) 0xFF;
- assertEquals(providerName, Arrays.toString(encoded), Arrays.toString(encodedCopy));
-
- final CertPath actualPath;
- if (encoding == null) {
- actualPath = cf.generateCertPath(new ByteArrayInputStream(encoded));
- } else {
- actualPath = cf.generateCertPath(new ByteArrayInputStream(encoded), encoding);
- }
-
- // PKCS7 certificate bags are not guaranteed to be in order.
- final List<? extends Certificate> actualCerts;
- if (!"PKCS7".equals(encoding)) {
- actualCerts = actualPath.getCertificates();
- assertEquals(providerName, expectedCerts, actualCerts);
- } else {
- actualCerts = pathFromList.getCertificates();
- }
-
- try {
- actualCerts.remove(0);
- fail("List of certificate should be immutable");
- } catch (UnsupportedOperationException expected) {
- }
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(actualPath);
- oos.close();
-
- byte[] serialized = baos.toByteArray();
- ByteArrayInputStream bais = new ByteArrayInputStream(serialized);
- ObjectInputStream ois = new ObjectInputStream(bais);
- Object output = ois.readObject();
- assertTrue(providerName, output instanceof CertPath);
-
- assertEquals(providerName, actualPath, (CertPath) output);
- }
-
- public static class KeyHolder {
- public X509Certificate certificate;
-
- public PrivateKey privateKey;
- }
-
- @SuppressWarnings("deprecation")
- private static KeyHolder generateCertificate(boolean isCa, KeyHolder issuer) throws Exception {
- Date startDate = new Date();
-
- GregorianCalendar cal = new GregorianCalendar();
- cal.setTimeZone(TimeZone.getTimeZone("UTC"));
- cal.set(2100, 0, 1, 0, 0, 0); // Jan 1, 2100 UTC
- Date expiryDate = cal.getTime();
-
- KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
- KeyPair keyPair = kpg.generateKeyPair();
-
- BigInteger serial;
- X500Principal issuerPrincipal;
- X500Principal subjectPrincipal;
- PrivateKey caKey;
- if (issuer != null) {
- serial = issuer.certificate.getSerialNumber().add(BigInteger.ONE);
- subjectPrincipal = new X500Principal("CN=Test Certificate Serial #" + serial.toString());
- issuerPrincipal = issuer.certificate.getSubjectX500Principal();
- caKey = issuer.privateKey;
- } else {
- serial = BigInteger.ONE;
- subjectPrincipal = new X500Principal("CN=Test CA, O=Tests, C=US");
- issuerPrincipal = subjectPrincipal;
- caKey = keyPair.getPrivate();
- }
-
- BasicConstraints basicConstraints;
- if (isCa) {
- basicConstraints = new BasicConstraints(10 - serial.intValue());
- } else {
- basicConstraints = new BasicConstraints(false);
- }
-
- X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
-
- PublicKey pubKey = keyPair.getPublic();
- certGen.setSerialNumber(serial);
- certGen.setIssuerDN(issuerPrincipal);
- certGen.setNotBefore(startDate);
- certGen.setNotAfter(expiryDate);
- certGen.setSubjectDN(subjectPrincipal);
- certGen.setPublicKey(pubKey);
- certGen.setSignatureAlgorithm("SHA1withRSA");
-
- if (issuer != null) {
- certGen.addExtension(Extension.authorityKeyIdentifier, false,
- new AuthorityKeyIdentifierStructure(issuer.certificate));
- } else {
- certGen.addExtension(Extension.authorityKeyIdentifier, false,
- new AuthorityKeyIdentifier(generatePublicKeyDigest(pubKey)));
- }
-
- certGen.addExtension(Extension.subjectKeyIdentifier, false,
- new SubjectKeyIdentifier(generatePublicKeyDigest(pubKey)));
- certGen.addExtension(Extension.basicConstraints, true, basicConstraints);
-
- X509Certificate cert = certGen.generate(caKey);
-
- KeyHolder holder = new KeyHolder();
- holder.certificate = cert;
- holder.privateKey = keyPair.getPrivate();
-
- return holder;
- }
-
- /**
- * Generates a type 1 key identifier according to RFC 3280 4.2.1.2.
- */
- private static byte[] generatePublicKeyDigest(PublicKey pubKey) {
- SubjectPublicKeyInfo spki = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded());
- MessageDigest sha1digest;
- try {
- sha1digest = MessageDigest.getInstance("SHA-1");
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("SHA-1 not available");
- }
- return sha1digest.digest(spki.getPublicKeyData().getBytes());
- }
-}
diff --git a/luni/src/test/java/libcore/java/security/spec/AlgorithmParametersPSSTest.java b/luni/src/test/java/libcore/java/security/spec/AlgorithmParametersPSSTest.java
index 7c60b87..7b725bb 100644
--- a/luni/src/test/java/libcore/java/security/spec/AlgorithmParametersPSSTest.java
+++ b/luni/src/test/java/libcore/java/security/spec/AlgorithmParametersPSSTest.java
@@ -40,15 +40,8 @@
private static final byte[] DEFAULT_SPEC_DER_ENCODED = HexEncoding.decode("3000");
private static final PSSParameterSpec WEIRD_SPEC =
- new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA384, 27, 3);
- private static final byte[] WEIRD_SPEC_DER_ENCODED =
- HexEncoding.decode(
- "3039a00f300d06096086480165030402030500a11c301a06092a864886f70d010108300d060960"
- + "86480165030402020500a20302011ba303020103");
-
- private static final PSSParameterSpec WEIRD2_SPEC =
new PSSParameterSpec("SHA-224", "MGF1", MGF1ParameterSpec.SHA256, 32, 1);
- private static final byte[] WEIRD2_SPEC_DER_ENCODED =
+ private static final byte[] WEIRD_SPEC_DER_ENCODED =
HexEncoding.decode(
"3034a00f300d06096086480165030402040500a11c301a06092a864886f70d010108300d060960"
+ "86480165030402010500a203020120");
@@ -107,7 +100,6 @@
public void testInitWithDerEncoded() throws Exception {
assertInitWithDerEncoded(WEIRD_SPEC_DER_ENCODED, WEIRD_SPEC);
assertInitWithDerEncoded(DEFAULT_SPEC_DER_ENCODED, DEFAULT_SPEC);
- assertInitWithDerEncoded(WEIRD2_SPEC_DER_ENCODED, WEIRD2_SPEC);
}
private void assertInitWithDerEncoded(
@@ -136,7 +128,6 @@
public void testGetEncoded() throws Exception {
assertGetEncoded(WEIRD_SPEC, WEIRD_SPEC_DER_ENCODED);
assertGetEncoded(DEFAULT_SPEC, DEFAULT_SPEC_DER_ENCODED);
- assertGetEncoded(WEIRD2_SPEC, WEIRD2_SPEC_DER_ENCODED);
}
private void assertGetEncoded(PSSParameterSpec spec, byte[] expectedEncoded) throws Exception {
diff --git a/luni/src/test/java/libcore/java/text/DecimalFormatTest.java b/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
index 65f566e..740e7a5 100644
--- a/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
@@ -283,6 +283,34 @@
assertEquals(expected, numberFormat.format(2.01));
}
+ /**
+ * Test no extra spacing between currency symbol and the numeric amount
+ */
+ public void testCurrencySymbolSpacing() {
+ Currency currency = Currency.getInstance(Locale.US);
+ for (Locale locale : Locale.getAvailableLocales()) {
+ DecimalFormatSymbols dfs = new DecimalFormatSymbols(locale);
+ String formattedZero = new DecimalFormat("0", dfs).format(0);
+
+ assertCurrencyFormat("USD" + formattedZero, "\u00a4\u00a40", dfs, currency, locale);
+ assertCurrencyFormat(formattedZero + "USD", "0\u00a4\u00a4", dfs, currency, locale);
+ assertCurrencyFormat(currency.getSymbol(locale) + formattedZero, "\u00a40", dfs,
+ currency, locale);
+ assertCurrencyFormat(formattedZero + currency.getSymbol(locale), "0\u00a4", dfs,
+ currency, locale);
+ }
+ }
+
+ private static void assertCurrencyFormat(String expected, String pattern,
+ DecimalFormatSymbols dfs,
+ Currency currency, Locale locale) {
+ DecimalFormat df = new DecimalFormat(pattern, dfs);
+ df.setCurrency(currency);
+ df.setMaximumFractionDigits(0);
+ assertEquals("Not formatted as expected with pattern " + pattern + " in locale " + locale,
+ expected, df.format(0));
+ }
+
// http://b/27855939
public void testBug27855939() {
DecimalFormat df = new DecimalFormat("00");
@@ -544,6 +572,31 @@
}
/**
+ * Pattern separator should be localized. http://b/112080617
+ */
+ public void testPatternSeparator() {
+ // Test US locale
+ {
+ DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ assertEquals(';', df.getDecimalFormatSymbols().getPatternSeparator());
+ // toLocalizedPattern() returns no pattern separator when input pattern has no prefix.
+ // Add prefixes 'AAA'/'BBB' to force pattern separator in output pattern.
+ df.applyLocalizedPattern("'AAA'+0;'BBB'-0");
+ assertEquals("'AAA'+#0;'BBB'-#0", df.toLocalizedPattern());
+ assertEquals("BBB-123", df.format(-123));
+ }
+ // Test a locale using non-ascii-semi-colon pattern separator.
+ {
+ DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(
+ Locale.forLanguageTag("ar-EG"));
+ assertEquals('\u061b', df.getDecimalFormatSymbols().getPatternSeparator());
+ df.applyLocalizedPattern("'AAA'+\u0660\u061b'BBB'-\u0660");
+ assertEquals("'AAA'+#\u0660\u061b'BBB'-#\u0660", df.toLocalizedPattern());
+ assertEquals("BBB-\u0661\u0662\u0663", df.format(-123));
+ }
+ }
+
+ /**
* Returns DecimalFormat instances created in different ways:
* <ol>
* <li>Using an implicit DecimalFormatSymbols created using the default locale.</li>
@@ -602,6 +655,33 @@
assertParseError(" 0", "1");
}
+ // Test that getMaximumIntegerDigits should return value >= 309 by default, even though a
+ // leading optional digit # is provided in the input pattern. 309 is chosen because
+ // it is the upper limit of integer digits when formatting numbers other than BigInteger
+ // and BigDecimal.
+ public void testDefaultGetMaximumIntegerDigits() {
+ Locale originalLocale = Locale.getDefault();
+ try {
+ Locale.setDefault(Locale.US);
+ DecimalFormat df = new DecimalFormat();
+ int maxIntegerDigits = df.getMaximumIntegerDigits();
+ assertTrue("getMaximumIntegerDigits should be >= 309, but returns " + maxIntegerDigits,
+ maxIntegerDigits >= 309);
+
+ String[] patterns = new String[] { "0", "#0", "#.", "#", ".#", "#.#", "#,##0.00",
+ "#,##0.00%", "#,##0.00%", "¤#,##0.00%", "#00.00", "#,#00.00"
+ };
+ for (String pattern : patterns) {
+ df = new DecimalFormat(pattern);
+ maxIntegerDigits = df.getMaximumIntegerDigits();
+ assertTrue("getMaximumIntegerDigits should be >= 309, but returns "
+ + maxIntegerDigits, maxIntegerDigits >= 309);
+ }
+ } finally {
+ Locale.setDefault(originalLocale);
+ }
+ }
+
private void assertParseError(String pattern, String input) {
ParsePosition pos = new ParsePosition(0);
diff --git a/luni/src/test/java/libcore/java/util/ArraysTest.java b/luni/src/test/java/libcore/java/util/ArraysTest.java
index 2c9d5c5..b48e8ea 100644
--- a/luni/src/test/java/libcore/java/util/ArraysTest.java
+++ b/luni/src/test/java/libcore/java/util/ArraysTest.java
@@ -534,4 +534,11 @@
} catch (IllegalArgumentException expected) {
}
}
+
+ // http://b/74236526
+ public void test_deepEquals_nestedArraysOfDifferentTypesButEqualValues() {
+ assertTrue(Arrays.deepEquals(
+ new Object[] { new Object[] { "Hello", "world" } },
+ new Object[] { new String[] { "Hello", "world" } }));
+ }
}
diff --git a/luni/src/test/java/libcore/java/util/CalendarTest.java b/luni/src/test/java/libcore/java/util/CalendarTest.java
index c828a08..cdeab95 100644
--- a/luni/src/test/java/libcore/java/util/CalendarTest.java
+++ b/luni/src/test/java/libcore/java/util/CalendarTest.java
@@ -48,7 +48,7 @@
// get(Calendar.ZONE_OFFSET) returns the zone offset of the time zone passed to setTimeZone.
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.US);
assertEquals(0, cal.get(Calendar.ZONE_OFFSET));
- TimeZone tz = java.util.TimeZone.getTimeZone("GMT+7");
+ TimeZone tz = TimeZone.getTimeZone("GMT+7");
cal.setTimeZone(tz);
assertEquals(25200000, cal.get(Calendar.ZONE_OFFSET));
}
@@ -418,4 +418,16 @@
}
}
+
+ /**
+ * Ensures that Gregorian is the default Calendar for all Locales in Android. This is the
+ * historic behavior on Android; this test exists to avoid unintentional regressions.
+ * http://b/80294184
+ */
+ public void testAllDefaultCalendar_Gregorian() {
+ for (Locale locale : Locale.getAvailableLocales()) {
+ assertTrue("Default calendar should be Gregorian: " + locale,
+ Calendar.getInstance(locale) instanceof GregorianCalendar);
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/java/util/LocaleTest.java b/luni/src/test/java/libcore/java/util/LocaleTest.java
index 969402b..33e427c 100644
--- a/luni/src/test/java/libcore/java/util/LocaleTest.java
+++ b/luni/src/test/java/libcore/java/util/LocaleTest.java
@@ -130,6 +130,30 @@
Locale.forLanguageTag("zh-Hant-CN-VARIANT").getDisplayName(Locale.US));
}
+ public void testGetDisplayCountry_locale_null() {
+ assertThrowsNpe(() -> {
+ Locale.forLanguageTag("en-US").getDisplayCountry(null);
+ });
+ }
+
+ public void testGetDisplayLanguage_locale_null() {
+ assertThrowsNpe(() -> {
+ Locale.forLanguageTag("en-US").getDisplayLanguage(null);
+ });
+ }
+
+ public void testGetDisplayScript_locale_null() {
+ assertThrowsNpe(() -> {
+ Locale.forLanguageTag("sr-Cyrl-BA").getDisplayScript(null);
+ });
+ }
+
+ public void testGetDisplayVariant_locale_null() {
+ assertThrowsNpe(() -> {
+ Locale.forLanguageTag("en-US-POSIX").getDisplayVariant(null);
+ });
+ }
+
public void test_getDisplayCountry_8870289() throws Exception {
assertEquals("Hong Kong", new Locale("", "HK").getDisplayCountry(Locale.US));
assertEquals("Macau", new Locale("", "MO").getDisplayCountry(Locale.US));
@@ -220,6 +244,25 @@
assertEquals(1, count);
}
+ /**
+ * Check that the straightforward ways to try to construct/obtain a Locale
+ * with null country don't work.
+ */
+ public void test_nullCountry_fails() {
+ try {
+ new Locale(/* language */ "en", /* country */ null);
+ } catch (NullPointerException expected) {
+ }
+ try {
+ new Locale(/* language */ "en", /* country */ null, /* variant */ "EN");
+ } catch (NullPointerException expected) {
+ }
+ assertNotNull(Locale.getDefault().getCountry());
+ for (Locale locale : Locale.getAvailableLocales()) {
+ assertNotNull(locale.getCountry());
+ }
+ }
+
public void test_getISO3Country() {
// Empty country code.
assertEquals("", new Locale("en", "").getISO3Country());
diff --git a/luni/src/test/java/libcore/java/util/TimeZoneTest.java b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
index bf4c8e0..058309f 100644
--- a/luni/src/test/java/libcore/java/util/TimeZoneTest.java
+++ b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
@@ -20,17 +20,11 @@
import java.text.SimpleDateFormat;
import java.time.ZoneId;
-import java.util.ArrayList;
import java.util.Calendar;
-import java.util.Collections;
import java.util.Date;
-import java.util.List;
import java.util.Locale;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
-import java.util.concurrent.BrokenBarrierException;
-import java.util.concurrent.CyclicBarrier;
-import java.util.concurrent.atomic.AtomicInteger;
public class TimeZoneTest extends TestCase {
// http://code.google.com/p/android/issues/detail?id=877
@@ -65,6 +59,14 @@
// http://code.google.com/p/android/issues/detail?id=14395
public void testPreHistoricInDaylightTime() throws Exception {
+ // Originally this test was intended to assert what happens when the first transition for a
+ // time zone was a "to DST" transition. i.e. that the (implicit) offset / DST state before
+ // the first was treated as a non-DST state. Since zic version 2014c all zones have an
+ // explicit non-DST transition at time -2^31 seconds so it is no longer possible to test.
+ // This regression test has been kept in case that changes again in future and to prove the
+ // behavior has remained consistent. The comment below in this test that assume the old
+ // transitions is now incorrect.
+
Locale.setDefault(Locale.US);
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
TimeZone.setDefault(tz);
@@ -88,33 +90,38 @@
}
public void testPreHistoricOffsets() throws Exception {
- // "Africa/Bissau" has just a few transitions and hasn't changed in a long time.
- // 1912-01-01 00:02:19-0100 ... 1912-01-01 00:02:20-0100
- // 1974-12-31 23:59:59-0100 ... 1975-01-01 01:00:00+0000
+ // "Africa/Bissau" has just a few transitions and hasn't changed in a long time:
+ // Transition time : Offset : DST / non-DST : Comment
+ // 1901-12-13 20:45:52 GMT : -01:02:20 : non-DST : This entry included by zic > 2014b
+ // 1912-01-01 01:00:00 GMT : -01:00:00 : non-DST :
+ // 1975-01-01 01:00:00 GMT : 00:00:00 : non-DST :
TimeZone tz = TimeZone.getTimeZone("Africa/Bissau");
// Times before our first transition should assume we're still following that transition.
- assertNonDaylightOffset(-3600, parseIsoTime("1911-01-01T00:00:00.0+0000"), tz);
+ assertNonDaylightOffset(-3740, parseIsoTime("1901-12-13T00:00:00.0+0000"), tz);
- assertNonDaylightOffset(-3600, parseIsoTime("1912-01-01T12:00:00.0-0100"), tz);
+ // Times just after our first transition work as you would expect.
+ assertNonDaylightOffset(-3740, parseIsoTime("1902-12-13T20:45:53.0+0000"), tz);
// Times after our last transition should assume we're still following that transition.
assertNonDaylightOffset(0, parseIsoTime("1980-01-01T00:00:00.0+0000"), tz);
}
- private static void assertNonDaylightOffset(int expectedOffsetSeconds, long epochSeconds, TimeZone tz) {
- assertEquals(expectedOffsetSeconds, tz.getOffset(epochSeconds * 1000) / 1000);
- assertFalse(tz.inDaylightTime(new Date(epochSeconds * 1000)));
+ private static void assertNonDaylightOffset(
+ int expectedOffsetSeconds, long epochMillis, TimeZone tz) {
+ assertEquals(expectedOffsetSeconds, tz.getOffset(epochMillis) / 1000);
+ assertFalse(tz.inDaylightTime(new Date(epochMillis)));
}
private static long parseIsoTime(String isoTime) throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
Date date = sdf.parse(isoTime);
- return date.getTime() / 1000;
+ return date.getTime();
}
- public void testZeroTransitionZones() throws Exception {
- // Zones with no transitions historical or future seem ideal for testing.
+ public void testMinimalTransitionZones() throws Exception {
+ // Zones with minimal transitions, historical or future, seem ideal for testing.
+ // UTC is also included, although it may be implemented differently from the others.
String[] ids = new String[] { "Africa/Bujumbura", "Indian/Cocos", "Pacific/Wake", "UTC" };
for (String id : ids) {
TimeZone tz = TimeZone.getTimeZone(id);
@@ -288,31 +295,6 @@
assertEquals("", failures.toString());
}
- // http://b/30527513
- public void testDisplayNamesWithScript() throws Exception {
- Locale latinLocale = Locale.forLanguageTag("sr-Latn-RS");
- Locale cyrillicLocale = Locale.forLanguageTag("sr-Cyrl-RS");
- Locale noScriptLocale = Locale.forLanguageTag("sr-RS");
- TimeZone tz = TimeZone.getTimeZone("Europe/London");
-
- final String latinName = "Srednje vreme po Griniču";
- final String cyrillicName = "Средње време по Гриничу";
-
- // Check java.util.TimeZone
- assertEquals(latinName, tz.getDisplayName(latinLocale));
- assertEquals(cyrillicName, tz.getDisplayName(cyrillicLocale));
- assertEquals(cyrillicName, tz.getDisplayName(noScriptLocale));
-
- // Check ICU TimeZoneNames
- // The one-argument getDisplayName() override uses LONG_GENERIC style which is different
- // from what java.util.TimeZone uses. Force the LONG style to get equivalent results.
- final int style = android.icu.util.TimeZone.LONG;
- android.icu.util.TimeZone utz = android.icu.util.TimeZone.getTimeZone(tz.getID());
- assertEquals(latinName, utz.getDisplayName(false, style, latinLocale));
- assertEquals(cyrillicName, utz.getDisplayName(false, style, cyrillicLocale));
- assertEquals(cyrillicName, utz.getDisplayName(false, style, noScriptLocale));
- }
-
// http://b/7955614
public void testApia() throws Exception {
TimeZone tz = TimeZone.getTimeZone("Pacific/Apia");
@@ -342,16 +324,19 @@
// http://b/18839557
public void testOverflowing32BitUnixDates() {
+ // This timezone didn't have any daylight savings prior to 1917.
final TimeZone tz = TimeZone.getTimeZone("America/New_York");
- // This timezone didn't have any daylight savings prior to 1917 and this
- // date is sometime in 1901.
- assertFalse(tz.inDaylightTime(new Date(-2206292400000L)));
- assertEquals(-18000000, tz.getOffset(-2206292400000L));
+ // This value is outside of the 32-bit range.
+ long upperTime = 2206292400000L; // Wed, 30 Nov 2039 19:00:00 GMT
+ long lowerTime = -upperTime; // Thu, 01 Feb 1900 05:00:00 GMT
- // Nov 30th 2039, no daylight savings as per current rules.
- assertFalse(tz.inDaylightTime(new Date(2206292400000L)));
- assertEquals(-18000000, tz.getOffset(2206292400000L));
+ assertFalse(tz.inDaylightTime(new Date(lowerTime)));
+ assertEquals(-18000000, tz.getOffset(lowerTime));
+
+ // No daylight savings according to the rules at the time of writing.
+ assertFalse(tz.inDaylightTime(new Date(upperTime)));
+ assertEquals(-18000000, tz.getOffset(upperTime));
}
public void testTimeZoneIDLocalization() {
@@ -368,22 +353,6 @@
}
}
- // http://b/28949992
- public void testSetDefaultAppliesToIcuTimezone() {
- TimeZone origTz = TimeZone.getDefault();
- try {
- android.icu.util.TimeZone origIcuTz = android.icu.util.TimeZone.getDefault();
- assertEquals(origTz.getID(), origIcuTz.getID());
-
- TimeZone tz = TimeZone.getTimeZone("GMT-05:00");
- TimeZone.setDefault(tz);
- android.icu.util.TimeZone icuTz = android.icu.util.TimeZone.getDefault();
- assertEquals(tz.getID(), icuTz.getID());
- } finally {
- TimeZone.setDefault(origTz);
- }
- }
-
// http://b/33197219
public void testDisplayNameForNonCanonicalTimezones() {
TimeZone canonical = TimeZone.getTimeZone("Europe/London");
@@ -395,107 +364,4 @@
assertEquals(canonical.getDisplayName(true, TimeZone.LONG, Locale.ENGLISH),
nonCanonical.getDisplayName(true, TimeZone.LONG, Locale.ENGLISH));
}
-
- // http://b/30937209
- public void testSetDefaultDeadlock() throws InterruptedException, BrokenBarrierException {
- // Since this tests a deadlock, the test has two fundamental problems:
- // - it is probabilistic: it's not guaranteed to fail if the problem exists
- // - if it fails, it will effectively hang the current runtime, as no other thread will
- // be able to call TimeZone.getDefault()/setDefault() successfully any more.
-
- // 10 was too low to be reliable, 100 failed more than half the time (on a bullhead).
- final int iterations = 100;
- TimeZone otherTimeZone = TimeZone.getTimeZone("Europe/London");
- AtomicInteger setterCount = new AtomicInteger();
- CyclicBarrier startBarrier = new CyclicBarrier(2);
- Thread setter = new Thread(() -> {
- waitFor(startBarrier);
- for (int i = 0; i < iterations; i++) {
- TimeZone.setDefault(otherTimeZone);
- TimeZone.setDefault(null);
- setterCount.set(i+1);
- }
- });
- setter.setName("testSetDefaultDeadlock setter");
-
- AtomicInteger getterCount = new AtomicInteger();
- Thread getter = new Thread(() -> {
- waitFor(startBarrier);
- for (int i = 0; i < iterations; i++) {
- android.icu.util.TimeZone.getDefault();
- getterCount.set(i+1);
- }
- });
- getter.setName("testSetDefaultDeadlock getter");
-
- setter.start();
- getter.start();
-
- // 2 seconds is plenty: If successful, we usually complete much faster.
- setter.join(1000);
- getter.join(1000);
- if (setter.isAlive() || getter.isAlive()) {
- fail("Threads are still alive. Getter iteration count: " + getterCount.get()
- + ", setter iteration count: " + setterCount.get());
- }
- // Guard against unexpected uncaught exceptions.
- assertEquals("Setter iterations", iterations, setterCount.get());
- assertEquals("Getter iterations", iterations, getterCount.get());
- }
-
- // http://b/30979219
- public void testSetDefaultRace() throws InterruptedException {
- // Since this tests a race condition, the test is probabilistic: it's not guaranteed to
- // fail if the problem exists
-
- // These iterations are significantly faster than the ones in #testSetDefaultDeadlock
- final int iterations = 10000;
- List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<>());
- Thread.UncaughtExceptionHandler handler = (t, e) -> exceptions.add(e);
-
- CyclicBarrier startBarrier = new CyclicBarrier(2);
- Thread clearer = new Thread(() -> {
- waitFor(startBarrier);
- for (int i = 0; i < iterations; i++) {
- // This is not public API but can effectively be invoked via
- // java.util.TimeZone.setDefault. Call it directly to reduce the amount of code
- // involved in this test.
- android.icu.util.TimeZone.setICUDefault(null);
- }
- });
- clearer.setName("testSetDefaultRace clearer");
- clearer.setUncaughtExceptionHandler(handler);
-
- Thread getter = new Thread(() -> {
- waitFor(startBarrier);
- for (int i = 0; i < iterations; i++) {
- android.icu.util.TimeZone.getDefault();
- }
- });
- getter.setName("testSetDefaultRace getter");
- getter.setUncaughtExceptionHandler(handler);
-
- clearer.start();
- getter.start();
-
- // 20 seconds is plenty: If successful, we usually complete much faster.
- clearer.join(10000);
- getter.join(10000);
-
- if (!exceptions.isEmpty()) {
- Throwable firstException = exceptions.get(0);
- firstException.printStackTrace();
- fail("Threads did not succeed successfully: " + firstException);
- }
- assertFalse("clearer thread is still alive", clearer.isAlive());
- assertFalse("getter thread is still alive", getter.isAlive());
- }
-
- private static void waitFor(CyclicBarrier barrier) {
- try {
- barrier.await();
- } catch (InterruptedException | BrokenBarrierException e) {
- throw new RuntimeException(e);
- }
- }
}
diff --git a/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java b/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java
index 399093a..dc617c3 100644
--- a/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java
+++ b/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java
@@ -177,6 +177,20 @@
}
}
+ public void test_startI_groupIndexOutOfBounds() {
+ Matcher matcher = Pattern.compile("(Hello)").matcher("Hello, world!");
+ assertTrue(matcher.find());
+ try {
+ matcher.start(-1 /* out of bounds */);
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ matcher.start(2 /* out of bounds */);
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
public void test_endI() {
String testPattern = "(((abb)a)(bb))";
String testString = "cccabbabbabbabbabb";
@@ -199,6 +213,19 @@
}
}
+ public void test_endI_groupIndexOutOfBounds() {
+ Matcher matcher = Pattern.compile("(Hello)").matcher("Hello, world!");
+ assertTrue(matcher.find());
+ try {
+ matcher.end(-1 /* out of bounds */);
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ matcher.end(2 /* out of bounds */);
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
public void test_lookingAt() {
String testPattern = "(((abb)a)(bb))";
diff --git a/luni/src/test/java/libcore/java/util/zip/AbstractZipFileTest.java b/luni/src/test/java/libcore/java/util/zip/AbstractZipFileTest.java
index 3d5440e..9157a0c 100644
--- a/luni/src/test/java/libcore/java/util/zip/AbstractZipFileTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/AbstractZipFileTest.java
@@ -484,28 +484,16 @@
}
/**
- * RI does not allow reading of an empty zip using a {@link ZipFile}.
+ * RI does allow reading of an empty zip using a {@link ZipFile}.
*/
- public void testConstructorFailsWhenReadingEmptyZipArchive() throws IOException {
+ public void testConstructorWorksWhenReadingEmptyZipArchive() throws IOException {
File resources = Support_Resources.createTempFolder();
File emptyZip = Support_Resources.copyFile(
resources, "java/util/zip", "EmptyArchive.zip");
- try {
- // The following should fail with an exception but if it doesn't then we need to clean
- // up the resource so we need a reference to it.
- ZipFile zipFile = new ZipFile(emptyZip);
-
- // Clean up the resource.
- try {
- zipFile.close();
- } catch (Exception e) {
- // Ignore
- }
- fail();
- } catch (ZipException expected) {
- // expected
+ try (ZipFile zipFile = new ZipFile(emptyZip)) {
+ assertEquals(0, zipFile.size());
}
}
@@ -633,4 +621,19 @@
is.close();
zipFile.close();
}
+
+ public void testReadTruncatedZipFile() throws IOException {
+ final File f = createTemporaryZipFile();
+ try (FileOutputStream fos = new FileOutputStream(f)) {
+ // Byte representation of lower 4 bytes of ZipConstants.LOCSIG in little endian order.
+ byte[] bytes = new byte[] {0x50, 0x4b, 0x03, 0x04};
+ fos.write(bytes);
+ }
+
+ try (ZipFile zipFile = new ZipFile(f)) {
+ fail("Should not be possible to open the ZipFile as it is too short");
+ } catch (ZipException e) {
+ // expected
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java
index d9f3fe4..19ee2b93 100644
--- a/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java
@@ -202,6 +202,16 @@
}
}
+ public void testNonGzipData() {
+ byte[] data = new byte[100];
+ try (InputStream is = new GZIPInputStream(new ByteArrayInputStream(data), data.length)) {
+ fail();
+ } catch (IOException expected) {
+ // Zeroes do not match the GZIPInputStream.GZIP_MAGIC number.
+ assertEquals("Not in GZIP format", expected.getMessage());
+ }
+ }
+
/**
* Test a openJdk8 fix for case where GZIPInputStream.readTrailer may accidently
* close the input stream if trailing bytes looks "close" enough. Wrapping GZIP in
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java
index fa85f9a..d3d6357 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java
@@ -16,10 +16,12 @@
package libcore.java.util.zip;
+import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
@@ -72,22 +74,20 @@
}
/**
- * Reference implementation does NOT allow writing of an empty zip using a
- * {@link ZipOutputStream}.
+ * Reference implementation does allow writing of an empty zip using a {@link ZipOutputStream}.
+ *
+ * See JDK-6440786.
*/
- @DisableResourceLeakageDetection(
- why = "InflaterOutputStream.close() does not work properly if finish() throws an"
- + " exception; finish() throws an exception if the output is invalid.",
- bug = "31797037")
public void testCreateEmpty() throws IOException {
File result = File.createTempFile("ZipFileTest", "zip");
ZipOutputStream out =
new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(result)));
- try {
- out.close();
- fail("Close on empty stream failed to throw exception");
- } catch (ZipException e) {
- // expected
+ out.close();
+
+ // Verify that the empty zip file can be read back using ZipInputStream.
+ try (ZipInputStream in = new ZipInputStream(
+ new BufferedInputStream(new FileInputStream(result)))) {
+ assertNull(in.getNextEntry());
}
}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java
deleted file mode 100644
index aed6ce8..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2009 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.spec;
-
-import tests.security.AlgorithmParameterGeneratorTest;
-import tests.security.AlgorithmParameterKeyAgreementHelper;
-
-public class AlgorithmParameterGeneratorTestDH extends
- AlgorithmParameterGeneratorTest {
-
- public AlgorithmParameterGeneratorTestDH() {
- super("DH", new AlgorithmParameterKeyAgreementHelper("DH"));
- }
-
- @Override
- public void testAlgorithmParameterGenerator() throws Exception {
- super.testAlgorithmParameterGenerator();
- }
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDSA.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDSA.java
deleted file mode 100644
index 834de6c..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDSA.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 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.spec;
-
-import java.security.spec.DSAParameterSpec;
-import tests.security.AlgorithmParameterGeneratorTest;
-import tests.security.AlgorithmParameterSignatureHelper;
-
-public class AlgorithmParameterGeneratorTestDSA extends
- AlgorithmParameterGeneratorTest {
-
- public AlgorithmParameterGeneratorTestDSA() {
- super("DSA", new AlgorithmParameterSignatureHelper<DSAParameterSpec>("DSA", DSAParameterSpec.class));
- }
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestAES.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestAES.java
deleted file mode 100644
index ae87ca5..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestAES.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2009 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.spec;
-
-import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.util.Arrays;
-import java.util.Base64;
-import javax.crypto.spec.IvParameterSpec;
-import tests.security.AlgorithmParameterSymmetricHelper;
-import tests.security.AlgorithmParametersTest;
-
-public class AlgorithmParametersTestAES extends AlgorithmParametersTest {
-
- private static final byte[] parameterData = new byte[] {
- (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
- (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5,
- (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
- (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5 };
-
- // See README.ASN1 for how to understand and reproduce this data
-
- // asn1=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5040868C8
- private static final String ENCODED_DATA = "BBAECGjI/2Ry9QQIaMj/ZHL1";
-
- public AlgorithmParametersTestAES() {
- super("AES", new AlgorithmParameterSymmetricHelper("AES", "CBC/PKCS5PADDING", 128), new IvParameterSpec(parameterData));
- }
-
- public void testEncoding() throws Exception {
- for (Provider p : Security.getProviders()) {
- AlgorithmParameters params;
- try {
- params = AlgorithmParameters.getInstance("AES", p);
- } catch (NoSuchAlgorithmException e) {
- // This provider doesn't support AES, ignore
- continue;
- }
-
- params.init(new IvParameterSpec(parameterData));
- assertEquals("Provider: " + p.getName(),
- ENCODED_DATA, Base64.getEncoder().encodeToString(params.getEncoded()));
-
- params = AlgorithmParameters.getInstance("AES", p);
- params.init(Base64.getDecoder().decode(ENCODED_DATA));
- assertTrue("Provider: " + p.getName(),
- Arrays.equals(parameterData,
- params.getParameterSpec(IvParameterSpec.class).getIV()));
- }
- }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDES.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDES.java
deleted file mode 100644
index e59ba3f..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDES.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2009 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.spec;
-
-import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.util.Arrays;
-import java.util.Base64;
-import javax.crypto.spec.IvParameterSpec;
-import tests.security.AlgorithmParameterSymmetricHelper;
-import tests.security.AlgorithmParametersTest;
-
-public class AlgorithmParametersTestDES extends AlgorithmParametersTest {
-
- private static final byte[] parameterData = new byte[] {
- (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
- (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5 };
-
- // See README.ASN1 for how to understand and reproduce this data
-
- // asn1=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5
- private static final String ENCODED_DATA = "BAgECGjI/2Ry9Q==";
-
- public AlgorithmParametersTestDES() {
- super("DES", new AlgorithmParameterSymmetricHelper("DES", "CBC/PKCS5PADDING", 56), new IvParameterSpec(parameterData));
- }
-
- public void testEncoding() throws Exception {
- for (Provider p : Security.getProviders()) {
- AlgorithmParameters params;
- try {
- params = AlgorithmParameters.getInstance("DES", p);
- } catch (NoSuchAlgorithmException e) {
- // This provider doesn't support DES, ignore
- continue;
- }
-
- params.init(new IvParameterSpec(parameterData));
- assertEquals("Provider: " + p.getName(),
- ENCODED_DATA, Base64.getEncoder().encodeToString(params.getEncoded()));
-
- params = AlgorithmParameters.getInstance("DES", p);
- params.init(Base64.getDecoder().decode(ENCODED_DATA));
- assertTrue("Provider: " + p.getName(),
- Arrays.equals(parameterData,
- params.getParameterSpec(IvParameterSpec.class).getIV()));
- }
- }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDESede.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDESede.java
deleted file mode 100644
index 9cb7c5d..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDESede.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2009 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.spec;
-
-import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.util.Arrays;
-import java.util.Base64;
-import javax.crypto.spec.IvParameterSpec;
-import tests.security.AlgorithmParameterSymmetricHelper;
-import tests.security.AlgorithmParametersTest;
-
-public class AlgorithmParametersTestDESede extends AlgorithmParametersTest {
-
- private static final byte[] parameterData = new byte[] {
- (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
- (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5 };
-
- // See README.ASN1 for how to understand and reproduce this data
-
- // asn1=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5
- private static final String ENCODED_DATA = "BAgECGjI/2Ry9Q==";
-
- public AlgorithmParametersTestDESede() {
- super("DESede", new AlgorithmParameterSymmetricHelper("DESede", "CBC/PKCS5PADDING", 112), new IvParameterSpec(parameterData));
- }
-
- public void testEncoding() throws Exception {
- for (Provider p : Security.getProviders()) {
- AlgorithmParameters params;
- try {
- params = AlgorithmParameters.getInstance("DESede", p);
- } catch (NoSuchAlgorithmException e) {
- // This provider doesn't support DESede, ignore
- continue;
- }
-
- params.init(new IvParameterSpec(parameterData));
- assertEquals("Provider: " + p.getName(),
- ENCODED_DATA, Base64.getEncoder().encodeToString(params.getEncoded()));
-
- params = AlgorithmParameters.getInstance("DESede", p);
- params.init(Base64.getDecoder().decode(ENCODED_DATA));
- assertTrue("Provider: " + p.getName(),
- Arrays.equals(parameterData,
- params.getParameterSpec(IvParameterSpec.class).getIV()));
- }
- }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java
deleted file mode 100644
index 6e62c03..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2009 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.spec;
-
-import java.math.BigInteger;
-import javax.crypto.spec.DHParameterSpec;
-import tests.security.AlgorithmParameterKeyAgreementHelper;
-import tests.security.AlgorithmParametersTest;
-
-public class AlgorithmParametersTestDH extends AlgorithmParametersTest {
-
- private static final byte[] P = new byte[] {
- (byte) 0x00, (byte) 0xB8, (byte) 0xA4, (byte) 0x06, (byte) 0x10,
- (byte) 0xA2, (byte) 0x8B, (byte) 0xD2, (byte) 0xC0, (byte) 0xB6,
- (byte) 0x87, (byte) 0xFF, (byte) 0x15, (byte) 0xBA, (byte) 0x18,
- (byte) 0xE9, (byte) 0x7D, (byte) 0x77, (byte) 0x9F, (byte) 0xAF,
- (byte) 0x6F, (byte) 0x0B, (byte) 0xA4, (byte) 0xB6, (byte) 0x2B,
- (byte) 0x35, (byte) 0xE2, (byte) 0x01, (byte) 0x66, (byte) 0x41,
- (byte) 0x05, (byte) 0xE7, (byte) 0x6A, (byte) 0x62, (byte) 0x19,
- (byte) 0x94, (byte) 0x18, (byte) 0x46, (byte) 0xBA, (byte) 0x60,
- (byte) 0x2E, (byte) 0x5A, (byte) 0x48, (byte) 0x6C, (byte) 0x4B,
- (byte) 0xBF, (byte) 0x8C, (byte) 0xBF, (byte) 0xB9, (byte) 0xEE,
- (byte) 0xCC, (byte) 0x35, (byte) 0x89, (byte) 0x18, (byte) 0x02,
- (byte) 0x18, (byte) 0xFE, (byte) 0xF4, (byte) 0x02, (byte) 0x3B,
- (byte) 0x5E, (byte) 0x8A, (byte) 0x42, (byte) 0xB3, (byte) 0x39};
-
- private static final byte[] Q = new byte[] {
- (byte) 0x00, (byte) 0x87, (byte) 0xE2, (byte) 0xD1, (byte) 0x8A,
- (byte) 0x23, (byte) 0x90, (byte) 0x3A, (byte) 0x0F, (byte) 0xC8,
- (byte) 0x38, (byte) 0xA8, (byte) 0x65, (byte) 0x35, (byte) 0x89,
- (byte) 0x4F, (byte) 0x4B, (byte) 0xB3, (byte) 0xBF, (byte) 0x18,
- (byte) 0x3C, (byte) 0x3B, (byte) 0xD8, (byte) 0x72, (byte) 0xC3,
- (byte) 0xCF, (byte) 0xC9, (byte) 0xA7, (byte) 0x39, (byte) 0x7E,
- (byte) 0x9C, (byte) 0x69, (byte) 0xDA, (byte) 0xDE, (byte) 0x8E,
- (byte) 0x96, (byte) 0x9D, (byte) 0x44, (byte) 0xC1, (byte) 0x1E,
- (byte) 0x58, (byte) 0xC7, (byte) 0xFC, (byte) 0x40, (byte) 0x1B,
- (byte) 0xE8, (byte) 0x23, (byte) 0xF3, (byte) 0x6B, (byte) 0x95,
- (byte) 0x68, (byte) 0x29, (byte) 0x93, (byte) 0x35, (byte) 0x05,
- (byte) 0xC5, (byte) 0xCB, (byte) 0xB8, (byte) 0x57, (byte) 0x8F,
- (byte) 0xB9, (byte) 0xC3, (byte) 0x36, (byte) 0x09, (byte) 0x51};
-
- private static final int l = 511;
-
- public AlgorithmParametersTestDH() {
- super("DH", new AlgorithmParameterKeyAgreementHelper("DH"),
- new DHParameterSpec(new BigInteger(P), new BigInteger(Q), l));
-
- }
-
- // Broken Test: Suffers from DH slowness, disabling for now
- @Override
- public void testAlgorithmParameters() throws Exception {
- super.testAlgorithmParameters();
- }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDSA.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDSA.java
deleted file mode 100644
index b524161..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDSA.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2009 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.spec;
-
-import java.math.BigInteger;
-import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.security.spec.DSAParameterSpec;
-import java.util.Base64;
-
-import tests.security.AlgorithmParameterSignatureHelper;
-import tests.security.AlgorithmParametersTest;
-
-public class AlgorithmParametersTestDSA extends AlgorithmParametersTest {
-
- /*
- * Parameters generated with OpenSSL:
- * openssl dsaparam -genkey 1024 -C
- */
- private static final byte[] P = new byte[] {
- (byte) 0xE6, (byte) 0x41, (byte) 0x58, (byte) 0x77, (byte) 0x76,
- (byte) 0x5A, (byte) 0x4A, (byte) 0x53, (byte) 0xF1, (byte) 0xD6,
- (byte) 0xC8, (byte) 0x7D, (byte) 0x67, (byte) 0x1F, (byte) 0x2F,
- (byte) 0xFA, (byte) 0xDE, (byte) 0xB7, (byte) 0xAA, (byte) 0xCD,
- (byte) 0xD7, (byte) 0x5D, (byte) 0xD0, (byte) 0xE9, (byte) 0xB1,
- (byte) 0xDA, (byte) 0xFE, (byte) 0x42, (byte) 0xBE, (byte) 0xCC,
- (byte) 0x42, (byte) 0x52, (byte) 0x2E, (byte) 0x01, (byte) 0xD2,
- (byte) 0x16, (byte) 0xB1, (byte) 0x5B, (byte) 0xC4, (byte) 0x42,
- (byte) 0xF9, (byte) 0x55, (byte) 0x0F, (byte) 0xE2, (byte) 0xD5,
- (byte) 0x01, (byte) 0xD2, (byte) 0x7E, (byte) 0x22, (byte) 0xF6,
- (byte) 0xC1, (byte) 0xFE, (byte) 0x5C, (byte) 0x6A, (byte) 0xCF,
- (byte) 0x82, (byte) 0x1B, (byte) 0x5C, (byte) 0x46, (byte) 0x66,
- (byte) 0x8B, (byte) 0xAF, (byte) 0xDF, (byte) 0x44, (byte) 0xE2,
- (byte) 0x0E, (byte) 0xA3, (byte) 0x58, (byte) 0xF7, (byte) 0xA3,
- (byte) 0x24, (byte) 0xE3, (byte) 0x84, (byte) 0xA6, (byte) 0x16,
- (byte) 0xE0, (byte) 0xCA, (byte) 0x72, (byte) 0x55, (byte) 0x07,
- (byte) 0xA0, (byte) 0x99, (byte) 0x7B, (byte) 0xF8, (byte) 0xB1,
- (byte) 0x5A, (byte) 0x84, (byte) 0x36, (byte) 0x5A, (byte) 0xC8,
- (byte) 0x6A, (byte) 0xFE, (byte) 0xA6, (byte) 0xB4, (byte) 0x1B,
- (byte) 0x3A, (byte) 0x0A, (byte) 0x00, (byte) 0x6B, (byte) 0x72,
- (byte) 0xDC, (byte) 0x0C, (byte) 0xD1, (byte) 0x09, (byte) 0x25,
- (byte) 0x11, (byte) 0x68, (byte) 0x6B, (byte) 0x75, (byte) 0xDE,
- (byte) 0x2C, (byte) 0x1A, (byte) 0xC2, (byte) 0x3A, (byte) 0xCB,
- (byte) 0xA0, (byte) 0x17, (byte) 0xCA, (byte) 0x2D, (byte) 0xEE,
- (byte) 0xA2, (byte) 0x5A, (byte) 0x9D, (byte) 0x1F, (byte) 0x33,
- (byte) 0x1B, (byte) 0x07, (byte) 0x6D,
- };
- private static final byte[] Q = new byte[] {
- (byte) 0x9B, (byte) 0x39, (byte) 0xD0, (byte) 0x02, (byte) 0x0F,
- (byte) 0xE9, (byte) 0x96, (byte) 0x16, (byte) 0xC5, (byte) 0x25,
- (byte) 0xF7, (byte) 0x94, (byte) 0xA9, (byte) 0x2C, (byte) 0xD0,
- (byte) 0x25, (byte) 0x5B, (byte) 0x6E, (byte) 0xE0, (byte) 0x8F,
- };
- private static final byte[] G = new byte[] {
- (byte) 0x5E, (byte) 0x9C, (byte) 0x95, (byte) 0x5F, (byte) 0x7E,
- (byte) 0x91, (byte) 0x47, (byte) 0x4D, (byte) 0x68, (byte) 0xA4,
- (byte) 0x1C, (byte) 0x44, (byte) 0x3B, (byte) 0xEC, (byte) 0x0A,
- (byte) 0x7E, (byte) 0x59, (byte) 0x54, (byte) 0xF7, (byte) 0xEF,
- (byte) 0x42, (byte) 0xFB, (byte) 0x63, (byte) 0x95, (byte) 0x08,
- (byte) 0x2F, (byte) 0x4A, (byte) 0xD3, (byte) 0xBC, (byte) 0x79,
- (byte) 0x9D, (byte) 0xBA, (byte) 0xD8, (byte) 0x8A, (byte) 0x83,
- (byte) 0x84, (byte) 0xAE, (byte) 0x5B, (byte) 0x26, (byte) 0x80,
- (byte) 0xB3, (byte) 0xFB, (byte) 0x9C, (byte) 0xA3, (byte) 0xCF,
- (byte) 0xF4, (byte) 0x0A, (byte) 0xD5, (byte) 0xB6, (byte) 0x65,
- (byte) 0x65, (byte) 0x1A, (byte) 0x4F, (byte) 0xC0, (byte) 0x86,
- (byte) 0x3B, (byte) 0xE6, (byte) 0xFB, (byte) 0x4E, (byte) 0x9E,
- (byte) 0x49, (byte) 0x0A, (byte) 0x8C, (byte) 0x77, (byte) 0x2D,
- (byte) 0x93, (byte) 0x0B, (byte) 0xCA, (byte) 0x81, (byte) 0x07,
- (byte) 0x09, (byte) 0xC4, (byte) 0x71, (byte) 0xFD, (byte) 0xC8,
- (byte) 0xC7, (byte) 0xD1, (byte) 0xA3, (byte) 0xD0, (byte) 0xBB,
- (byte) 0x7D, (byte) 0x92, (byte) 0x74, (byte) 0x8B, (byte) 0x3B,
- (byte) 0x2A, (byte) 0x45, (byte) 0x1F, (byte) 0x5D, (byte) 0x85,
- (byte) 0x90, (byte) 0xE3, (byte) 0xFB, (byte) 0x0E, (byte) 0x16,
- (byte) 0xBA, (byte) 0x8A, (byte) 0xDE, (byte) 0x10, (byte) 0x0F,
- (byte) 0xE0, (byte) 0x0F, (byte) 0x37, (byte) 0xA7, (byte) 0xC1,
- (byte) 0xDC, (byte) 0xBC, (byte) 0x00, (byte) 0xB8, (byte) 0x24,
- (byte) 0x0F, (byte) 0xF6, (byte) 0x5F, (byte) 0xB1, (byte) 0xA8,
- (byte) 0x9A, (byte) 0xDB, (byte) 0x9F, (byte) 0x36, (byte) 0x54,
- (byte) 0x45, (byte) 0xBD, (byte) 0xC0, (byte) 0xE8, (byte) 0x27,
- (byte) 0x82, (byte) 0xC9, (byte) 0x75,
- };
-
- // The ASN.1 module for DSA is defined in RFC 3279 section 3. See README.ASN1 for how
- // to understand and reproduce this data.
-
- // asn1=SEQUENCE:dsa
- // [dsa]
- // p=INT:0xE6415877765A4A53F1D6C87D671F2FFADEB7AACDD75DD0E9B1DAFE42BECC42522E01D216B15BC442F9550FE2D501D27E22F6C1FE5C6ACF821B5C46668BAFDF44E20EA358F7A324E384A616E0CA725507A0997BF8B15A84365AC86AFEA6B41B3A0A006B72DC0CD1092511686B75DE2C1AC23ACBA017CA2DEEA25A9D1F331B076D
- // q=INT:0x9B39D0020FE99616C525F794A92CD0255B6EE08F
- // g=INT:0x5E9C955F7E91474D68A41C443BEC0A7E5954F7EF42FB6395082F4AD3BC799DBAD88A8384AE5B2680B3FB9CA3CFF40AD5B665651A4FC0863BE6FB4E9E490A8C772D930BCA810709C471FDC8C7D1A3D0BB7D92748B3B2A451F5D8590E3FB0E16BA8ADE100FE00F37A7C1DCBC00B8240FF65FB1A89ADB9F365445BDC0E82782C975
- private static final String ENCODED_DATA = "MIIBHgKBgQDmQVh3dlpKU/HWyH1nHy/63reqzddd0Omx2v5"
- + "CvsxCUi4B0haxW8RC+VUP4tUB0n4i9sH+XGrPghtcRmaLr99E4g6jWPejJOOEphbgynJVB6CZe/ixWoQ"
- + "2Wshq/qa0GzoKAGty3AzRCSURaGt13iwawjrLoBfKLe6iWp0fMxsHbQIVAJs50AIP6ZYWxSX3lKks0CV"
- + "bbuCPAoGAXpyVX36RR01opBxEO+wKfllU9+9C+2OVCC9K07x5nbrYioOErlsmgLP7nKPP9ArVtmVlGk/"
- + "Ahjvm+06eSQqMdy2TC8qBBwnEcf3Ix9Gj0Lt9knSLOypFH12FkOP7Dha6it4QD+APN6fB3LwAuCQP9l+"
- + "xqJrbnzZURb3A6CeCyXU=";
-
- public AlgorithmParametersTestDSA() {
- super("DSA", new AlgorithmParameterSignatureHelper<DSAParameterSpec>(
- "DSA", DSAParameterSpec.class), new DSAParameterSpec(
- new BigInteger(1, P), new BigInteger(1, Q), new BigInteger(1, G)));
- }
-
- public void testEncoding() throws Exception {
- for (Provider p : Security.getProviders()) {
- AlgorithmParameters params;
- try {
- params = AlgorithmParameters.getInstance("DSA", p);
- } catch (NoSuchAlgorithmException e) {
- // This provider doesn't support DSA, ignore
- continue;
- }
-
- DSAParameterSpec spec = new DSAParameterSpec(
- new BigInteger(1, P), new BigInteger(1, Q), new BigInteger(1, G));
-
- params.init(spec);
- assertEquals("Provider: " + p.getName(),
- ENCODED_DATA, Base64.getEncoder().encodeToString(params.getEncoded()));
-
- params = AlgorithmParameters.getInstance("DSA", p);
- params.init(Base64.getDecoder().decode(ENCODED_DATA));
- DSAParameterSpec derivedSpec = params.getParameterSpec(DSAParameterSpec.class);
-
- assertEquals("Provider: " + p.getName(), new BigInteger(1, P), derivedSpec.getP());
- assertEquals("Provider: " + p.getName(), new BigInteger(1, Q), derivedSpec.getQ());
- assertEquals("Provider: " + p.getName(), new BigInteger(1, G), derivedSpec.getG());
- }
- }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestGCM.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestGCM.java
deleted file mode 100644
index cb99c9a..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestGCM.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.spec;
-
-import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.util.Arrays;
-import java.util.Base64;
-import javax.crypto.spec.GCMParameterSpec;
-
-import tests.security.AlgorithmParameterSymmetricHelper;
-import tests.security.AlgorithmParametersTest;
-
-public class AlgorithmParametersTestGCM extends AlgorithmParametersTest {
-
- private static final byte[] IV = new byte[] {
- (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
- (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5,
- (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8 };
-
- private static final int TLEN = 96;
-
- // The ASN.1 encoding for GCM params (specified in RFC 5084 section 3.2) specifies
- // a default value of 12 for TLEN, so both values with and without TLEN should work.
- // See README.ASN1 for how to understand and reproduce this data.
-
- // asn1=SEQUENCE:gcm
- // [gcm]
- // iv=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5040868C8
- private static final String ENCODED_DATA_NO_TLEN = "MA4EDAQIaMj/ZHL1BAhoyA==";
-
- // asn1=SEQUENCE:gcm
- // [gcm]
- // iv=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5040868C8
- // tlen=INT:12
- private static final String ENCODED_DATA_TLEN = "MBEEDAQIaMj/ZHL1BAhoyAIBDA==";
-
- public AlgorithmParametersTestGCM() {
- super("GCM", new AlgorithmParameterSymmetricHelper("AES", "GCM/NOPADDING", 128), new GCMParameterSpec(TLEN, IV));
- }
-
- public void testEncoding() throws Exception {
- for (Provider p : Security.getProviders()) {
- AlgorithmParameters params;
- try {
- params = AlgorithmParameters.getInstance("GCM", p);
- } catch (NoSuchAlgorithmException e) {
- // This provider doesn't support AES/GCM, ignore
- continue;
- }
-
- params.init(new GCMParameterSpec(TLEN, IV));
- String encoded = Base64.getEncoder().encodeToString(params.getEncoded());
- assertTrue("Provider: " + p.getName() + ", encoded: " + encoded,
- encoded.equals(ENCODED_DATA_TLEN) || encoded.equals(ENCODED_DATA_NO_TLEN));
-
- params = AlgorithmParameters.getInstance("GCM", p);
- params.init(Base64.getDecoder().decode(ENCODED_DATA_NO_TLEN));
- GCMParameterSpec spec = params.getParameterSpec(GCMParameterSpec.class);
- assertEquals("Provider: " + p.getName(), TLEN, spec.getTLen());
- assertTrue("Provider: " + p.getName(), Arrays.equals(IV, spec.getIV()));
-
- params = AlgorithmParameters.getInstance("GCM", p);
- params.init(Base64.getDecoder().decode(ENCODED_DATA_TLEN));
- spec = params.getParameterSpec(GCMParameterSpec.class);
- assertEquals("Provider: " + p.getName(), TLEN, spec.getTLen());
- assertTrue("Provider: " + p.getName(), Arrays.equals(IV, spec.getIV()));
- }
- }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestOAEP.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestOAEP.java
deleted file mode 100644
index 7123e42..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestOAEP.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2009 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.spec;
-
-import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.security.spec.MGF1ParameterSpec;
-import java.util.Arrays;
-import java.util.Base64;
-import javax.crypto.spec.OAEPParameterSpec;
-import javax.crypto.spec.PSource;
-import tests.security.AlgorithmParameterAsymmetricHelper;
-import tests.security.AlgorithmParametersTest;
-
-public class AlgorithmParametersTestOAEP extends AlgorithmParametersTest {
-
- // The ASN.1 encoding for OAEP params (specified in RFC 4055 section 4.1) specifies
- // default values for all parameters, so we need to consider encodings with those
- // values both explicitly specified and unspecified. When encoding values, it is required
- // that default values are left empty, but implementations must be able to parse explicitly-
- // specified defaults as well.
- //
- // See README.ASN1 for how to understand and reproduce this data.
-
- // asn1=SEQUENCE
- private static final String ENCODED_DATA_ALL_DEFAULTS = "MAA=";
-
- // asn1=SEQUENCE:oaep
- // [oaep]
- // hashFunc=EXP:0,SEQUENCE:sha1
- // maskGenFunc=EXP:1,SEQUENCE:mgf1
- // pSourceFunc=EXP:2,SEQUENCE:pSpecified
- // [mgf1]
- // oid=OID:1.2.840.113549.1.1.8
- // params=SEQUENCE:sha1
- // [pSpecified]
- // oid=OID:1.2.840.113549.1.1.9
- // val=OCTETSTRING:
- // [sha1]
- // oid=OID:sha1
- // params=NULL
- private static final String ENCODED_DATA_EXPLICIT_DEFAULTS =
- "MDigCzAJBgUrDgMCGgUAoRgwFgYJKoZIhvcNAQEIMAkGBSsOAwIaBQCiDzANBgkqhkiG9w0BAQkEAA==";
-
- // Base64 version of ASN.1-encoded data with none of the default values. Specifically:
- // SHA-256 hashFunc, MGF1-SHA-384 maskGenFunc, and [1, 2, 3, 4] pSourceFunc
-
- // asn1=SEQUENCE:oaep
- // [oaep]
- // hashFunc=EXP:0,SEQUENCE:sha256
- // maskGenFunc=EXP:1,SEQUENCE:mgf1
- // pSourceFunc=EXP:2,SEQUENCE:pSpecified
- // [sha256]
- // oid=OID:sha256
- // params=NULL
- // [mgf1]
- // oid=OID:1.2.840.113549.1.1.8
- // params=SEQUENCE:sha384
- // [sha384]
- // oid=OID:sha384
- // params=NULL
- // [pSpecified]
- // oid=OID:1.2.840.113549.1.1.9
- // val=FORMAT:HEX,OCTETSTRING:01020304
- private static final String ENCODED_DATA_NON_DEFAULTS = "MESgDzANBglghkgBZQMEAgEFAKEc"
- + "MBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgIFAKITMBEGCSqGSIb3DQEBCQQEAQIDBA==";
-
- // Base64 version of ASN.1-encoded data with some default and some non-default values.
- // Specifically, SHA-1 hashFunc (default), MGF1-SHA-512 maskGenFunc (non-default),
- // empty pSourceFunc (default)
-
- // asn1=SEQUENCE:oaep
- // [oaep]
- // maskGenFunc=EXP:1,SEQUENCE:mgf1
- // [mgf1]
- // oid=OID:1.2.840.113549.1.1.8
- // params=SEQUENCE:sha512
- // [sha512]
- // oid=OID:sha512
- // params=NULL
- private static final String ENCODED_DATA_MIXED = "MB6hHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIDBQA=";
-
- public AlgorithmParametersTestOAEP() {
- super("OAEP", new AlgorithmParameterAsymmetricHelper("RSA"), new OAEPParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT));
- }
-
- public void testEncoding() throws Exception {
- for (Provider p : Security.getProviders()) {
- AlgorithmParameters params;
- try {
- params = AlgorithmParameters.getInstance("OAEP", p);
- } catch (NoSuchAlgorithmException e) {
- // This provider doesn't support OAEP, ignore
- continue;
- }
-
- OAEPParameterSpec spec = new OAEPParameterSpec(
- "SHA-1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT);
- params.init(spec);
- assertEquals("Provider: " + p.getName(),
- ENCODED_DATA_ALL_DEFAULTS,
- Base64.getEncoder().encodeToString(params.getEncoded()));
-
- params = AlgorithmParameters.getInstance("OAEP", p);
- spec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA384,
- new PSource.PSpecified(new byte[] {1, 2, 3, 4}));
- params.init(spec);
- assertEquals("Provider: " + p.getName(),
- ENCODED_DATA_NON_DEFAULTS,
- Base64.getEncoder().encodeToString(params.getEncoded()));
-
- params = AlgorithmParameters.getInstance("OAEP", p);
- spec = new OAEPParameterSpec(
- "SHA-1", "MGF1", MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT);
- params.init(spec);
- assertEquals("Provider: " + p.getName(),
- ENCODED_DATA_MIXED,
- Base64.getEncoder().encodeToString(params.getEncoded()));
-
- params = AlgorithmParameters.getInstance("OAEP", p);
- params.init(Base64.getDecoder().decode(ENCODED_DATA_ALL_DEFAULTS));
- OAEPParameterSpec producedSpec = params.getParameterSpec(OAEPParameterSpec.class);
-
- assertEquals("Provider: " + p.getName(), "SHA-1", producedSpec.getDigestAlgorithm());
- assertEquals("Provider: " + p.getName(), "MGF1", producedSpec.getMGFAlgorithm());
- assertEquals("Provider: " + p.getName(),
- MGF1ParameterSpec.SHA1.getDigestAlgorithm(),
- ((MGF1ParameterSpec) producedSpec.getMGFParameters()).getDigestAlgorithm());
- assertTrue("Provider: " + p.getName(),
- Arrays.equals(PSource.PSpecified.DEFAULT.getValue(),
- ((PSource.PSpecified) producedSpec.getPSource()).getValue()));
-
- params = AlgorithmParameters.getInstance("OAEP", p);
- params.init(Base64.getDecoder().decode(ENCODED_DATA_EXPLICIT_DEFAULTS));
- producedSpec = params.getParameterSpec(OAEPParameterSpec.class);
-
- assertEquals("Provider: " + p.getName(), "SHA-1", producedSpec.getDigestAlgorithm());
- assertEquals("Provider: " + p.getName(), "MGF1", producedSpec.getMGFAlgorithm());
- assertEquals("Provider: " + p.getName(),
- MGF1ParameterSpec.SHA1.getDigestAlgorithm(),
- ((MGF1ParameterSpec) producedSpec.getMGFParameters()).getDigestAlgorithm());
- assertTrue("Provider: " + p.getName(),
- Arrays.equals(PSource.PSpecified.DEFAULT.getValue(),
- ((PSource.PSpecified) producedSpec.getPSource()).getValue()));
-
- params = AlgorithmParameters.getInstance("OAEP", p);
- params.init(Base64.getDecoder().decode(ENCODED_DATA_NON_DEFAULTS));
- producedSpec = params.getParameterSpec(OAEPParameterSpec.class);
-
- assertEquals("Provider: " + p.getName(), "SHA-256", producedSpec.getDigestAlgorithm());
- assertEquals("Provider: " + p.getName(), "MGF1", producedSpec.getMGFAlgorithm());
- assertEquals("Provider: " + p.getName(),
- MGF1ParameterSpec.SHA384.getDigestAlgorithm(),
- ((MGF1ParameterSpec) producedSpec.getMGFParameters()).getDigestAlgorithm());
- assertTrue("Provider: " + p.getName(),
- Arrays.equals(new byte[] {1, 2, 3, 4},
- ((PSource.PSpecified) producedSpec.getPSource()).getValue()));
-
- params = AlgorithmParameters.getInstance("OAEP", p);
- params.init(Base64.getDecoder().decode(ENCODED_DATA_MIXED));
- producedSpec = params.getParameterSpec(OAEPParameterSpec.class);
-
- assertEquals("Provider: " + p.getName(), "SHA-1", producedSpec.getDigestAlgorithm());
- assertEquals("Provider: " + p.getName(), "MGF1", producedSpec.getMGFAlgorithm());
- assertEquals("Provider: " + p.getName(),
- MGF1ParameterSpec.SHA512.getDigestAlgorithm(),
- ((MGF1ParameterSpec) producedSpec.getMGFParameters()).getDigestAlgorithm());
- assertTrue("Provider: " + p.getName(),
- Arrays.equals(PSource.PSpecified.DEFAULT.getValue(),
- ((PSource.PSpecified) producedSpec.getPSource()).getValue()));
- }
- }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestDH.java
deleted file mode 100644
index 02b4395..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestDH.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2009 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.spec;
-
-import java.security.KeyPair;
-import javax.crypto.spec.DHPrivateKeySpec;
-import javax.crypto.spec.DHPublicKeySpec;
-import tests.security.KeyAgreementHelper;
-import tests.security.KeyFactoryTest;
-
-public class KeyFactoryTestDH extends KeyFactoryTest<DHPublicKeySpec, DHPrivateKeySpec> {
-
- public KeyFactoryTestDH() {
- super("DH", DHPublicKeySpec.class, DHPrivateKeySpec.class);
- }
-
- @Override
- protected void check(KeyPair keyPair) throws Exception {
- new KeyAgreementHelper("DH").test(keyPair);
- }
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestDSA.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestDSA.java
deleted file mode 100644
index 236ad72..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestDSA.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2009 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.spec;
-
-import java.security.KeyPair;
-import java.security.spec.DSAPrivateKeySpec;
-import java.security.spec.DSAPublicKeySpec;
-import tests.security.KeyFactoryTest;
-import tests.security.SignatureHelper;
-
-public class KeyFactoryTestDSA extends
- KeyFactoryTest<DSAPublicKeySpec, DSAPrivateKeySpec> {
-
- public KeyFactoryTestDSA() {
- super("DSA", DSAPublicKeySpec.class, DSAPrivateKeySpec.class);
- }
-
- @Override
- protected void check(KeyPair keyPair) throws Exception {
- new SignatureHelper("DSA").test(keyPair);
- }
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestRSA.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestRSA.java
deleted file mode 100644
index 5e174bd..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestRSA.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2009 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.spec;
-
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.RSAPrivateKeySpec;
-import java.security.spec.RSAPublicKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import tests.security.CipherAsymmetricCryptHelper;
-import tests.security.DefaultKeys;
-import tests.security.KeyFactoryTest;
-
-public class KeyFactoryTestRSA extends
- KeyFactoryTest<RSAPublicKeySpec, RSAPrivateKeySpec> {
-
- @SuppressWarnings("unchecked")
- public KeyFactoryTestRSA() {
- super("RSA", RSAPublicKeySpec.class, RSAPrivateKeySpec.class);
- }
-
- @Override
- protected void check(KeyPair keyPair) throws Exception {
- new CipherAsymmetricCryptHelper("RSA").test(keyPair);
- }
-
- public void testExtraBufferSpace_Private() throws Exception {
- PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
- byte[] encoded = privateKey.getEncoded();
- byte[] longBuffer = new byte[encoded.length + 147];
- System.arraycopy(encoded, 0, longBuffer, 0, encoded.length);
- KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(longBuffer));
- }
-
- public void testExtraBufferSpace_Public() throws Exception {
- PublicKey publicKey = DefaultKeys.getPublicKey("RSA");
- byte[] encoded = publicKey.getEncoded();
- byte[] longBuffer = new byte[encoded.length + 147];
- System.arraycopy(encoded, 0, longBuffer, 0, encoded.length);
- KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(longBuffer));
- }
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java
deleted file mode 100644
index 5a74d68..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2009 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.spec;
-
-import java.security.NoSuchAlgorithmException;
-import tests.security.KeyAgreementHelper;
-import tests.security.KeyPairGeneratorTest;
-
-public class KeyPairGeneratorTestDH extends KeyPairGeneratorTest {
-
- public KeyPairGeneratorTestDH() {
- super("DH", new KeyAgreementHelper("DH"));
- }
-
- // Broken Test: Takes ages due to DH computations. Disabling for now.
- @Override
- public void testKeyPairGenerator() throws Exception {
- super.testKeyPairGenerator();
- }
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDSA.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDSA.java
deleted file mode 100644
index 387ebad..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDSA.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2009 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.spec;
-
-import tests.security.KeyPairGeneratorTest;
-import tests.security.SignatureHelper;
-
-public class KeyPairGeneratorTestDSA extends KeyPairGeneratorTest {
-
- public KeyPairGeneratorTestDSA() {
- super("DSA", new SignatureHelper("DSA"));
- }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestRSA.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestRSA.java
deleted file mode 100644
index 2e928ff..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestRSA.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2009 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.spec;
-
-import tests.security.CipherAsymmetricCryptHelper;
-import tests.security.KeyPairGeneratorTest;
-
-public class KeyPairGeneratorTestRSA extends KeyPairGeneratorTest {
-
- @SuppressWarnings("unchecked")
- public KeyPairGeneratorTestRSA() {
- super("RSA", new CipherAsymmetricCryptHelper("RSA"));
- }
-
-}
-
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/README b/luni/src/test/java/libcore/javax/crypto/spec/README
new file mode 100644
index 0000000..99e97e1
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/crypto/spec/README
@@ -0,0 +1,2 @@
+Most tests for javax.crypto.spec can be found in external/conscrypt.
+They should be updated at http://github.com/google/conscrypt.
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/README.ASN1 b/luni/src/test/java/libcore/javax/crypto/spec/README.ASN1
deleted file mode 100644
index 67ffae3..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/README.ASN1
+++ /dev/null
@@ -1,14 +0,0 @@
-Many tests in this package check the ASN.1 encoding for various kinds of parameters. The openssl
-command line tool can be used to view and encode data in ASN.1.
-
-Test data for encoding tests is preceded by its definition in the OpenSSL generation string
-format described at https://wiki.openssl.org/index.php/Manual:ASN1_generate_nconf(3). To
-reproduce the base64-encoded values in the test files, do:
-
-# Put data definition in a file, eg input.cnf
-openssl asn1parse -genconf input.cnf -out /tmp/asn1.der
-openssl base64 -in /tmp/asn1.der
-
-To view the ASN.1 data encoded in a base64-encoded string, do:
-
-echo 'BASE64-ENCODED DATA HERE' | openssl asn1parse -i
diff --git a/luni/src/test/java/libcore/libcore/icu/ICUCalendarTest.java b/luni/src/test/java/libcore/libcore/icu/ICUCalendarTest.java
new file mode 100644
index 0000000..e01de4d
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/icu/ICUCalendarTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 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.libcore.icu;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.icu.impl.ICUData;
+import android.icu.impl.ICUResourceBundle;
+import android.icu.util.Calendar;
+import android.icu.util.GregorianCalendar;
+import android.icu.util.ULocale;
+
+import org.junit.Test;
+
+/**
+ * Test for Android patches in ICU's calendar.
+ */
+public class ICUCalendarTest {
+
+ /**
+ * Ensures that Gregorian is the default Calendar for all Locales in Android. This is the
+ * historic behavior on Android; this test exists to avoid unintentional regressions.
+ * http://b/80294184
+ */
+ @Test
+ public void testAllDefaultCalendar_Gregorian() {
+ for (ULocale locale : ULocale.getAvailableLocales()) {
+ assertTrue("Default calendar should be Gregorian: " + locale,
+ Calendar.getInstance(locale) instanceof GregorianCalendar);
+ }
+
+ for (ULocale locale : ULocale.getAvailableLocales()) {
+ // Classes, e.g. RelativeDateTimeFormatter, use a different property,
+ // i.e. calendar/default, for calendar type. However, there is no direct way to obtain
+ // the calendar type via the APIs. Verify the property value directly here.
+ ICUResourceBundle bundle = (ICUResourceBundle) ICUResourceBundle.getBundleInstance(
+ ICUData.ICU_BASE_NAME, locale);
+ String calType = bundle.getStringWithFallback("calendar/default");
+ assertEquals("calendar/default should be Gregorian: " + locale, "gregorian", calType);
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/libcore/icu/ICUTest.java b/luni/src/test/java/libcore/libcore/icu/ICUTest.java
index 54bb74b..e67e9a1 100644
--- a/luni/src/test/java/libcore/libcore/icu/ICUTest.java
+++ b/luni/src/test/java/libcore/libcore/icu/ICUTest.java
@@ -16,18 +16,11 @@
package libcore.libcore.icu;
-import android.icu.util.TimeZone;
-
import java.text.BreakIterator;
import java.text.Collator;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
import java.util.Locale;
-import java.util.Set;
import libcore.icu.ICU;
-import libcore.util.TimeZoneFinder;
-import libcore.util.ZoneInfoDB;
public class ICUTest extends junit.framework.TestCase {
public void test_getISOLanguages() throws Exception {
@@ -261,63 +254,4 @@
ICU.setDefaultLocale(initialDefaultLocale);
}
}
-
- /** Confirms that ICU agrees with the rest of libcore about the version of the TZ data in use. */
- public void testTimeZoneDataVersion() {
- String icu4cTzVersion = ICU.getTZDataVersion();
-
- String zoneInfoTzVersion = ZoneInfoDB.getInstance().getVersion();
- assertEquals(icu4cTzVersion, zoneInfoTzVersion);
-
- String icu4jTzVersion = android.icu.util.TimeZone.getTZDataVersion();
- assertEquals(icu4jTzVersion, zoneInfoTzVersion);
-
- String tzLookupTzVersion = TimeZoneFinder.getInstance().getIanaVersion();
- assertEquals(icu4jTzVersion, tzLookupTzVersion);
- }
-
- /**
- * Confirms that ICU can recognize all the time zone IDs used by the ZoneInfoDB data.
- * ICU's IDs may be a superset.
- */
- public void testTimeZoneIdLookup() {
- String[] zoneInfoDbAvailableIds = ZoneInfoDB.getInstance().getAvailableIDs();
-
- // ICU has a known set of IDs. We want ANY because we don't want to filter to ICU's canonical
- // IDs only.
- Set<String> icuAvailableIds = android.icu.util.TimeZone.getAvailableIDs(
- TimeZone.SystemTimeZoneType.ANY, null /* region */, null /* rawOffset */);
-
- List<String> nonIcuAvailableIds = new ArrayList<>();
- List<String> creationFailureIds = new ArrayList<>();
- List<String> noCanonicalLookupIds = new ArrayList<>();
- List<String> nonSystemIds = new ArrayList<>();
- for (String zoneInfoDbId : zoneInfoDbAvailableIds) {
- if (!icuAvailableIds.contains(zoneInfoDbId)) {
- nonIcuAvailableIds.add(zoneInfoDbId);
- }
-
- boolean[] isSystemId = new boolean[1];
- String canonicalId = android.icu.util.TimeZone.getCanonicalID(zoneInfoDbId, isSystemId);
- if (canonicalId == null) {
- noCanonicalLookupIds.add(zoneInfoDbId);
- }
- if (!isSystemId[0]) {
- nonSystemIds.add(zoneInfoDbId);
- }
-
- android.icu.util.TimeZone icuTimeZone = android.icu.util.TimeZone.getTimeZone(zoneInfoDbId);
- if (icuTimeZone.getID().equals(TimeZone.UNKNOWN_ZONE_ID)) {
- creationFailureIds.add(zoneInfoDbId);
- }
- }
- assertTrue("Non-ICU available IDs: " + nonIcuAvailableIds
- + ", creation failed IDs: " + creationFailureIds
- + ", non-system IDs: " + nonSystemIds
- + ", ids without canonical IDs: " + noCanonicalLookupIds,
- nonIcuAvailableIds.isEmpty()
- && creationFailureIds.isEmpty()
- && nonSystemIds.isEmpty()
- && noCanonicalLookupIds.isEmpty());
- }
}
diff --git a/luni/src/test/java/libcore/libcore/icu/TimeZoneIntegrationTest.java b/luni/src/test/java/libcore/libcore/icu/TimeZoneIntegrationTest.java
new file mode 100644
index 0000000..db118ba
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/icu/TimeZoneIntegrationTest.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2018 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.libcore.icu;
+
+import org.junit.Test;
+
+import android.icu.text.TimeZoneNames;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import libcore.icu.ICU;
+import libcore.util.TimeZoneFinder;
+import libcore.util.ZoneInfoDB;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests that compare ICU and libcore time zone behavior and similar cross-cutting concerns.
+ */
+public class TimeZoneIntegrationTest {
+
+ // http://b/28949992
+ @Test
+ public void testJavaSetDefaultAppliesToIcuTimezone() {
+ java.util.TimeZone origTz = java.util.TimeZone.getDefault();
+ try {
+ android.icu.util.TimeZone origIcuTz = android.icu.util.TimeZone.getDefault();
+ assertEquals(origTz.getID(), origIcuTz.getID());
+
+ java.util.TimeZone tz = java.util.TimeZone.getTimeZone("GMT-05:00");
+ java.util.TimeZone.setDefault(tz);
+ android.icu.util.TimeZone icuTz = android.icu.util.TimeZone.getDefault();
+ assertEquals(tz.getID(), icuTz.getID());
+ } finally {
+ java.util.TimeZone.setDefault(origTz);
+ }
+ }
+
+ // http://b/30937209
+ @Test
+ public void testSetDefaultDeadlock() throws InterruptedException, BrokenBarrierException {
+ // Since this tests a deadlock, the test has two fundamental problems:
+ // - it is probabilistic: it's not guaranteed to fail if the problem exists
+ // - if it fails, it will effectively hang the current runtime, as no other thread will
+ // be able to call TimeZone.getDefault()/setDefault() successfully any more.
+
+ // 10 was too low to be reliable, 100 failed more than half the time (on a bullhead).
+ final int iterations = 100;
+ java.util.TimeZone otherTimeZone = java.util.TimeZone.getTimeZone("Europe/London");
+ AtomicInteger setterCount = new AtomicInteger();
+ CyclicBarrier startBarrier = new CyclicBarrier(2);
+ Thread setter = new Thread(() -> {
+ waitFor(startBarrier);
+ for (int i = 0; i < iterations; i++) {
+ java.util.TimeZone.setDefault(otherTimeZone);
+ java.util.TimeZone.setDefault(null);
+ setterCount.set(i+1);
+ }
+ });
+ setter.setName("testSetDefaultDeadlock setter");
+
+ AtomicInteger getterCount = new AtomicInteger();
+ Thread getter = new Thread(() -> {
+ waitFor(startBarrier);
+ for (int i = 0; i < iterations; i++) {
+ android.icu.util.TimeZone.getDefault();
+ getterCount.set(i+1);
+ }
+ });
+ getter.setName("testSetDefaultDeadlock getter");
+
+ setter.start();
+ getter.start();
+
+ // 2 seconds is plenty: If successful, we usually complete much faster.
+ setter.join(1000);
+ getter.join(1000);
+ if (setter.isAlive() || getter.isAlive()) {
+ fail("Threads are still alive. Getter iteration count: " + getterCount.get()
+ + ", setter iteration count: " + setterCount.get());
+ }
+ // Guard against unexpected uncaught exceptions.
+ assertEquals("Setter iterations", iterations, setterCount.get());
+ assertEquals("Getter iterations", iterations, getterCount.get());
+ }
+
+ // http://b/30979219
+ @Test
+ public void testSetDefaultRace() throws InterruptedException {
+ // Since this tests a race condition, the test is probabilistic: it's not guaranteed to
+ // fail if the problem exists
+
+ // These iterations are significantly faster than the ones in #testSetDefaultDeadlock
+ final int iterations = 10000;
+ List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<>());
+ Thread.UncaughtExceptionHandler handler = (t, e) -> exceptions.add(e);
+
+ CyclicBarrier startBarrier = new CyclicBarrier(2);
+ Thread clearer = new Thread(() -> {
+ waitFor(startBarrier);
+ for (int i = 0; i < iterations; i++) {
+ // This is not public API but can effectively be invoked via
+ // java.util.TimeZone.setDefault. Call it directly to reduce the amount of code
+ // involved in this test.
+ android.icu.util.TimeZone.setICUDefault(null);
+ }
+ });
+ clearer.setName("testSetDefaultRace clearer");
+ clearer.setUncaughtExceptionHandler(handler);
+
+ Thread getter = new Thread(() -> {
+ waitFor(startBarrier);
+ for (int i = 0; i < iterations; i++) {
+ android.icu.util.TimeZone.getDefault();
+ }
+ });
+ getter.setName("testSetDefaultRace getter");
+ getter.setUncaughtExceptionHandler(handler);
+
+ clearer.start();
+ getter.start();
+
+ // 20 seconds is plenty: If successful, we usually complete much faster.
+ clearer.join(10000);
+ getter.join(10000);
+
+ if (!exceptions.isEmpty()) {
+ Throwable firstException = exceptions.get(0);
+ firstException.printStackTrace();
+ fail("Threads did not succeed successfully: " + firstException);
+ }
+ assertFalse("clearer thread is still alive", clearer.isAlive());
+ assertFalse("getter thread is still alive", getter.isAlive());
+ }
+
+ private static void waitFor(CyclicBarrier barrier) {
+ try {
+ barrier.await();
+ } catch (InterruptedException | BrokenBarrierException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Confirms that ICU agrees with the rest of libcore about the version of the TZ data in use.
+ */
+ @Test
+ public void testTimeZoneDataVersion() {
+ String icu4cTzVersion = ICU.getTZDataVersion();
+
+ String zoneInfoTzVersion = ZoneInfoDB.getInstance().getVersion();
+ assertEquals(icu4cTzVersion, zoneInfoTzVersion);
+
+ String icu4jTzVersion = android.icu.util.TimeZone.getTZDataVersion();
+ assertEquals(icu4jTzVersion, zoneInfoTzVersion);
+
+ String tzLookupTzVersion = TimeZoneFinder.getInstance().getIanaVersion();
+ assertEquals(icu4jTzVersion, tzLookupTzVersion);
+ }
+
+ /**
+ * Confirms that ICU can recognize all the time zone IDs used by the ZoneInfoDB data.
+ * ICU's IDs may be a superset.
+ */
+ @Test
+ public void testTimeZoneIdLookup() {
+ String[] zoneInfoDbAvailableIds = ZoneInfoDB.getInstance().getAvailableIDs();
+
+ // ICU has a known set of IDs. We want ANY because we don't want to filter to ICU's
+ // canonical IDs only.
+ Set<String> icuAvailableIds = android.icu.util.TimeZone.getAvailableIDs(
+ android.icu.util.TimeZone.SystemTimeZoneType.ANY, null /* region */,
+ null /* rawOffset */);
+
+ List<String> nonIcuAvailableIds = new ArrayList<>();
+ List<String> creationFailureIds = new ArrayList<>();
+ List<String> noCanonicalLookupIds = new ArrayList<>();
+ List<String> nonSystemIds = new ArrayList<>();
+ for (String zoneInfoDbId : zoneInfoDbAvailableIds) {
+ if (!icuAvailableIds.contains(zoneInfoDbId)) {
+ nonIcuAvailableIds.add(zoneInfoDbId);
+ }
+
+ boolean[] isSystemId = new boolean[1];
+ String canonicalId = android.icu.util.TimeZone.getCanonicalID(zoneInfoDbId, isSystemId);
+ if (canonicalId == null) {
+ noCanonicalLookupIds.add(zoneInfoDbId);
+ }
+ if (!isSystemId[0]) {
+ nonSystemIds.add(zoneInfoDbId);
+ }
+
+ android.icu.util.TimeZone icuTimeZone =
+ android.icu.util.TimeZone.getTimeZone(zoneInfoDbId);
+ if (icuTimeZone.getID().equals(android.icu.util.TimeZone.UNKNOWN_ZONE_ID)) {
+ creationFailureIds.add(zoneInfoDbId);
+ }
+ }
+ assertTrue("Non-ICU available IDs: " + nonIcuAvailableIds
+ + ", creation failed IDs: " + creationFailureIds
+ + ", non-system IDs: " + nonSystemIds
+ + ", ids without canonical IDs: " + noCanonicalLookupIds,
+ nonIcuAvailableIds.isEmpty()
+ && creationFailureIds.isEmpty()
+ && nonSystemIds.isEmpty()
+ && noCanonicalLookupIds.isEmpty());
+ }
+
+ // http://b/30527513
+ @Test
+ public void testDisplayNamesWithScript() throws Exception {
+ Locale latinLocale = Locale.forLanguageTag("sr-Latn-RS");
+ Locale cyrillicLocale = Locale.forLanguageTag("sr-Cyrl-RS");
+ Locale noScriptLocale = Locale.forLanguageTag("sr-RS");
+ java.util.TimeZone tz = java.util.TimeZone.getTimeZone("Europe/London");
+
+ final String latinName = "Srednje vreme po Griniču";
+ final String cyrillicName = "Средње време по Гриничу";
+
+ // Check java.util.TimeZone
+ assertEquals(latinName, tz.getDisplayName(latinLocale));
+ assertEquals(cyrillicName, tz.getDisplayName(cyrillicLocale));
+ assertEquals(cyrillicName, tz.getDisplayName(noScriptLocale));
+
+ // Check ICU TimeZoneNames
+ // The one-argument getDisplayName() override uses LONG_GENERIC style which is different
+ // from what java.util.TimeZone uses. Force the LONG style to get equivalent results.
+ final int style = android.icu.util.TimeZone.LONG;
+ android.icu.util.TimeZone utz = android.icu.util.TimeZone.getTimeZone(tz.getID());
+ assertEquals(latinName, utz.getDisplayName(false, style, latinLocale));
+ assertEquals(cyrillicName, utz.getDisplayName(false, style, cyrillicLocale));
+ assertEquals(cyrillicName, utz.getDisplayName(false, style, noScriptLocale));
+ }
+
+ /**
+ * This test is to catch issues with the rules update process that could let the
+ * "negative DST" scheme enter the Android data set for either java.util.TimeZone or
+ * android.icu.util.TimeZone.
+ */
+ @Test
+ public void testDstMeansSummer() {
+ // Ireland was the original example that caused the default IANA upstream tzdata to contain
+ // a zone where DST is in the Winter (since tzdata 2018e, though it was tried in 2018a
+ // first). This change was made to historical and future transitions.
+ //
+ // The upstream reasoning went like this: "Irish *Standard* Time" is summer, so the other
+ // time must be the DST. So, DST is considered to be in the winter and the associated DST
+ // adjustment is negative from the standard time. In the old scheme "Irish Standard Time" /
+ // summer was just modeled as the DST in common with all other global time zones.
+ //
+ // Unfortunately, various users of formatting APIs assume standard and DST times are
+ // consistent and (effectively) that "DST" means "summer". We likely cannot adopt the
+ // concept of a winter DST without risking app compat issues.
+ //
+ // For example, getDisplayName(boolean daylight) has always returned the winter time for
+ // false, and the summer time for true. If we change this then it should be changed on a
+ // major release boundary, with improved APIs (e.g. a version of getDisplayName() that takes
+ // a millis), existing API behavior made dependent on target API version, and after fixing
+ // any platform code that makes incorrect assumptions about DST meaning "1 hour forward".
+
+ final String timeZoneId = "Europe/Dublin";
+ final Locale locale = Locale.UK;
+ // 26 Oct 2015 01:00:00 GMT - one day after the start of "Greenwich Mean Time" in
+ // Europe/Dublin in 2015. An arbitrary historical example of winter in Ireland.
+ final long winterTimeMillis = 1445821200000L;
+ final String winterTimeName = "Greenwich Mean Time";
+ final int winterOffsetRawMillis = 0;
+ final int winterOffsetDstMillis = 0;
+
+ // 30 Mar 2015 01:00:00 GMT - one day after the start of "Irish Standard Time" in
+ // Europe/Dublin in 2015. An arbitrary historical example of summer in Ireland.
+ final long summerTimeMillis = 1427677200000L;
+ final String summerTimeName = "Irish Standard Time";
+ final int summerOffsetRawMillis = 0;
+ final int summerOffsetDstMillis = (int) TimeUnit.HOURS.toMillis(1);
+
+ // There is no common interface between java.util.TimeZone and android.icu.util.TimeZone
+ // so the tests are for each are effectively duplicated.
+
+ // java.util.TimeZone
+ {
+ java.util.TimeZone timeZone = java.util.TimeZone.getTimeZone(timeZoneId);
+ assertTrue(timeZone.useDaylightTime());
+
+ assertFalse(timeZone.inDaylightTime(new Date(winterTimeMillis)));
+ assertTrue(timeZone.inDaylightTime(new Date(summerTimeMillis)));
+
+ assertEquals(winterOffsetRawMillis + winterOffsetDstMillis,
+ timeZone.getOffset(winterTimeMillis));
+ assertEquals(summerOffsetRawMillis + summerOffsetDstMillis,
+ timeZone.getOffset(summerTimeMillis));
+ assertEquals(winterTimeName,
+ timeZone.getDisplayName(false /* daylight */, java.util.TimeZone.LONG,
+ locale));
+ assertEquals(summerTimeName,
+ timeZone.getDisplayName(true /* daylight */, java.util.TimeZone.LONG,
+ locale));
+ }
+
+ // android.icu.util.TimeZone
+ {
+ android.icu.util.TimeZone timeZone = android.icu.util.TimeZone.getTimeZone(timeZoneId);
+ assertTrue(timeZone.useDaylightTime());
+
+ assertFalse(timeZone.inDaylightTime(new Date(winterTimeMillis)));
+ assertTrue(timeZone.inDaylightTime(new Date(summerTimeMillis)));
+
+ assertEquals(winterOffsetRawMillis + winterOffsetDstMillis,
+ timeZone.getOffset(winterTimeMillis));
+ assertEquals(summerOffsetRawMillis + summerOffsetDstMillis,
+ timeZone.getOffset(summerTimeMillis));
+
+ // These methods show the trouble we'd have if callers were to take the output from
+ // inDaylightTime() and pass it to getDisplayName().
+ assertEquals(winterTimeName,
+ timeZone.getDisplayName(false /* daylight */, android.icu.util.TimeZone.LONG,
+ locale));
+ assertEquals(summerTimeName,
+ timeZone.getDisplayName(true /* daylight */, android.icu.util.TimeZone.LONG,
+ locale));
+
+ // APIs not identical to java.util.TimeZone tested below.
+ int[] offsets = new int[2];
+ timeZone.getOffset(winterTimeMillis, false /* local */, offsets);
+ assertEquals(winterOffsetRawMillis, offsets[0]);
+ assertEquals(winterOffsetDstMillis, offsets[1]);
+
+ timeZone.getOffset(summerTimeMillis, false /* local */, offsets);
+ assertEquals(summerOffsetRawMillis, offsets[0]);
+ assertEquals(summerOffsetDstMillis, offsets[1]);
+ }
+
+ // icu TimeZoneNames
+ TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);
+ // getDisplayName: date = winterTimeMillis
+ assertEquals(winterTimeName, timeZoneNames.getDisplayName(
+ timeZoneId, TimeZoneNames.NameType.LONG_STANDARD, winterTimeMillis));
+ assertEquals(summerTimeName, timeZoneNames.getDisplayName(
+ timeZoneId, TimeZoneNames.NameType.LONG_DAYLIGHT, winterTimeMillis));
+ // getDisplayName: date = summerTimeMillis
+ assertEquals(winterTimeName, timeZoneNames.getDisplayName(
+ timeZoneId, TimeZoneNames.NameType.LONG_STANDARD, summerTimeMillis));
+ assertEquals(summerTimeName, timeZoneNames.getDisplayName(
+ timeZoneId, TimeZoneNames.NameType.LONG_DAYLIGHT, summerTimeMillis));
+ }
+}
diff --git a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
index 7015521..aea709f 100644
--- a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
+++ b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
@@ -119,6 +119,10 @@
@Test
public void test_checkNewMethodsInPosix() {
List<String> methodsNotRequireBlockGuardChecks = Arrays.asList(
+ "android_fdsan_exchange_owner_tag(java.io.FileDescriptor,long,long)",
+ "android_fdsan_get_owner_tag(java.io.FileDescriptor)",
+ "android_fdsan_get_tag_type(long)",
+ "android_fdsan_get_tag_value(long)",
"bind(java.io.FileDescriptor,java.net.InetAddress,int)",
"bind(java.io.FileDescriptor,java.net.SocketAddress)",
"capget(android.system.StructCapUserHeader)",
diff --git a/luni/src/test/java/libcore/libcore/io/FdsanTest.java b/luni/src/test/java/libcore/libcore/io/FdsanTest.java
new file mode 100644
index 0000000..354ed11
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/io/FdsanTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2018 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.libcore.io;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.RandomAccessFile;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.DatagramSocket;
+import java.net.ServerSocket;
+import java.net.Socket;
+import junit.framework.TestCase;
+
+import libcore.io.Libcore;
+
+public class FdsanTest extends TestCase {
+ public void testFileInputStream() throws Exception {
+ try (FileInputStream fis = new FileInputStream("/dev/null")) {
+ FileDescriptor fd = fis.getFD();
+ long tag = Libcore.os.android_fdsan_get_owner_tag(fd);
+ assertTrue(tag != FileDescriptor.NO_OWNER);
+ assertEquals("FileInputStream", Libcore.os.android_fdsan_get_tag_type(tag));
+ assertEquals(System.identityHashCode(fis), Libcore.os.android_fdsan_get_tag_value(tag));
+ }
+ }
+
+ public void testFileOutputStream() throws Exception {
+ try (FileOutputStream fis = new FileOutputStream("/dev/null")) {
+ FileDescriptor fd = fis.getFD();
+ long tag = Libcore.os.android_fdsan_get_owner_tag(fd);
+ assertTrue(tag != FileDescriptor.NO_OWNER);
+ assertEquals("FileOutputStream", Libcore.os.android_fdsan_get_tag_type(tag));
+ assertEquals(System.identityHashCode(fis), Libcore.os.android_fdsan_get_tag_value(tag));
+ }
+ }
+
+ public void testRandomAccessFile() throws Exception {
+ try (RandomAccessFile fis = new RandomAccessFile("/dev/null", "r")) {
+ FileDescriptor fd = fis.getFD();
+ long tag = Libcore.os.android_fdsan_get_owner_tag(fd);
+ assertTrue(tag != FileDescriptor.NO_OWNER);
+ assertEquals("RandomAccessFile", Libcore.os.android_fdsan_get_tag_type(tag));
+ assertEquals(System.identityHashCode(fis), Libcore.os.android_fdsan_get_tag_value(tag));
+ }
+ }
+
+ public void testParcelFileDescriptor() throws Exception {
+ Class pfdClass;
+ try {
+ pfdClass = Class.forName("android.os.ParcelFileDescriptor");
+ } catch (ClassNotFoundException ex) {
+ // Don't fail if ParcelFileDescriptor isn't on our classpath, e.g. in ART host tests.
+ return;
+ }
+
+ try (FileInputStream fis = new FileInputStream("/dev/null")) {
+ Method pfdMethodDup = pfdClass.getMethod("dup", FileDescriptor.class);
+ Method pfdMethodClose = pfdClass.getMethod("close");
+ Method pfdMethodGetFileDescriptor = pfdClass.getMethod("getFileDescriptor");
+ Field readonly = pfdClass.getField("MODE_READ_ONLY");
+
+ Object pfd = pfdMethodDup.invoke(null, fis.getFD());
+ FileDescriptor fd = (FileDescriptor)pfdMethodGetFileDescriptor.invoke(pfd);
+ long tag = Libcore.os.android_fdsan_get_owner_tag(fd);
+ assertTrue(tag != FileDescriptor.NO_OWNER);
+ assertEquals("ParcelFileDescriptor", Libcore.os.android_fdsan_get_tag_type(tag));
+ assertEquals(System.identityHashCode(pfd), Libcore.os.android_fdsan_get_tag_value(tag));
+ pfdMethodClose.invoke(pfd);
+ }
+ }
+
+ public void testDatagramSocket() throws Exception {
+ try (DatagramSocket socket = new DatagramSocket()) {
+ FileDescriptor fd = socket.getFileDescriptor$();
+ assertTrue(fd.valid());
+
+ long tag = Libcore.os.android_fdsan_get_owner_tag(fd);
+ assertTrue(tag != FileDescriptor.NO_OWNER);
+ assertEquals("DatagramSocketImpl", Libcore.os.android_fdsan_get_tag_type(tag));
+ assertTrue(Libcore.os.android_fdsan_get_tag_value(tag) != 0);
+ socket.close();
+ }
+ }
+
+ public void assertFdOwnedBySocket(FileDescriptor fd) throws Exception {
+ long tag = Libcore.os.android_fdsan_get_owner_tag(fd);
+ assertTrue(tag != FileDescriptor.NO_OWNER);
+ assertEquals("SocketImpl", Libcore.os.android_fdsan_get_tag_type(tag));
+ assertTrue(Libcore.os.android_fdsan_get_tag_value(tag) != 0);
+ }
+
+ public void testSocket() throws Exception {
+ try (Socket socket = new Socket()) {
+ assertFalse("new Socket shouldn't have an associated FileDescriptor",
+ socket.getFileDescriptor$().valid());
+ }
+
+ int port = 0; // auto-allocate port
+ try (ServerSocket serverSocket = new ServerSocket(port, /* backlog */ 1)) {
+ assertFdOwnedBySocket(serverSocket.getFileDescriptor$());
+
+ Socket client = new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort());
+ Socket server = serverSocket.accept();
+ assertFdOwnedBySocket(client.getFileDescriptor$());
+ assertFdOwnedBySocket(server.getFileDescriptor$());
+ client.close();
+ server.close();
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/libcore/io/OsTest.java b/luni/src/test/java/libcore/libcore/io/OsTest.java
index 5e8a691..aa0a5ba 100644
--- a/luni/src/test/java/libcore/libcore/io/OsTest.java
+++ b/luni/src/test/java/libcore/libcore/io/OsTest.java
@@ -1014,4 +1014,36 @@
Libcore.os.close(pipe[0]);
Libcore.os.close(pipe[1]);
}
+
+ public void testCloseNullFileDescriptor() throws Exception {
+ try {
+ Libcore.rawOs.close(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testSocketpairNullFileDescriptor1() throws Exception {
+ try {
+ Libcore.rawOs.socketpair(AF_UNIX, SOCK_STREAM, 0, null, new FileDescriptor());
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testSocketpairNullFileDescriptor2() throws Exception {
+ try {
+ Libcore.rawOs.socketpair(AF_UNIX, SOCK_STREAM, 0, new FileDescriptor(), null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testSocketpairNullFileDescriptorBoth() throws Exception {
+ try {
+ Libcore.rawOs.socketpair(AF_UNIX, SOCK_STREAM, 0, null, null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java b/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java
index f9ff9df..69344e2 100644
--- a/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java
+++ b/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java
@@ -16,78 +16,133 @@
package libcore.libcore.net;
-import junit.framework.TestCase;
-
import libcore.net.MimeUtils;
+import junit.framework.TestCase;
+
+import java.util.Objects;
+
public class MimeUtilsTest extends TestCase {
- public void test_15715370() {
- assertEquals("audio/flac", MimeUtils.guessMimeTypeFromExtension("flac"));
- assertEquals("flac", MimeUtils.guessExtensionFromMimeType("audio/flac"));
- assertEquals("flac", MimeUtils.guessExtensionFromMimeType("application/x-flac"));
- }
+ public void test_15715370() {
+ assertEquals("audio/flac", MimeUtils.guessMimeTypeFromExtension("flac"));
+ assertEquals("flac", MimeUtils.guessExtensionFromMimeType("audio/flac"));
+ assertEquals("flac", MimeUtils.guessExtensionFromMimeType("application/x-flac"));
+ }
- // https://code.google.com/p/android/issues/detail?id=78909
- public void test_78909() {
- assertEquals("mka", MimeUtils.guessExtensionFromMimeType("audio/x-matroska"));
- assertEquals("mkv", MimeUtils.guessExtensionFromMimeType("video/x-matroska"));
- }
+ // https://code.google.com/p/android/issues/detail?id=78909
+ public void test_78909() {
+ assertEquals("mka", MimeUtils.guessExtensionFromMimeType("audio/x-matroska"));
+ assertEquals("mkv", MimeUtils.guessExtensionFromMimeType("video/x-matroska"));
+ }
- public void test_16978217() {
- assertEquals("image/x-ms-bmp", MimeUtils.guessMimeTypeFromExtension("bmp"));
- assertEquals("image/x-icon", MimeUtils.guessMimeTypeFromExtension("ico"));
- assertEquals("video/mp2ts", MimeUtils.guessMimeTypeFromExtension("ts"));
- }
+ public void test_16978217() {
+ assertEquals("image/x-ms-bmp", MimeUtils.guessMimeTypeFromExtension("bmp"));
+ assertEquals("image/x-icon", MimeUtils.guessMimeTypeFromExtension("ico"));
+ assertEquals("video/mp2ts", MimeUtils.guessMimeTypeFromExtension("ts"));
+ }
- public void testCommon() {
- assertEquals("audio/mpeg", MimeUtils.guessMimeTypeFromExtension("mp3"));
- assertEquals("image/png", MimeUtils.guessMimeTypeFromExtension("png"));
- assertEquals("application/zip", MimeUtils.guessMimeTypeFromExtension("zip"));
+ public void testCommon() {
+ assertEquals("audio/mpeg", MimeUtils.guessMimeTypeFromExtension("mp3"));
+ assertEquals("image/png", MimeUtils.guessMimeTypeFromExtension("png"));
+ assertEquals("application/zip", MimeUtils.guessMimeTypeFromExtension("zip"));
- assertEquals("mp3", MimeUtils.guessExtensionFromMimeType("audio/mpeg"));
- assertEquals("png", MimeUtils.guessExtensionFromMimeType("image/png"));
- assertEquals("zip", MimeUtils.guessExtensionFromMimeType("application/zip"));
- }
+ assertEquals("mp3", MimeUtils.guessExtensionFromMimeType("audio/mpeg"));
+ assertEquals("png", MimeUtils.guessExtensionFromMimeType("image/png"));
+ assertEquals("zip", MimeUtils.guessExtensionFromMimeType("application/zip"));
+ }
- public void test_18390752() {
- assertEquals("jpg", MimeUtils.guessExtensionFromMimeType("image/jpeg"));
- }
+ public void test_18390752() {
+ assertEquals("jpg", MimeUtils.guessExtensionFromMimeType("image/jpeg"));
+ }
- public void test_30207891() {
- assertTrue(MimeUtils.hasMimeType("IMAGE/PNG"));
- assertTrue(MimeUtils.hasMimeType("IMAGE/png"));
- assertFalse(MimeUtils.hasMimeType(""));
- assertEquals("png", MimeUtils.guessExtensionFromMimeType("IMAGE/PNG"));
- assertEquals("png", MimeUtils.guessExtensionFromMimeType("IMAGE/png"));
- assertNull(MimeUtils.guessMimeTypeFromExtension(""));
- assertNull(MimeUtils.guessMimeTypeFromExtension("doesnotexist"));
- assertTrue(MimeUtils.hasExtension("PNG"));
- assertTrue(MimeUtils.hasExtension("PnG"));
- assertFalse(MimeUtils.hasExtension(""));
- assertFalse(MimeUtils.hasExtension(".png"));
- assertEquals("image/png", MimeUtils.guessMimeTypeFromExtension("PNG"));
- assertEquals("image/png", MimeUtils.guessMimeTypeFromExtension("PnG"));
- assertNull(MimeUtils.guessMimeTypeFromExtension(".png"));
- assertNull(MimeUtils.guessMimeTypeFromExtension(""));
- assertNull(MimeUtils.guessExtensionFromMimeType("doesnotexist"));
- }
+ public void test_30207891() {
+ assertTrue(MimeUtils.hasMimeType("IMAGE/PNG"));
+ assertTrue(MimeUtils.hasMimeType("IMAGE/png"));
+ assertFalse(MimeUtils.hasMimeType(""));
+ assertEquals("png", MimeUtils.guessExtensionFromMimeType("IMAGE/PNG"));
+ assertEquals("png", MimeUtils.guessExtensionFromMimeType("IMAGE/png"));
+ assertNull(MimeUtils.guessMimeTypeFromExtension(""));
+ assertNull(MimeUtils.guessMimeTypeFromExtension("doesnotexist"));
+ assertTrue(MimeUtils.hasExtension("PNG"));
+ assertTrue(MimeUtils.hasExtension("PnG"));
+ assertFalse(MimeUtils.hasExtension(""));
+ assertFalse(MimeUtils.hasExtension(".png"));
+ assertEquals("image/png", MimeUtils.guessMimeTypeFromExtension("PNG"));
+ assertEquals("image/png", MimeUtils.guessMimeTypeFromExtension("PnG"));
+ assertNull(MimeUtils.guessMimeTypeFromExtension(".png"));
+ assertNull(MimeUtils.guessMimeTypeFromExtension(""));
+ assertNull(MimeUtils.guessExtensionFromMimeType("doesnotexist"));
+ }
- public void test_30793548() {
- assertEquals("video/3gpp", MimeUtils.guessMimeTypeFromExtension("3gpp"));
- assertEquals("video/3gpp", MimeUtils.guessMimeTypeFromExtension("3gp"));
- assertEquals("video/3gpp2", MimeUtils.guessMimeTypeFromExtension("3gpp2"));
- assertEquals("video/3gpp2", MimeUtils.guessMimeTypeFromExtension("3g2"));
- }
+ public void test_30793548() {
+ assertEquals("video/3gpp", MimeUtils.guessMimeTypeFromExtension("3gpp"));
+ assertEquals("video/3gpp", MimeUtils.guessMimeTypeFromExtension("3gp"));
+ assertEquals("video/3gpp2", MimeUtils.guessMimeTypeFromExtension("3gpp2"));
+ assertEquals("video/3gpp2", MimeUtils.guessMimeTypeFromExtension("3g2"));
+ }
- public void test_37167977() {
- // https://tools.ietf.org/html/rfc5334#section-10.1
- assertEquals("audio/ogg", MimeUtils.guessMimeTypeFromExtension("ogg"));
- assertEquals("audio/ogg", MimeUtils.guessMimeTypeFromExtension("oga"));
- assertEquals("audio/ogg", MimeUtils.guessMimeTypeFromExtension("spx"));
- assertEquals("video/ogg", MimeUtils.guessMimeTypeFromExtension("ogv"));
- }
+ public void test_37167977() {
+ // https://tools.ietf.org/html/rfc5334#section-10.1
+ assertEquals("audio/ogg", MimeUtils.guessMimeTypeFromExtension("ogg"));
+ assertEquals("audio/ogg", MimeUtils.guessMimeTypeFromExtension("oga"));
+ assertEquals("audio/ogg", MimeUtils.guessMimeTypeFromExtension("spx"));
+ assertEquals("video/ogg", MimeUtils.guessMimeTypeFromExtension("ogv"));
+ }
- public void test_70851634() {
- assertEquals("application/vnd.youtube.yt", MimeUtils.guessMimeTypeFromExtension("yt"));
- }
+ public void test_70851634() {
+ assertEquals("application/vnd.youtube.yt", MimeUtils.guessMimeTypeFromExtension("yt"));
+ }
+
+ public void test_112162449_audio() {
+ // According to https://en.wikipedia.org/wiki/M3U#Internet_media_types
+ // this is a giant mess, so we pick "audio/x-mpegurl" because a similar
+ // playlist format uses "audio/x-scpls".
+ assertMimeTypeFromExtension("audio/x-mpegurl", "m3u");
+ assertMimeTypeFromExtension("audio/x-mpegurl", "m3u8");
+ assertExtensionFromMimeType("m3u", "audio/x-mpegurl");
+
+ assertExtensionFromMimeType("m4a", "audio/mp4");
+ assertMimeTypeFromExtension("audio/mpeg", "m4a");
+
+ assertBidirectional("audio/aac", "aac");
+ }
+
+ public void test_112162449_video() {
+ assertBidirectional("video/x-flv", "flv");
+ assertBidirectional("video/quicktime", "mov");
+ assertBidirectional("video/mpeg", "mpeg");
+ }
+
+ public void test_112162449_image() {
+ assertBidirectional("image/heif", "heif");
+ assertBidirectional("image/heif-sequence", "heifs");
+ assertBidirectional("image/heic", "heic");
+ assertBidirectional("image/heic-sequence", "heics");
+ assertMimeTypeFromExtension("image/heif", "hif");
+
+ assertBidirectional("image/x-adobe-dng", "dng");
+ assertBidirectional("image/x-photoshop", "psd");
+
+ assertBidirectional("image/jp2", "jp2");
+ assertMimeTypeFromExtension("image/jp2", "jpg2");
+ }
+
+ private static void assertMimeTypeFromExtension(String mimeType, String extension) {
+ final String actual = MimeUtils.guessMimeTypeFromExtension(extension);
+ if (!Objects.equals(mimeType, actual)) {
+ fail("Expected " + mimeType + " but was " + actual + " for extension " + extension);
+ }
+ }
+
+ private static void assertExtensionFromMimeType(String extension, String mimeType) {
+ final String actual = MimeUtils.guessExtensionFromMimeType(mimeType);
+ if (!Objects.equals(extension, actual)) {
+ fail("Expected " + extension + " but was " + actual + " for type " + mimeType);
+ }
+ }
+
+ private static void assertBidirectional(String mimeType, String extension) {
+ assertMimeTypeFromExtension(mimeType, extension);
+ assertExtensionFromMimeType(extension, mimeType);
+ }
}
diff --git a/luni/src/test/java/libcore/libcore/net/UriCodecTest.java b/luni/src/test/java/libcore/libcore/net/UriCodecTest.java
deleted file mode 100644
index ca8de89..0000000
--- a/luni/src/test/java/libcore/libcore/net/UriCodecTest.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * 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
- */
-
-package libcore.libcore.net;
-
-import junit.framework.TestCase;
-
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import libcore.net.UriCodec;
-
-/**
- * Tests for {@link UriCodec}
- */
-public class UriCodecTest extends TestCase {
- private static final UriCodec CODEC = new UriCodec() {
- @Override
- protected boolean isRetained(char c) {
- return c == '$';
- }
- };
-
- private static final String VALID_ENCODED_STRING = "a0b$CD%01a%23b%45c%67%89%abd%cd%efq";
-
- public void testValidate_stringOK_passes() throws Exception {
- assertEquals(
- VALID_ENCODED_STRING,
- CODEC.validate(
- VALID_ENCODED_STRING, 0, VALID_ENCODED_STRING.length(), "test OK string"));
- }
-
- // Hex codes in upper case are valid as well.
- public void testValidate_stringUppercaseOK_passes() throws Exception {
- String stringOKUpperCase = VALID_ENCODED_STRING.toUpperCase();
- CODEC.validate(stringOKUpperCase, 0, stringOKUpperCase.length(), "test OK UC string");
- }
-
- // Characters before the start index are ignored.
- public void testValidate_wrongCharsBeforeStart_passes() throws Exception {
- assertEquals(VALID_ENCODED_STRING, CODEC.validate(
- "%p" + VALID_ENCODED_STRING,
- 2,
- VALID_ENCODED_STRING.length() + 2,
- "test string"));
- }
-
- // Fails with character 'p', invalid after '%'
- public void testValidate_wrongCharsAtStart_fails() throws Exception {
- try {
- CODEC.validate(
- "%p" + VALID_ENCODED_STRING,
- 0,
- VALID_ENCODED_STRING.length() + 2,
- "test string");
- fail("Expected URISyntaxException");
- } catch (URISyntaxException expected) {
- // Expected.
- }
- }
-
- // Fails with character 'p', invalid after '%'
- public void testValidate_wrongCharsBeyondEnd_passes() throws Exception {
- assertEquals(VALID_ENCODED_STRING, CODEC.validate(
- VALID_ENCODED_STRING + "%p",
- 0,
- VALID_ENCODED_STRING.length(),
- "test string"));
- }
-
- // Fails with character 'p', invalid after '%'
- public void testValidate_wrongCharsAtEnd_fails() throws Exception {
- try {
- CODEC.validate(
- VALID_ENCODED_STRING + "%p",
- 0,
- VALID_ENCODED_STRING.length() + 2,
- "test string");
- fail("Expected URISyntaxException");
- } catch (URISyntaxException expected) {
- // Expected.
- }
- }
-
- public void testValidate_secondDigitWrong_fails() throws Exception {
- try {
- CODEC.validate(
- VALID_ENCODED_STRING + "%1p",
- 0,
- VALID_ENCODED_STRING.length() + 2,
- "test string");
- fail("Expected URISyntaxException");
- } catch (URISyntaxException expected) {
- // Expected.
- }
- }
-
- public void testValidate_emptyString_passes() throws Exception {
- assertEquals("", CODEC.validate("", 0, 0, "empty string"));
- }
-
- public void testValidate_stringEndingWithPercent_fails() throws Exception {
- try {
- CODEC.validate("a%", 0, 0, "a% string");
- } catch (URISyntaxException expected) {
- // Expected.
- }
- }
-
- public void testValidate_stringEndingWithPercentAndSingleDigit_fails() throws Exception {
- try {
- CODEC.validate("a%1", 0, 0, "a%1 string");
- } catch (URISyntaxException expected) {
- // Expected.
- }
- }
-
- public void testValidateSimple_stringOK_passes() throws Exception {
- UriCodec.validateSimple(VALID_ENCODED_STRING, "$%");
- }
-
- // Hex codes in upper case are valid as well.
- public void testValidateSimple_stringUppercaseOK_passes() throws Exception {
- UriCodec.validateSimple(VALID_ENCODED_STRING.toUpperCase(), "$%");
- }
-
- // Fails with character 'p', invalid after '%'
- public void testValidateSimple_wrongCharsAtStart_fails() throws Exception {
- try {
- UriCodec.validateSimple("%/" + VALID_ENCODED_STRING, "$%");
- fail("Expected URISyntaxException");
- } catch (URISyntaxException expected) {
- // Expected.
- }
- }
-
- // Fails with character 'p', invalid after '%'
- public void testValidateSimple_wrongCharsAtEnd_fails() throws Exception {
- try {
- UriCodec.validateSimple(VALID_ENCODED_STRING + "%/", "$%");
- fail("Expected URISyntaxException");
- } catch (URISyntaxException expected) {
- // Expected.
- }
- }
-
- public void testValidateSimple_emptyString_passes() throws Exception {
- UriCodec.validateSimple("", "$%");
- }
-
- public void testValidateSimple_stringEndingWithPercent_passes() throws Exception {
- UriCodec.validateSimple("a%", "$%");
- }
-
- public void testValidateSimple_stringEndingWithPercentAndSingleDigit_passes() throws Exception {
- UriCodec.validateSimple("a%1", "$%");
- }
-
- public void testEncode_emptyString_returnsEmptyString() {
- assertEquals("", CODEC.encode("", StandardCharsets.UTF_8));
- }
-
- public void testEncode() {
- assertEquals("ab%2F$%C4%82%2512", CODEC.encode("ab/$\u0102%12", StandardCharsets.UTF_8));
- }
-
- public void testEncode_convertWhitespace() {
- // Whitespace is not retained, output %20.
- assertEquals("ab%2F$%C4%82%2512%20",
- CODEC.encode("ab/$\u0102%12 ", StandardCharsets.UTF_8));
-
- UriCodec withWhitespaceRetained = new UriCodec() {
- @Override
- protected boolean isRetained(char c) {
- return c == '$' || c == ' ';
- }
- };
- // Whitespace is retained, convert to plus.
- assertEquals("ab%2F$%C4%82%2512+",
- withWhitespaceRetained.encode("ab/$\u0102%12 ", StandardCharsets.UTF_8));
- }
-
- /** Confirm that '%' can be retained, disabling '%' encoding. http://b/24806835 */
- public void testEncode_percentRetained() {
- UriCodec withPercentRetained = new UriCodec() {
- @Override
- protected boolean isRetained(char c) {
- return c == '%';
- }
- };
- // Percent is retained
- assertEquals("ab%34%20", withPercentRetained.encode("ab%34 ", StandardCharsets.UTF_8));
- }
-
- public void testEncode_partially_returnsPercentUnchanged() {
- StringBuilder stringBuilder = new StringBuilder();
- // Check it's really appending instead of returning a new builder.
- stringBuilder.append("pp");
- CODEC.appendPartiallyEncoded(stringBuilder, "ab/$\u0102%");
- // Returns % at the end instead of %25.
- assertEquals("ppab%2F$%C4%82%", stringBuilder.toString());
- }
-
- public void testEncode_partially_returnsCharactersAfterPercentEncoded() {
- StringBuilder stringBuilder = new StringBuilder();
- // Check it's really appending instead of returning a new builder.
- stringBuilder.append("pp");
- CODEC.appendPartiallyEncoded(stringBuilder, "ab/$\u0102%\u0102");
- // Returns %C4%82 at the end.
- assertEquals("ppab%2F$%C4%82%%C4%82", stringBuilder.toString());
- }
-
- public void testEncode_partially_returnsDigitsAfterPercentUnchanged() {
- StringBuilder stringBuilder = new StringBuilder();
- // Check it's really appending instead of returning a new builder.
- stringBuilder.append("pp");
- CODEC.appendPartiallyEncoded(stringBuilder, "ab/$\u0102%38");
- // Returns %38 at the end.
- assertEquals("ppab%2F$%C4%82%38", stringBuilder.toString());
- }
-
- // Last character needs encoding (make sure we are flushing the buffer with chars to encode).
- public void testEncode_lastCharacter() {
- assertEquals("ab%2F$%C4%82%25%E0%A1%80",
- CODEC.encode("ab/$\u0102%\u0840", StandardCharsets.UTF_8));
- }
-
- // Last character needs encoding (make sure we are flushing the buffer with chars to encode).
- public void testEncode_flushBufferBeforePlusFromSpace() {
- UriCodec withSpaceRetained = new UriCodec() {
- @Override
- protected boolean isRetained(char c) {
- return c == ' ';
- }
- };
- assertEquals("%2F+",
- withSpaceRetained.encode("/ ", StandardCharsets.UTF_8));
- }
-
- public void testDecode_emptyString_returnsEmptyString() {
- assertEquals("", UriCodec.decode(""));
- }
-
- public void testDecode_wrongHexDigit_fails() {
- try {
- // %p in the end.
- UriCodec.decode("ab%2f$%C4%82%25%e0%a1%80%p");
- fail("Expected URISyntaxException");
- } catch (IllegalArgumentException expected) {
- // Expected.
- }
- }
-
- public void testDecode_secondHexDigitWrong_fails() {
- try {
- // %1p in the end.
- UriCodec.decode("ab%2f$%c4%82%25%e0%a1%80%1p");
- fail("Expected URISyntaxException");
- } catch (IllegalArgumentException expected) {
- // Expected.
- }
- }
-
- public void testDecode_endsWithPercent_fails() {
- try {
- // % in the end.
- UriCodec.decode("ab%2f$%c4%82%25%e0%a1%80%");
- fail("Expected URISyntaxException");
- } catch (IllegalArgumentException expected) {
- // Expected.
- }
- }
-
- public void testDecode_dontThrowException_appendsUnknownCharacter() {
- assertEquals("ab/$\u0102%\u0840\ufffd",
- UriCodec.decode("ab%2f$%c4%82%25%e0%a1%80%",
- false /* convertPlus */,
- StandardCharsets.UTF_8,
- false /* throwOnFailure */));
- }
-
- public void testDecode_convertPlus() {
- assertEquals("ab/$\u0102% \u0840",
- UriCodec.decode("ab%2f$%c4%82%25+%e0%a1%80",
- true /* convertPlus */,
- StandardCharsets.UTF_8,
- false /* throwOnFailure */));
- }
-
- // Last character needs decoding (make sure we are flushing the buffer with chars to decode).
- public void testDecode_lastCharacter() {
- assertEquals("ab/$\u0102%\u0840",
- UriCodec.decode("ab%2f$%c4%82%25%e0%a1%80"));
- }
-
- // Check that a second row of encoded characters is decoded properly (internal buffers are
- // reset properly).
- public void testDecode_secondRowOfEncoded() {
- assertEquals("ab/$\u0102%\u0840aa\u0840",
- UriCodec.decode("ab%2f$%c4%82%25%e0%a1%80aa%e0%a1%80"));
- }
-}
diff --git a/luni/src/test/java/libcore/libcore/util/ArrayUtilsTest.java b/luni/src/test/java/libcore/libcore/util/ArrayUtilsTest.java
new file mode 100644
index 0000000..81f0b01
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/util/ArrayUtilsTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2018 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.libcore.util;
+
+import static libcore.util.ArrayUtils.throwsIfOutOfBounds;
+
+import org.junit.Test;
+
+public class ArrayUtilsTest {
+ @Test
+ public void testThrowsIfOutOfBounds_passesWhenRangeInsideArray() {
+ throwsIfOutOfBounds(10, 2, 6);
+ }
+
+ @Test
+ public void testThrowsIfOutOfBounds_passesWhenRangeIsWholeArray() {
+ throwsIfOutOfBounds(10, 0, 10);
+ }
+
+ @Test
+ public void testThrowsIfOutOfBounds_passesWhenEmptyRangeAtStart() {
+ throwsIfOutOfBounds(10, 0, 0);
+ }
+
+ @Test
+ public void testThrowsIfOutOfBounds_passesWhenEmptyRangeAtEnd() {
+ throwsIfOutOfBounds(10, 10, 0);
+ }
+
+ @Test
+ public void testThrowsIfOutOfBounds_passesWhenEmptyArray() {
+ throwsIfOutOfBounds(0, 0, 0);
+ }
+
+ @Test(expected = ArrayIndexOutOfBoundsException.class)
+ public void testThrowsIfOutOfBounds_failsWhenRangeStartNegative() {
+ throwsIfOutOfBounds(10, -1, 5);
+ }
+
+ @Test(expected = ArrayIndexOutOfBoundsException.class)
+ public void testThrowsIfOutOfBounds_failsWhenCountNegative() {
+ throwsIfOutOfBounds(10, 5, -1);
+ }
+
+ @Test(expected = ArrayIndexOutOfBoundsException.class)
+ public void testThrowsIfOutOfBounds_failsWhenRangeStartTooHigh() {
+ throwsIfOutOfBounds(10, 11, 0);
+ }
+
+
+ @Test(expected = ArrayIndexOutOfBoundsException.class)
+ public void testThrowsIfOutOfBounds_failsWhenRangeEndTooHigh() {
+ throwsIfOutOfBounds(10, 5, 6);
+ }
+
+ @Test(expected = ArrayIndexOutOfBoundsException.class)
+ public void testThrowsIfOutOfBounds_failsWhenLengthNegative() {
+ throwsIfOutOfBounds(-1, 0, 0);
+ }
+
+ @Test(expected = ArrayIndexOutOfBoundsException.class)
+ public void testThrowsIfOutOfBounds_failsWhenOverflowRangeEndTooHigh() {
+ throwsIfOutOfBounds(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
+ }
+}
diff --git a/luni/src/test/java/libcore/sun/misc/SharedSecretsTest.java b/luni/src/test/java/libcore/sun/misc/SharedSecretsTest.java
new file mode 100644
index 0000000..49923a5
--- /dev/null
+++ b/luni/src/test/java/libcore/sun/misc/SharedSecretsTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 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.sun.misc;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import sun.misc.SharedSecrets;
+
+@RunWith(JUnit4.class)
+public class SharedSecretsTest {
+
+ /**
+ * This test doesn't completely rule out race conditions such as http://b/80495283 (between
+ * FileDescriptor and UnixChannelFactory): Even if this test passes by the time it runs, the
+ * condition that it enforces may not have been true earlier in the runtime start.
+ */
+ @Test
+ public void testGetJavaIOFileDescriptorAccess_notNull() {
+ Assert.assertNotNull("SharedSecrets.getJavaIOFileDescriptorAccess can't be null",
+ SharedSecrets.getJavaIOFileDescriptorAccess());
+ }
+}
diff --git a/luni/src/test/java/libcore/xml/KxmlPullParserDtdTest.java b/luni/src/test/java/libcore/xml/KxmlPullParserDtdTest.java
index 3175b37..0803c58 100644
--- a/luni/src/test/java/libcore/xml/KxmlPullParserDtdTest.java
+++ b/luni/src/test/java/libcore/xml/KxmlPullParserDtdTest.java
@@ -16,7 +16,7 @@
package libcore.xml;
-import org.kxml2.io.KXmlParser;
+import com.android.org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
diff --git a/luni/src/test/java/libcore/xml/KxmlPullParserTest.java b/luni/src/test/java/libcore/xml/KxmlPullParserTest.java
index 71f25e9..760668d 100644
--- a/luni/src/test/java/libcore/xml/KxmlPullParserTest.java
+++ b/luni/src/test/java/libcore/xml/KxmlPullParserTest.java
@@ -16,7 +16,7 @@
package libcore.xml;
-import org.kxml2.io.KXmlParser;
+import com.android.org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
public class KxmlPullParserTest extends PullParserTest {
diff --git a/luni/src/test/java/libcore/xml/KxmlSerializerTest.java b/luni/src/test/java/libcore/xml/KxmlSerializerTest.java
index fffb3f1..4c4075b 100644
--- a/luni/src/test/java/libcore/xml/KxmlSerializerTest.java
+++ b/luni/src/test/java/libcore/xml/KxmlSerializerTest.java
@@ -16,11 +16,11 @@
package libcore.xml;
+import com.android.org.kxml2.io.KXmlSerializer;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import junit.framework.TestCase;
-import org.kxml2.io.KXmlSerializer;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
diff --git a/luni/src/test/java/libcore/xml/XmlPullParserFactoryTest.java b/luni/src/test/java/libcore/xml/XmlPullParserFactoryTest.java
index 7194414..0431a16 100644
--- a/luni/src/test/java/libcore/xml/XmlPullParserFactoryTest.java
+++ b/luni/src/test/java/libcore/xml/XmlPullParserFactoryTest.java
@@ -16,14 +16,14 @@
package libcore.xml;
+import com.android.org.kxml2.io.KXmlParser;
+import com.android.org.kxml2.io.KXmlSerializer;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import junit.framework.TestCase;
-import org.kxml2.io.KXmlParser;
-import org.kxml2.io.KXmlSerializer;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
diff --git a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/Matcher2Test.java b/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/Matcher2Test.java
deleted file mode 100644
index 0a64dce..0000000
--- a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/Matcher2Test.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.harmony.regex.tests.java.util.regex;
-
-import junit.framework.TestCase;
-import java.util.regex.*;
-
-/**
- * Tests Matcher methods
- *
- */
-public class Matcher2Test extends TestCase {
-
- public void test_toString() {
- Pattern p = Pattern.compile("foo");
- Matcher m = p.matcher("bar");
- assertNotNull(m.toString());
- }
-
- public void testErrorConditions() throws PatternSyntaxException {
- // Test match cursors in absence of a match
- Pattern p = Pattern.compile("foo");
- Matcher m = p.matcher("bar");
- assertFalse(m.matches());
-
- try {
- m.start();
- fail("IllegalStateException expected");
- } catch (IllegalStateException e) {
- }
-
- try {
- m.end();
- fail("IllegalStateException expected");
- } catch (IllegalStateException e) {
- }
-
- try {
- m.group();
- fail("IllegalStateException expected");
- } catch (IllegalStateException e) {
- }
-
- try {
- m.start(1);
- fail("IllegalStateException expected");
- } catch (IllegalStateException e) {
- }
-
- try {
- m.end(1);
- fail("IllegalStateException expected");
- } catch (IllegalStateException e) {
- }
-
- try {
- m.group(1);
- fail("IllegalStateException expected");
- } catch (IllegalStateException e) {
- }
-
- // regression test for HARMONY-2418
- try {
- m.usePattern(null);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- // PASSED
- }
- }
-
- public void testErrorConditions2() throws PatternSyntaxException {
- // Test match cursors in absence of a match
- Pattern p = Pattern.compile("(foo[0-9])(bar[a-z])");
- Matcher m = p.matcher("foo1barzfoo2baryfoozbar5");
-
- assertTrue(m.find());
- assertEquals(0, m.start());
- assertEquals(8, m.end());
- assertEquals(0, m.start(1));
- assertEquals(4, m.end(1));
- assertEquals(4, m.start(2));
- assertEquals(8, m.end(2));
-
- try {
- m.start(3);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- }
-
- try {
- m.end(3);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- }
-
- try {
- m.group(3);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- }
-
- try {
- m.start(-1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- }
-
- try {
- m.end(-1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- }
-
- try {
- m.group(-1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- }
-
- assertTrue(m.find());
- assertEquals(8, m.start());
- assertEquals(16, m.end());
- assertEquals(8, m.start(1));
- assertEquals(12, m.end(1));
- assertEquals(12, m.start(2));
- assertEquals(16, m.end(2));
-
- try {
- m.start(3);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- }
-
- try {
- m.end(3);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- }
-
- try {
- m.group(3);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- }
-
- try {
- m.start(-1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- }
-
- try {
- m.end(-1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- }
-
- try {
- m.group(-1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- }
-
- assertFalse(m.find());
-
- try {
- m.start(3);
- fail("IllegalStateException expected");
- } catch (IllegalStateException e) {
- }
-
- try {
- m.end(3);
- fail("IllegalStateException expected");
- } catch (IllegalStateException e) {
- }
-
- try {
- m.group(3);
- fail("IllegalStateException expected");
- } catch (IllegalStateException e) {
- }
-
- try {
- m.start(-1);
- fail("IllegalStateException expected");
- } catch (IllegalStateException e) {
- }
-
- try {
- m.end(-1);
- fail("IllegalStateException expected");
- } catch (IllegalStateException e) {
- }
-
- try {
- m.group(-1);
- fail("IllegalStateException expected");
- } catch (IllegalStateException e) {
- }
- }
-
- /*
- * Regression test for HARMONY-997
- */
- public void testReplacementBackSlash() {
- String str = "replace me";
- String replacedString = "me";
- String substitutionString = "\\";
- Pattern pat = Pattern.compile(replacedString);
- Matcher mat = pat.matcher(str);
- try {
- String res = mat.replaceAll(substitutionString);
- fail("IndexOutOfBoundsException should be thrown - " + res);
- } catch (Exception e) {
- }
- }
-}
-
diff --git a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/ModeTest.java b/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/ModeTest.java
deleted file mode 100644
index 569d3e6..0000000
--- a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/ModeTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.harmony.regex.tests.java.util.regex;
-
-import junit.framework.TestCase;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-import java.util.regex.PatternSyntaxException;
-
-/**
- * Tests Pattern compilation modes and modes triggered in pattern strings
- *
- */
-public class ModeTest extends TestCase {
-
- public void testCase() throws PatternSyntaxException {
- Pattern p;
- Matcher m;
-
- p = Pattern.compile("([a-z]+)[0-9]+");
- m = p.matcher("cAT123#dog345");
- assertTrue(m.find());
- assertEquals("dog", m.group(1));
- assertFalse(m.find());
-
-
- p = Pattern.compile("([a-z]+)[0-9]+", Pattern.CASE_INSENSITIVE);
- m = p.matcher("cAt123#doG345");
- assertTrue(m.find());
- assertEquals("cAt", m.group(1));
- assertTrue(m.find());
- assertEquals("doG", m.group(1));
- assertFalse(m.find());
-
-
- p = Pattern.compile("(?i)([a-z]+)[0-9]+");
- m = p.matcher("cAt123#doG345");
- assertTrue(m.find());
- assertEquals("cAt", m.group(1));
- assertTrue(m.find());
- assertEquals("doG", m.group(1));
- assertFalse(m.find());
- }
- public void testMultiline() throws PatternSyntaxException {
- Pattern p;
- Matcher m;
-
- p = Pattern.compile("^foo");
- m = p.matcher("foobar");
- assertTrue(m.find());
- assertTrue(m.start() == 0 && m.end() == 3);
- assertFalse(m.find());
-
- m = p.matcher("barfoo");
- assertFalse(m.find());
-
-
- p = Pattern.compile("foo$");
- m = p.matcher("foobar");
- assertFalse(m.find());
-
- m = p.matcher("barfoo");
- assertTrue(m.find());
- assertTrue(m.start() == 3 && m.end() == 6);
- assertFalse(m.find());
-
-
- p = Pattern.compile("^foo([0-9]*)", Pattern.MULTILINE);
- m = p.matcher("foo1bar\nfoo2foo3\nbarfoo4");
- assertTrue(m.find());
- assertEquals("1", m.group(1));
- assertTrue(m.find());
- assertEquals("2", m.group(1));
- assertFalse(m.find());
-
-
- p = Pattern.compile("foo([0-9]*)$", Pattern.MULTILINE);
- m = p.matcher("foo1bar\nfoo2foo3\nbarfoo4");
- assertTrue(m.find());
- assertEquals("3", m.group(1));
- assertTrue(m.find());
- assertEquals("4", m.group(1));
- assertFalse(m.find());
-
-
- p = Pattern.compile("(?m)^foo([0-9]*)");
- m = p.matcher("foo1bar\nfoo2foo3\nbarfoo4");
- assertTrue(m.find());
- assertEquals("1", m.group(1));
- assertTrue(m.find());
- assertEquals("2", m.group(1));
- assertFalse(m.find());
-
- p = Pattern.compile("(?m)foo([0-9]*)$");
- m = p.matcher("foo1bar\nfoo2foo3\nbarfoo4");
- assertTrue(m.find());
- assertEquals("3", m.group(1));
- assertTrue(m.find());
- assertEquals("4", m.group(1));
- assertFalse(m.find());
- }
-}
diff --git a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java b/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
index 96de6c8..3a56f6a 100644
--- a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
+++ b/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
@@ -18,6 +18,7 @@
package org.apache.harmony.regex.tests.java.util.regex;
import java.io.Serializable;
+import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
@@ -27,6 +28,10 @@
import org.apache.harmony.testframework.serialization.SerializationTest;
import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+import dalvik.system.VMRuntime;
+
+import static java.util.Arrays.asList;
+
public class PatternTest extends TestCase {
String[] testPatterns = {
"(a|b)*abb",
@@ -107,7 +112,7 @@
s = pat.split("", -1);
assertEquals(s.length, 1);
s = pat.split("abccbadfe", -1);
- assertEquals(s.length, 11);
+ assertEquals(s.length, 10);
// zero limit
pat = Pattern.compile("b");
s = pat.split("abccbadfebb", 0);
@@ -118,7 +123,7 @@
s = pat.split("", 0);
assertEquals(s.length, 1);
s = pat.split("abccbadfe", 0);
- assertEquals(s.length, 10);
+ assertEquals(s.length, 9);
// positive limit
pat = Pattern.compile("b");
s = pat.split("abccbadfebb", 12);
@@ -129,7 +134,7 @@
s = pat.split("", 11);
assertEquals(s.length, 1);
s = pat.split("abccbadfe", 15);
- assertEquals(s.length, 11);
+ assertEquals(s.length, 10);
pat = Pattern.compile("b");
s = pat.split("abccbadfebb", 5);
@@ -139,8 +144,8 @@
pat = Pattern.compile("");
s = pat.split("", 1);
assertEquals(s.length, 1);
- s = pat.split("abccbadfe", 11);
- assertEquals(s.length, 11);
+ s = pat.split("abccbadfe", 10);
+ assertEquals(s.length, 10);
pat = Pattern.compile("b");
s = pat.split("abccbadfebb", 3);
@@ -150,6 +155,65 @@
assertEquals(s.length, 5);
}
+ public void testSplitOnEmptyPattern_apiCurrent() {
+ assertEquals(asList("t", "e", "s", "t"), asList("test".split("")));
+ assertEquals(asList(""), asList("".split("")));
+ assertEquals(asList(""), asList(Pattern.compile("").split("")));
+ assertEquals(asList(""), asList("".split("", -1)));
+ }
+
+ public void testSplitOnEmptyPattern_api28() {
+ runWithTargetSdkVersion(28, () -> {
+ assertEquals(asList("", "t", "e", "s", "t"), asList("test".split("")));
+ assertEquals(asList(""), asList("".split("")));
+ assertEquals(asList(""), asList(Pattern.compile("").split("")));
+ assertEquals(asList(""), asList("".split("", -1)));
+ });
+ }
+
+ /**
+ * Tests that a match at the beginning of the input string only produces
+ * a "" if the match is positive-width.
+ */
+ public void testMatchBeginningOfInputSequence_apiCurrent() {
+ // Positive-width match at the beginning of the input.
+ assertEquals(asList("", "", "rdv", "rk"), asList("aardvark".split("a")));
+ assertEquals(asList("", "anana"), asList("banana".split("b")));
+ // Zero-width match at the beginning of the input
+ assertEquals(asList("a", "ardv", "ark"), asList("aardvark".split("(?=a)")));
+ assertEquals(asList("banana"), asList("banana".split("(?=b)")));
+
+ // For comparison, matches in the middle of the input never yield an empty substring:
+ assertEquals(asList("aar", "vark"), asList("aardvark".split("d")));
+ assertEquals(asList("aar", "dvark"), asList("aardvark".split("(?=d)")));
+ }
+
+ public void testMatchBeginningOfInputSequence_api28() {
+ runWithTargetSdkVersion(28, () -> {
+ // Positive-width match at the beginning of the input.
+ assertEquals(asList("", "", "rdv", "rk"), asList("aardvark".split("a")));
+ assertEquals(asList("", "anana"), asList("banana".split("b")));
+ // Zero-width match at the beginning of the input
+ assertEquals(asList("", "a", "ardv", "ark"), asList("aardvark".split("(?=a)")));
+ assertEquals(asList("banana"), asList("banana".split("(?=b)")));
+
+ // For comparison, matches in the middle of the input never yield an empty substring:
+ assertEquals(asList("aar", "vark"), asList("aardvark".split("d")));
+ assertEquals(asList("aar", "dvark"), asList("aardvark".split("(?=d)")));
+ });
+ }
+
+ private static void runWithTargetSdkVersion(int targetSdkVersion, Runnable runnable) {
+ VMRuntime vmRuntime = VMRuntime.getRuntime();
+ int oldVersion = vmRuntime.getTargetSdkVersion();
+ vmRuntime.setTargetSdkVersion(targetSdkVersion);
+ try {
+ runnable.run();
+ } finally {
+ vmRuntime.setTargetSdkVersion(oldVersion);
+ }
+ }
+
public void testSplitCharSequence() {
String s[];
Pattern pat = Pattern.compile("b");
@@ -161,7 +225,7 @@
s = pat.split("");
assertEquals(s.length, 1);
s = pat.split("abccbadfe");
- assertEquals(s.length, 10);
+ assertEquals(s.length, 9);
// bug6544
String s1 = "";
String[] arr = s1.split(":");
diff --git a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/ReplaceTest.java b/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/ReplaceTest.java
deleted file mode 100644
index e609bb2..0000000
--- a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/ReplaceTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.harmony.regex.tests.java.util.regex;
-
-import junit.framework.TestCase;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-import java.util.regex.PatternSyntaxException;
-
-public class ReplaceTest extends TestCase {
- public void testSimpleReplace() throws PatternSyntaxException {
- String target, pattern, repl;
-
- target = "foobarfobarfoofo1barfort";
- pattern = "fo[^o]";
- repl = "xxx";
-
- Pattern p = Pattern.compile(pattern);
- Matcher m = p.matcher(target);
-
- assertEquals("foobarxxxarfoofo1barfort", m.replaceFirst(repl));
- assertEquals("foobarxxxarfooxxxbarxxxt", m.replaceAll(repl));
- }
-
- public void testCaptureReplace() {
- String target, pattern, repl, s;
- Pattern p = null;
- Matcher m;
-
- target = "[31]foo;bar[42];[99]xyz";
- pattern = "\\[([0-9]+)\\]([a-z]+)";
- repl = "$2[$1]";
-
- p = Pattern.compile(pattern);
- m = p.matcher(target);
- s = m.replaceFirst(repl);
- assertEquals("foo[31];bar[42];[99]xyz", s);
- s = m.replaceAll(repl);
- assertEquals("foo[31];bar[42];xyz[99]", s);
-
- target = "[31]foo(42)bar{63}zoo;[12]abc(34)def{56}ghi;{99}xyz[88]xyz(77)xyz;";
- pattern = "\\[([0-9]+)\\]([a-z]+)\\(([0-9]+)\\)([a-z]+)\\{([0-9]+)\\}([a-z]+)";
- repl = "[$5]$6($3)$4{$1}$2";
- p = Pattern.compile(pattern);
- m = p.matcher(target);
- s = m.replaceFirst(repl);
- // System.out.println(s);
- assertEquals("[63]zoo(42)bar{31}foo;[12]abc(34)def{56}ghi;{99}xyz[88]xyz(77)xyz;", s
- );
- s = m.replaceAll(repl);
- // System.out.println(s);
- assertEquals("[63]zoo(42)bar{31}foo;[56]ghi(34)def{12}abc;{99}xyz[88]xyz(77)xyz;", s
- );
- }
-
- public void testEscapeReplace() {
- String target, pattern, repl, s;
-
- target = "foo'bar''foo";
- pattern = "'";
- repl = "\\'";
- s = target.replaceAll(pattern, repl);
- assertEquals("foo'bar''foo", s);
- repl = "\\\\'";
- s = target.replaceAll(pattern, repl);
- assertEquals("foo\\'bar\\'\\'foo", s);
- repl = "\\$3";
- s = target.replaceAll(pattern, repl);
- assertEquals("foo$3bar$3$3foo", s);
- }
-}
diff --git a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/SplitTest.java b/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/SplitTest.java
deleted file mode 100644
index 5c8996a..0000000
--- a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/SplitTest.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package org.apache.harmony.regex.tests.java.util.regex;
-
-import junit.framework.TestCase;
-import java.util.regex.*;
-
-/**
- * TODO Type description
- *
- */
-public class SplitTest extends TestCase {
- public void testSimple() {
- Pattern p = Pattern.compile("/");
- String[] results = p.split("have/you/done/it/right");
- String[] expected = new String[] { "have", "you", "done", "it", "right" };
- assertArraysEqual(expected, results);
- }
-
- @SuppressWarnings("InvalidPatternSyntax")
- public void testEmptySplits() {
- // Trailing empty matches are removed.
- assertArraysEqual(new String[0], "hello".split("."));
- assertArraysEqual(new String[] { "1", "2" }, "1:2:".split(":"));
- // ...including when that results in an empty result.
- assertArraysEqual(new String[0], ":".split(":"));
- // ...but not when limit < 0.
- assertArraysEqual(new String[] { "1", "2", "" }, "1:2:".split(":", -1));
-
- // Leading empty matches are retained.
- assertArraysEqual(new String[] { "", "", "o" }, "hello".split(".."));
-
- // A separator that doesn't occur in the input gets you the input.
- assertArraysEqual(new String[] { "hello" }, "hello".split("not-present-in-test"));
- // ...including when the input is the empty string.
- // (Perl returns an empty list instead.)
- assertArraysEqual(new String[] { "" }, "".split("not-present-in-test"));
- assertArraysEqual(new String[] { "" }, "".split("A?"));
-
- // The limit argument controls the size of the result.
- // If l == 0, the result is as long as needed, except trailing empty matches are dropped.
- // If l < 0, the result is as long as needed, and trailing empty matches are retained.
- // If l > 0, the result contains the first l matches, plus one string containing the remaining input.
- // Examples without a trailing separator (and hence without a trailing empty match):
- assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", 0));
- assertArraysEqual(new String[] { "a,b,c" }, "a,b,c".split(",", 1));
- assertArraysEqual(new String[] { "a", "b,c" }, "a,b,c".split(",", 2));
- assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", 3));
- assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", Integer.MAX_VALUE));
- // Examples with a trailing separator (and hence possibly with a trailing empty match):
- assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c,".split(",", 0));
- assertArraysEqual(new String[] { "a,b,c," }, "a,b,c,".split(",", 1));
- assertArraysEqual(new String[] { "a", "b,c," }, "a,b,c,".split(",", 2));
- assertArraysEqual(new String[] { "a", "b", "c," }, "a,b,c,".split(",", 3));
- assertArraysEqual(new String[] { "a", "b", "c", "" }, "a,b,c,".split(",", Integer.MAX_VALUE));
- assertArraysEqual(new String[] { "a", "b", "c", "" }, "a,b,c,".split(",", -1));
- }
-
- private void assertArraysEqual(String[] expected, String[] actual) {
- assertEquals(expected.length, actual.length);
- for (int i = 0; i < expected.length; i++) {
- assertEquals(Integer.toString(i), expected[i], actual[i]);
- }
- }
-
- public void testSplit1() throws PatternSyntaxException {
- Pattern p = Pattern.compile(" ");
-
- String input = "poodle zoo";
- String tokens[];
-
- tokens = p.split(input, 1);
- assertEquals(1, tokens.length);
- assertTrue(tokens[0].equals(input));
- tokens = p.split(input, 2);
- assertEquals(2, tokens.length);
- assertEquals("poodle", tokens[0]);
- assertEquals("zoo", tokens[1]);
- tokens = p.split(input, 5);
- assertEquals(2, tokens.length);
- assertEquals("poodle", tokens[0]);
- assertEquals("zoo", tokens[1]);
- tokens = p.split(input, -2);
- assertEquals(2, tokens.length);
- assertEquals("poodle", tokens[0]);
- assertEquals("zoo", tokens[1]);
- tokens = p.split(input, 0);
- assertEquals(2, tokens.length);
- assertEquals("poodle", tokens[0]);
- assertEquals("zoo", tokens[1]);
- tokens = p.split(input);
- assertEquals(2, tokens.length);
- assertEquals("poodle", tokens[0]);
- assertEquals("zoo", tokens[1]);
-
- p = Pattern.compile("d");
-
- tokens = p.split(input, 1);
- assertEquals(1, tokens.length);
- assertTrue(tokens[0].equals(input));
- tokens = p.split(input, 2);
- assertEquals(2, tokens.length);
- assertEquals("poo", tokens[0]);
- assertEquals("le zoo", tokens[1]);
- tokens = p.split(input, 5);
- assertEquals(2, tokens.length);
- assertEquals("poo", tokens[0]);
- assertEquals("le zoo", tokens[1]);
- tokens = p.split(input, -2);
- assertEquals(2, tokens.length);
- assertEquals("poo", tokens[0]);
- assertEquals("le zoo", tokens[1]);
- tokens = p.split(input, 0);
- assertEquals(2, tokens.length);
- assertEquals("poo", tokens[0]);
- assertEquals("le zoo", tokens[1]);
- tokens = p.split(input);
- assertEquals(2, tokens.length);
- assertEquals("poo", tokens[0]);
- assertEquals("le zoo", tokens[1]);
-
- p = Pattern.compile("o");
-
- tokens = p.split(input, 1);
- assertEquals(1, tokens.length);
- assertTrue(tokens[0].equals(input));
- tokens = p.split(input, 2);
- assertEquals(2, tokens.length);
- assertEquals("p", tokens[0]);
- assertEquals("odle zoo", tokens[1]);
- tokens = p.split(input, 5);
- assertEquals(5, tokens.length);
- assertEquals("p", tokens[0]);
- assertTrue(tokens[1].equals(""));
- assertEquals("dle z", tokens[2]);
- assertTrue(tokens[3].equals(""));
- assertTrue(tokens[4].equals(""));
- tokens = p.split(input, -2);
- assertEquals(5, tokens.length);
- assertEquals("p", tokens[0]);
- assertTrue(tokens[1].equals(""));
- assertEquals("dle z", tokens[2]);
- assertTrue(tokens[3].equals(""));
- assertTrue(tokens[4].equals(""));
- tokens = p.split(input, 0);
- assertEquals(3, tokens.length);
- assertEquals("p", tokens[0]);
- assertTrue(tokens[1].equals(""));
- assertEquals("dle z", tokens[2]);
- tokens = p.split(input);
- assertEquals(3, tokens.length);
- assertEquals("p", tokens[0]);
- assertTrue(tokens[1].equals(""));
- assertEquals("dle z", tokens[2]);
- }
-
- public void testSplit2() {
- Pattern p = Pattern.compile("");
- String s[];
- s = p.split("a", -1);
- assertEquals(3, s.length);
- assertEquals("", s[0]);
- assertEquals("a", s[1]);
- assertEquals("", s[2]);
-
- s = p.split("", -1);
- assertEquals(1, s.length);
- assertEquals("", s[0]);
-
- s = p.split("abcd", -1);
- assertEquals(6, s.length);
- assertEquals("", s[0]);
- assertEquals("a", s[1]);
- assertEquals("b", s[2]);
- assertEquals("c", s[3]);
- assertEquals("d", s[4]);
- assertEquals("", s[5]);
-
- // Regression test for Android
- assertEquals("GOOG,23,500".split("|").length, 12);
- }
-
-
- public void testSplitSupplementaryWithEmptyString() {
-
- /*
- * See http://www.unicode.org/reports/tr18/#Supplementary_Characters
- * We have to treat text as code points not code units.
- */
- Pattern p = Pattern.compile("");
- String s[];
- s = p.split("a\ud869\uded6b", -1);
- assertEquals(5, s.length);
- assertEquals("", s[0]);
- assertEquals("a", s[1]);
- assertEquals("\ud869\uded6", s[2]);
- assertEquals("b", s[3]);
- assertEquals("", s[4]);
- }
-}
diff --git a/mmodules/core_platform_api/Android.bp b/mmodules/core_platform_api/Android.bp
new file mode 100644
index 0000000..523601d
--- /dev/null
+++ b/mmodules/core_platform_api/Android.bp
@@ -0,0 +1,79 @@
+// Copyright (C) 2018 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.
+
+// Build rules for the APIs that various core libraries provide to other parts
+// of the Android software stack: these include the public SDK APIs plus some
+// "core platform APIs" that only the Android software stack can use.
+
+// Generates stub source files for the {public SDK + core platform} API of the
+// core jars.
+droidstubs {
+ name: "core-platform-api-stubs",
+ srcs: [":core_api_files"],
+ no_framework_libs: true,
+
+ installable: false,
+ args: "--show-single-annotation libcore.api.CorePlatformApi",
+
+ api_filename: "api.txt",
+ removed_api_filename: "removed.txt",
+ previous_api: "previous.txt",
+ check_api: {
+ current: {
+ api_file: "api/platform/current-api.txt",
+ removed_api_file: "api/platform/current-removed.txt",
+ },
+ last_released: {
+ api_file: "api/platform/last-api.txt",
+ removed_api_file: "api/platform/last-removed.txt",
+ },
+ },
+}
+
+// A library containing the {public SDK + core platform} API stubs for the core jars.
+java_library {
+ name: "core.platform.api.stubs",
+ srcs: [":core-platform-api-stubs"],
+
+ no_standard_libs: true,
+ libs: ["core-all"],
+ system_modules: "core-all-system-modules",
+ openjdk9: {
+ javacflags: ["--patch-module=java.base=."],
+ },
+}
+
+// Used when compiling higher-level code against core.platform.api.stubs.
+java_system_modules {
+ name: "core-platform-api-stubs-system-modules",
+ libs: ["core.platform.api.stubs"],
+}
+
+// Tests associated with the core platform APIs.
+java_test {
+ name: "core-platform-api-test",
+ srcs: [ "src/test/java/**/*.java" ],
+
+ no_standard_libs: true,
+ libs: [
+ // We depend on stubs not the impl code. We do not test
+ // internals, just the {public SDK + core platform} APIs.
+ "core.platform.api.stubs",
+ // Other deps needed for tests.
+ "junit",
+ ],
+ system_modules: "core-platform-api-stubs-system-modules",
+}
+
+
diff --git a/mmodules/core_platform_api/api/platform/current-api.txt b/mmodules/core_platform_api/api/platform/current-api.txt
new file mode 100644
index 0000000..1a9d8bf
--- /dev/null
+++ b/mmodules/core_platform_api/api/platform/current-api.txt
@@ -0,0 +1,8 @@
+package libcore.mmodule.libart {
+
+ public class DemoLibartClass {
+ method public static java.lang.String corePlatformApiMethod();
+ }
+
+}
+
diff --git a/mmodules/core_platform_api/api/platform/current-removed.txt b/mmodules/core_platform_api/api/platform/current-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mmodules/core_platform_api/api/platform/current-removed.txt
diff --git a/mmodules/core_platform_api/api/platform/last-api.txt b/mmodules/core_platform_api/api/platform/last-api.txt
new file mode 100644
index 0000000..1a9d8bf
--- /dev/null
+++ b/mmodules/core_platform_api/api/platform/last-api.txt
@@ -0,0 +1,8 @@
+package libcore.mmodule.libart {
+
+ public class DemoLibartClass {
+ method public static java.lang.String corePlatformApiMethod();
+ }
+
+}
+
diff --git a/mmodules/core_platform_api/api/platform/last-removed.txt b/mmodules/core_platform_api/api/platform/last-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mmodules/core_platform_api/api/platform/last-removed.txt
diff --git a/mmodules/core_platform_api/src/test/java/libcore/test/coreplatformapi/DemoLibartCorePlatformApiTest.java b/mmodules/core_platform_api/src/test/java/libcore/test/coreplatformapi/DemoLibartCorePlatformApiTest.java
new file mode 100644
index 0000000..bc4265c
--- /dev/null
+++ b/mmodules/core_platform_api/src/test/java/libcore/test/coreplatformapi/DemoLibartCorePlatformApiTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 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.test.coreplatformapi;
+
+import static org.junit.Assert.assertEquals;
+
+import libcore.mmodule.libart.DemoLibartClass;
+
+import org.junit.Test;
+
+/**
+ * A test of the behavior of {@link DemoLibartClass} core platform API methods.
+ */
+public class DemoLibartCorePlatformApiTest {
+
+ @Test
+ public void corePlatformApiMethod() {
+ assertEquals("Hello World", DemoLibartClass.corePlatformApiMethod());
+ }
+}
diff --git a/mmodules/core_platform_api_client_demo/Android.bp b/mmodules/core_platform_api_client_demo/Android.bp
new file mode 100644
index 0000000..c5d5015
--- /dev/null
+++ b/mmodules/core_platform_api_client_demo/Android.bp
@@ -0,0 +1,23 @@
+// Copyright (C) 2018 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.
+
+// A demo library that depends on core internals and acts as a stand-in
+// for rules like "framework" until we have the full Core platform API marked
+// out.
+java_library {
+ name: "core_platform_api_client_demo",
+ srcs: ["src/main/java/**/*.java"],
+ sdk_version: "core_platform_current",
+}
+
diff --git a/mmodules/core_platform_api_client_demo/src/main/java/com/android/coreplatformapiclient/DemoCorePlatformApiClientClass.java b/mmodules/core_platform_api_client_demo/src/main/java/com/android/coreplatformapiclient/DemoCorePlatformApiClientClass.java
new file mode 100644
index 0000000..6e6d83b
--- /dev/null
+++ b/mmodules/core_platform_api_client_demo/src/main/java/com/android/coreplatformapiclient/DemoCorePlatformApiClientClass.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 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.coreplatformapiclient;
+
+import libcore.mmodule.libart.DemoLibartClass;
+
+/**
+ * A class that uses "core API" and can be used to test framework build rule changes.
+ */
+public class DemoCorePlatformApiClientClass {
+
+ public static void callingPublicApi() {
+ new Object();
+ }
+
+ public static void callingCorePlatformApi() {
+ DemoLibartClass.corePlatformApiMethod();
+
+ // This is an example of a method that is not in the public SDK or core API so will fail
+ // compilation if the build is doing things correctly.
+ // Byte.toHexString((byte) 8, true);
+ }
+}
diff --git a/mmodules/intracoreapi/Android.bp b/mmodules/intracoreapi/Android.bp
new file mode 100644
index 0000000..d67af36
--- /dev/null
+++ b/mmodules/intracoreapi/Android.bp
@@ -0,0 +1,50 @@
+// Copyright (C) 2018 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.
+
+// Build rules for the APIs that the various core libraries can depend on from
+// each other: public SDK APIs and "intra-core" APIs. Intra-core APIs are not
+// for use by other parts of the Android software stack.
+
+// Generates stub source files for the {public SDK + intra-core} API
+// of the core jars.
+droidstubs {
+ name: "core-intra-stubs",
+ srcs: [":core_api_files"],
+ no_framework_libs: true,
+
+ api_filename: "api.txt",
+ installable: false,
+ args: "--show-single-annotation libcore.api.IntraCoreApi",
+}
+
+// A library containing the {public SDK + intra-core} API stubs for the
+// core jars.
+java_library {
+ name: "core.intra.stubs",
+ srcs: [":core-intra-stubs"],
+
+ no_standard_libs: true,
+ libs: ["core-all"],
+ system_modules: "core-all-system-modules",
+ openjdk9: {
+ javacflags: ["--patch-module=java.base=."],
+ },
+}
+
+// Used when compiling against core.intra.stubs.
+java_system_modules {
+ name: "core-intra-stubs-system-modules",
+ libs: ["core.intra.stubs"],
+}
+
diff --git a/mmodules/libart_oj/Android.bp b/mmodules/libart_oj/Android.bp
new file mode 100644
index 0000000..807f255
--- /dev/null
+++ b/mmodules/libart_oj/Android.bp
@@ -0,0 +1,91 @@
+// Copyright (C) 2018 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.
+
+// This build file handles the logical unit that is the combined "core-libart"
+// + "core-oj" jars. These two jars will always be shipped as a unit but are
+// kept separate on device for licensing reasons. Because they will be shipped
+// together we can consider them as a unit and we don't need a well-defined
+// intra-core API between them.
+
+// A rule that checks we can build core-libart and core-oj using only the source
+// for core-libart and core-oj and the APIs in core-intra-stubs.
+java_library {
+ name: "core-libart-oj.depscheck",
+ srcs: [
+ ":core_libart_java_files",
+ ":core_oj_java_files",
+ ],
+ errorprone: {
+ javacflags: [
+ "-Xep:MissingOverride:OFF", // Ignore missing @Override.
+ "-Xep:ConstantOverflow:WARN", // Known constant overflow in SplittableRandom
+ ],
+ },
+
+ installable: false,
+
+ no_standard_libs: true,
+ libs: ["core.intra.stubs"],
+ system_modules: "core-intra-stubs-system-modules",
+ openjdk9: {
+ javacflags: ["--patch-module=java.base=."],
+ },
+}
+
+// Tests associated with the {core-libart + core-oj} intra-core APIs.
+java_test {
+ name: "core-libart+oj-intra-test",
+ srcs: [ "src/test/java/**/*.java" ],
+
+ no_standard_libs: true,
+ libs: [
+ // We depend on stubs not the impl code. We do not test
+ // internals, just the {public SDK + intra-core} APIs.
+ "core.intra.stubs",
+ // Other deps needed for tests.
+ "junit",
+ ],
+ system_modules: "core-intra-stubs-system-modules",
+}
+
+// Generates stub source files for the {public SDK + intra-core} APIs
+// of core-libart.
+droidstubs {
+ name: "core-libart+oj-intra-stubs",
+ srcs: [
+ ":core_libart_api_files",
+ ":core_oj_api_files",
+ ],
+ no_framework_libs: true,
+
+ installable: false,
+ args: "--show-single-annotation libcore.api.IntraCoreApi",
+}
+
+// A library containing the {public SDK + intra-core} API stubs for
+// core-libart.
+java_library {
+ name: "core-libart+oj.intra.stubs",
+ srcs: [":core-libart+oj-intra-stubs"],
+
+ no_standard_libs: true,
+ // We use core.intra.stubs here to prove that we have all the dependencies
+ // needed to compile the libart intra stubs within the intra stubs, i.e.
+ // there are no non-API references.
+ libs: ["core.intra.stubs"],
+ system_modules: "core-intra-stubs-system-modules",
+ openjdk9: {
+ javacflags: ["--patch-module=java.base=."],
+ },
+}
diff --git a/mmodules/libart_oj/src/test/java/libcore/test/mmodule/libart/DemoLibartClassTest.java b/mmodules/libart_oj/src/test/java/libcore/test/mmodule/libart/DemoLibartClassTest.java
new file mode 100644
index 0000000..76c28d8
--- /dev/null
+++ b/mmodules/libart_oj/src/test/java/libcore/test/mmodule/libart/DemoLibartClassTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2018 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.test.mmodule.libart;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import libcore.mmodule.libart.DemoLibartClass;
+
+import org.junit.Test;
+
+/**
+ * A test for the presence and behavior of {@link DemoLibartClass}.
+ */
+public class DemoLibartClassTest {
+
+ @Test
+ public void classLoader() {
+ Class<?> clazz = DemoLibartClass.class;
+ ClassLoader bootClassLoader = ClassLoader.getSystemClassLoader().getParent();
+
+ // The DemoLibartClass must be loaded by the boot classloader.
+ assertSame(bootClassLoader, clazz.getClassLoader());
+ }
+
+ @Test
+ public void simpleMethod() {
+ assertEquals("Hello World", DemoLibartClass.simpleMethod());
+ }
+
+ @Test
+ public void intraCoreDependencyMethod() {
+ assertEquals("Hello World", DemoLibartClass.intraCoreDependencyMethod());
+ }
+}
diff --git a/mmodules/simple/Android.bp b/mmodules/simple/Android.bp
new file mode 100644
index 0000000..fae8e14
--- /dev/null
+++ b/mmodules/simple/Android.bp
@@ -0,0 +1,128 @@
+// Copyright (C) 2018 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.
+
+filegroup {
+ name: "core_simple_java_files",
+ srcs: ["src/main/java/**/*.java"]
+}
+
+java_defaults {
+ name: "core-simple-defaults",
+ srcs: [":core_simple_java_files"],
+ installable: true,
+
+ // As a logical part of the set of core libs we cannot use
+ // no_standard_libs: false here because this core jar is one of the
+ // default standard libs and that leads to a cycle.
+ // So, we deliberately compile against core-all to avoid cycles.
+ no_standard_libs: true,
+ libs: ["core-all"],
+ system_modules: "core-all-system-modules",
+ openjdk9: {
+ javacflags: ["--patch-module=java.base=."],
+ },
+
+ dxflags: ["--core-library"],
+}
+
+// A library containing the implementation of core-simple.
+java_library {
+ name: "core-simple",
+ hostdex: true,
+ defaults: ["core-simple-defaults"],
+}
+
+// A guaranteed unstripped version of core-simple.
+// The build system may or may not strip the core-simple jar
+// but this will not be stripped. See b/24535627.
+java_library {
+ name: "core-simple-testdex",
+ defaults: ["core-simple-defaults"],
+ dex_preopt: {
+ enabled: false,
+ },
+}
+
+// A rule that checks we can build core-simple using only the source for
+// core-simple and the APIs in the core.intra.stubs.
+java_library {
+ name: "core-simple.depscheck",
+ srcs: [":core_simple_java_files"],
+ installable: false,
+
+ no_standard_libs: true,
+ libs: ["core.intra.stubs"],
+ system_modules: "core-intra-stubs-system-modules",
+ openjdk9: {
+ javacflags: ["--patch-module=java.base=."],
+ },
+}
+
+// Tests associated with the core-simple intra-core APIs.
+java_test {
+ name: "core-simple-intra-test",
+ srcs: [ "src/test/java/**/*.java" ],
+
+ no_standard_libs: true,
+ libs: [
+ // We depend on stubs not the impl code. We do not test
+ // internals, just the {public SDK + intra-core} APIs.
+ "core.intra.stubs",
+ // Other deps needed for tests.
+ "junit",
+ ],
+ system_modules: "core-intra-stubs-system-modules",
+}
+
+// Generates stub source files for the {public SDK + intra-core} APIs
+// of core-simple.
+droidstubs {
+ name: "core-simple-intra-stubs",
+ srcs: [":core_simple_java_files"],
+ no_framework_libs: true,
+
+ installable: false,
+ args: "--show-single-annotation libcore.api.IntraCoreApi",
+
+ api_filename: "api.txt",
+ removed_api_filename: "removed.txt",
+ previous_api: "previous.txt",
+ check_api: {
+ current: {
+ api_file: "api/intra/current-api.txt",
+ removed_api_file: "api/intra/current-removed.txt",
+ },
+ last_released: {
+ api_file: "api/intra/last-api.txt",
+ removed_api_file: "api/intra/last-removed.txt",
+ },
+ },
+}
+
+// A library containing the {public SDK + intra-core} API stubs for
+// core-simple.
+java_library {
+ name: "core-simple.intra.stubs",
+ srcs: [":core-simple-intra-stubs"],
+
+ no_standard_libs: true,
+ // We use core.intra.stubs here to prove that we have all the dependencies
+ // needed to compile the simple intra stubs within the intra stubs, i.e.
+ // there are no non-API references.
+ libs: ["core.intra.stubs"],
+ system_modules: "core-intra-stubs-system-modules",
+ openjdk9: {
+ javacflags: ["--patch-module=java.base=."],
+ },
+}
diff --git a/mmodules/simple/api/intra/current-api.txt b/mmodules/simple/api/intra/current-api.txt
new file mode 100644
index 0000000..6aa0d7a
--- /dev/null
+++ b/mmodules/simple/api/intra/current-api.txt
@@ -0,0 +1,9 @@
+package libcore.mmodule.simple {
+
+ public class DemoSimpleClass {
+ method public static java.lang.String intraCoreDependencyMethod();
+ method public static java.lang.String simpleMethod();
+ }
+
+}
+
diff --git a/mmodules/simple/api/intra/current-removed.txt b/mmodules/simple/api/intra/current-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mmodules/simple/api/intra/current-removed.txt
diff --git a/mmodules/simple/api/intra/last-api.txt b/mmodules/simple/api/intra/last-api.txt
new file mode 100644
index 0000000..6aa0d7a
--- /dev/null
+++ b/mmodules/simple/api/intra/last-api.txt
@@ -0,0 +1,9 @@
+package libcore.mmodule.simple {
+
+ public class DemoSimpleClass {
+ method public static java.lang.String intraCoreDependencyMethod();
+ method public static java.lang.String simpleMethod();
+ }
+
+}
+
diff --git a/mmodules/simple/api/intra/last-removed.txt b/mmodules/simple/api/intra/last-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mmodules/simple/api/intra/last-removed.txt
diff --git a/mmodules/simple/src/main/java/libcore/mmodule/simple/DemoSimpleClass.java b/mmodules/simple/src/main/java/libcore/mmodule/simple/DemoSimpleClass.java
new file mode 100644
index 0000000..a6bf475
--- /dev/null
+++ b/mmodules/simple/src/main/java/libcore/mmodule/simple/DemoSimpleClass.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 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.mmodule.simple;
+
+import libcore.mmodule.libart.DemoLibartClass;
+
+/**
+ * A class that nothing in libcore or the Android framework depends on to provide public SDK
+ * behavior. It is intended for use in a fake installable mmodule. Its presence can be tested for,
+ * the classloader identified and its behavior modified over time to simulate real mmodule code,
+ * without touching any "real" platform logic.
+ *
+ * @hide
+ */
+@libcore.api.IntraCoreApi
+public class DemoSimpleClass {
+
+ private DemoSimpleClass() {}
+
+ /**
+ * A simple method that has no native or data file dependencies but is part of the simple
+ * mmodule's API contract.
+ */
+ @libcore.api.IntraCoreApi
+ public static String simpleMethod() {
+ return "Hello World";
+ }
+
+ /**
+ * A method that depends on another part of the core libraries to work.
+ */
+ @libcore.api.IntraCoreApi // Exposed for tests
+ public static String intraCoreDependencyMethod() {
+ // Delegate to core-libart code to implement the method.
+ return DemoLibartClass.simpleMethod();
+ }
+
+ /**
+ * A method that is public but not part of the simple mmodule's API contract.
+ */
+ public static String hiddenMethod() {
+ return "Hello World";
+ }
+}
diff --git a/mmodules/simple/src/test/java/libcore/test/mmodule/simple/DemoSimpleClassTest.java b/mmodules/simple/src/test/java/libcore/test/mmodule/simple/DemoSimpleClassTest.java
new file mode 100644
index 0000000..523eed5
--- /dev/null
+++ b/mmodules/simple/src/test/java/libcore/test/mmodule/simple/DemoSimpleClassTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2018 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.test.mmodule.simple;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import libcore.mmodule.simple.DemoSimpleClass;
+
+import org.junit.Test;
+
+/**
+ * A test for the presence and behavior of {@link DemoSimpleClass}.
+ */
+public class DemoSimpleClassTest {
+
+ @Test
+ public void classLoader() {
+ Class<?> clazz = DemoSimpleClass.class;
+ ClassLoader bootClassLoader = ClassLoader.getSystemClassLoader().getParent();
+
+ // The DemoSimpleClass must be loaded by the boot classloader.
+ assertSame(bootClassLoader, clazz.getClassLoader());
+ }
+
+ @Test
+ public void simpleMethod() {
+ assertEquals("Hello World", DemoSimpleClass.simpleMethod());
+ }
+
+ @Test
+ public void intraCoreDependencyMethod() {
+ assertEquals("Hello World", DemoSimpleClass.intraCoreDependencyMethod());
+ }
+}
diff --git a/non_openjdk_java_files.bp b/non_openjdk_java_files.bp
index 929b411..d0b6d3d 100644
--- a/non_openjdk_java_files.bp
+++ b/non_openjdk_java_files.bp
@@ -38,6 +38,7 @@
"dalvik/src/main/java/dalvik/annotation/TestTarget.java",
"dalvik/src/main/java/dalvik/annotation/TestTargetClass.java",
"dalvik/src/main/java/dalvik/annotation/Throws.java",
+ "dalvik/src/main/java/dalvik/annotation/codegen/CovariantReturnType.java",
"dalvik/src/main/java/dalvik/annotation/optimization/CriticalNative.java",
"dalvik/src/main/java/dalvik/annotation/optimization/FastNative.java",
"dalvik/src/main/java/dalvik/annotation/optimization/ReachabilitySensitive.java",
@@ -60,6 +61,7 @@
"dalvik/src/main/java/dalvik/system/NativeStart.java",
"dalvik/src/main/java/dalvik/system/PathClassLoader.java",
"dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java",
+ "dalvik/src/main/java/dalvik/system/RuntimeHooks.java",
"dalvik/src/main/java/dalvik/system/SocketTagger.java",
"dalvik/src/main/java/dalvik/system/TemporaryDirectory.java",
"libart/src/main/java/dalvik/system/TransactionAbortError.java",
@@ -154,6 +156,9 @@
"luni/src/main/java/javax/xml/xpath/XPathFunctionException.java",
"luni/src/main/java/javax/xml/xpath/XPathFunctionResolver.java",
"luni/src/main/java/javax/xml/xpath/XPathVariableResolver.java",
+ "luni/src/main/java/libcore/api/CorePlatformApi.java",
+ "luni/src/main/java/libcore/api/IntraCoreApi.java",
+ "luni/src/main/java/libcore/mmodule/libart/DemoLibartClass.java",
"json/src/main/java/org/json/JSON.java",
"json/src/main/java/org/json/JSONArray.java",
"json/src/main/java/org/json/JSONException.java",
@@ -280,7 +285,6 @@
"luni/src/main/java/libcore/math/MathUtils.java",
"luni/src/main/java/libcore/net/MimeUtils.java",
"luni/src/main/java/libcore/net/NetworkSecurityPolicy.java",
- "luni/src/main/java/libcore/net/UriCodec.java",
"luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java",
"luni/src/main/java/libcore/net/event/NetworkEventListener.java",
"luni/src/main/java/libcore/net/http/HttpDate.java",
@@ -297,6 +301,7 @@
"luni/src/main/java/libcore/reflect/TypeVariableImpl.java",
"luni/src/main/java/libcore/reflect/Types.java",
"luni/src/main/java/libcore/reflect/WildcardTypeImpl.java",
+ "luni/src/main/java/libcore/util/ArrayUtils.java",
"luni/src/main/java/libcore/util/CharsetUtils.java",
"luni/src/main/java/libcore/util/EmptyArray.java",
"luni/src/main/java/libcore/util/BasicLruCache.java",
@@ -304,24 +309,23 @@
"luni/src/main/java/libcore/util/CountryTimeZones.java",
"luni/src/main/java/libcore/util/CountryZonesFinder.java",
"luni/src/main/java/libcore/util/EmptyArray.java",
+ "luni/src/main/java/libcore/util/HexEncoding.java",
"luni/src/main/java/libcore/util/NativeAllocationRegistry.java",
"luni/src/main/java/libcore/util/NonNull.java",
"luni/src/main/java/libcore/util/Nullable.java",
"luni/src/main/java/libcore/util/NullFromTypeParam.java",
"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/TimeZoneFinder.java",
+ "luni/src/main/java/libcore/util/XmlObjectFactory.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",
"dalvik/src/main/java/org/apache/harmony/dalvik/NativeTestTarget.java",
"dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/Chunk.java",
"dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/ChunkHandler.java",
"dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/DdmServer.java",
"dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/DdmVmInternal.java",
- "luni/src/main/java/org/apache/harmony/luni/internal/util/TimezoneGetter.java",
"luni/src/main/java/org/apache/harmony/xml/ExpatAttributes.java",
"luni/src/main/java/org/apache/harmony/xml/ExpatException.java",
"luni/src/main/java/org/apache/harmony/xml/ExpatParser.java",
@@ -352,8 +356,8 @@
"luni/src/main/java/org/apache/harmony/xml/parsers/SAXParserImpl.java",
"libart/src/main/java/java/lang/CaseMapper.java",
"libart/src/main/java/java/lang/StringFactory.java",
- "xml/src/main/java/org/kxml2/io/KXmlParser.java",
- "xml/src/main/java/org/kxml2/io/KXmlSerializer.java",
+ "xml/src/main/java/com/android/org/kxml2/io/KXmlParser.java",
+ "xml/src/main/java/com/android/org/kxml2/io/KXmlSerializer.java",
":non_openjdk_javadoc_files",
],
}
diff --git a/ojluni/annotations/README b/ojluni/annotations/README
new file mode 100644
index 0000000..aa7c781
--- /dev/null
+++ b/ojluni/annotations/README
@@ -0,0 +1,16 @@
+This directory contains annotated stub files which can be merged into
+the main source files by metalava when it is producing API stubs. This
+mechanism is used instead of adding the annotations to the main source
+files, to avoid carrying patches against the upstream sources.
+
+Directory structure
+===================
+
+libcore/ojluni/annotations/sdk:
+ - Contains annotations to be included in the public SDK, for example
+ annotations specifying additional details about method contracts.
+
+libcore/ojluni/annotations/sdk/nullability:
+ - Contains annotations to be included in the public SDK specifically
+ relating to nullability. Adding an annotated stub file to this subdirectory
+ will cause the annotations to be validated for correctness and completeness.
diff --git a/ojluni/annotations/sdk/nullability/java/io/PrintWriter.annotated.java b/ojluni/annotations/sdk/nullability/java/io/PrintWriter.annotated.java
new file mode 100644
index 0000000..531dfb0
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/io/PrintWriter.annotated.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1996, 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
+ * 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 java.io;
+
+import java.nio.charset.Charset;
+import java.util.Formatter;
+import java.util.Locale;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class PrintWriter extends java.io.Writer {
+
+public PrintWriter(@libcore.util.NonNull java.io.Writer out) { throw new RuntimeException("Stub!"); }
+
+public PrintWriter(@libcore.util.NonNull java.io.Writer out, boolean autoFlush) { throw new RuntimeException("Stub!"); }
+
+public PrintWriter(@libcore.util.NonNull java.io.OutputStream out) { throw new RuntimeException("Stub!"); }
+
+public PrintWriter(@libcore.util.NonNull java.io.OutputStream out, boolean autoFlush) { throw new RuntimeException("Stub!"); }
+
+public PrintWriter(@libcore.util.NonNull java.lang.String fileName) throws java.io.FileNotFoundException { throw new RuntimeException("Stub!"); }
+
+public PrintWriter(@libcore.util.NonNull java.lang.String fileName, @libcore.util.NonNull java.lang.String csn) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public PrintWriter(@libcore.util.NonNull java.io.File file) throws java.io.FileNotFoundException { throw new RuntimeException("Stub!"); }
+
+public PrintWriter(@libcore.util.NonNull java.io.File file, @libcore.util.NonNull java.lang.String csn) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public void flush() { throw new RuntimeException("Stub!"); }
+
+public void close() { throw new RuntimeException("Stub!"); }
+
+public boolean checkError() { throw new RuntimeException("Stub!"); }
+
+protected void setError() { throw new RuntimeException("Stub!"); }
+
+protected void clearError() { throw new RuntimeException("Stub!"); }
+
+public void write(int c) { throw new RuntimeException("Stub!"); }
+
+public void write(char[] buf, int off, int len) { throw new RuntimeException("Stub!"); }
+
+public void write(char[] buf) { throw new RuntimeException("Stub!"); }
+
+public void write(@libcore.util.NonNull java.lang.String s, int off, int len) { throw new RuntimeException("Stub!"); }
+
+public void write(@libcore.util.NonNull java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public void print(boolean b) { throw new RuntimeException("Stub!"); }
+
+public void print(char c) { throw new RuntimeException("Stub!"); }
+
+public void print(int i) { throw new RuntimeException("Stub!"); }
+
+public void print(long l) { throw new RuntimeException("Stub!"); }
+
+public void print(float f) { throw new RuntimeException("Stub!"); }
+
+public void print(double d) { throw new RuntimeException("Stub!"); }
+
+public void print(char[] s) { throw new RuntimeException("Stub!"); }
+
+public void print(@libcore.util.Nullable java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public void print(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public void println() { throw new RuntimeException("Stub!"); }
+
+public void println(boolean x) { throw new RuntimeException("Stub!"); }
+
+public void println(char x) { throw new RuntimeException("Stub!"); }
+
+public void println(int x) { throw new RuntimeException("Stub!"); }
+
+public void println(long x) { throw new RuntimeException("Stub!"); }
+
+public void println(float x) { throw new RuntimeException("Stub!"); }
+
+public void println(double x) { throw new RuntimeException("Stub!"); }
+
+public void println(char[] x) { throw new RuntimeException("Stub!"); }
+
+public void println(@libcore.util.Nullable java.lang.String x) { throw new RuntimeException("Stub!"); }
+
+public void println(@libcore.util.Nullable java.lang.Object x) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.PrintWriter printf(@libcore.util.NonNull java.lang.String format, java.lang.@libcore.util.Nullable Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.PrintWriter printf(@libcore.util.Nullable java.util.Locale l, @libcore.util.NonNull java.lang.String format, java.lang.@libcore.util.Nullable Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.PrintWriter format(@libcore.util.NonNull java.lang.String format, java.lang.@libcore.util.Nullable Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.PrintWriter format(@libcore.util.Nullable java.util.Locale l, @libcore.util.NonNull java.lang.String format, java.lang.@libcore.util.Nullable Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.PrintWriter append(@libcore.util.Nullable java.lang.CharSequence csq) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.PrintWriter append(@libcore.util.Nullable java.lang.CharSequence csq, int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.PrintWriter append(char c) { throw new RuntimeException("Stub!"); }
+
+protected java.io.Writer out;
+}
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/Appendable.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/Appendable.annotated.java
index 011089d..0ef58db 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/Appendable.annotated.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2004, 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
@@ -23,22 +23,18 @@
* questions.
*/
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang;
+import java.io.IOException;
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
- return JVM_InternString(env, this);
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Appendable {
+
+@libcore.util.NonNull public java.lang.Appendable append(@libcore.util.Nullable java.lang.CharSequence csq) throws java.io.IOException;
+
+@libcore.util.NonNull public java.lang.Appendable append(@libcore.util.Nullable java.lang.CharSequence csq, int start, int end) throws java.io.IOException;
+
+@libcore.util.NonNull public java.lang.Appendable append(char c) throws java.io.IOException;
}
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
-void register_java_lang_String(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Boolean.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Boolean.annotated.java
new file mode 100644
index 0000000..8022814
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Boolean.annotated.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1994, 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
+ * 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 java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Boolean implements java.io.Serializable, java.lang.Comparable<java.lang.Boolean> {
+
+public Boolean(boolean value) { throw new RuntimeException("Stub!"); }
+
+public Boolean(@libcore.util.Nullable java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static boolean parseBoolean(@libcore.util.Nullable java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public boolean booleanValue() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Boolean valueOf(boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Boolean valueOf(@libcore.util.Nullable java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(boolean value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static boolean getBoolean(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Boolean b) { throw new RuntimeException("Stub!"); }
+
+public static int compare(boolean x, boolean y) { throw new RuntimeException("Stub!"); }
+
+public static boolean logicalAnd(boolean a, boolean b) { throw new RuntimeException("Stub!"); }
+
+public static boolean logicalOr(boolean a, boolean b) { throw new RuntimeException("Stub!"); }
+
+public static boolean logicalXor(boolean a, boolean b) { throw new RuntimeException("Stub!"); }
+
+public static final java.lang.Boolean FALSE;
+static { FALSE = null; }
+
+public static final java.lang.Boolean TRUE;
+static { TRUE = null; }
+
+public static final java.lang.Class<java.lang.Boolean> TYPE;
+static { TYPE = null; }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Byte.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Byte.annotated.java
new file mode 100644
index 0000000..b64ca1e
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Byte.annotated.java
@@ -0,0 +1,90 @@
+/*
+ * 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
+ * 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 java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Byte extends java.lang.Number implements java.lang.Comparable<java.lang.Byte> {
+
+public Byte(byte value) { throw new RuntimeException("Stub!"); }
+
+public Byte(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(byte b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Byte valueOf(byte b) { throw new RuntimeException("Stub!"); }
+
+public static byte parseByte(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static byte parseByte(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Byte valueOf(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Byte valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Byte decode(@libcore.util.NonNull java.lang.String nm) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(byte value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Byte anotherByte) { throw new RuntimeException("Stub!"); }
+
+public static int compare(byte x, byte y) { throw new RuntimeException("Stub!"); }
+
+public static int toUnsignedInt(byte x) { throw new RuntimeException("Stub!"); }
+
+public static long toUnsignedLong(byte x) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 1; // 0x1
+
+public static final byte MAX_VALUE = 127; // 0x7f
+
+public static final byte MIN_VALUE = -128; // 0xffffff80
+
+public static final int SIZE = 8; // 0x8
+
+public static final java.lang.Class<java.lang.Byte> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/CharSequence.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/CharSequence.annotated.java
index 011089d..4c82aa8 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/CharSequence.annotated.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, 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
@@ -23,22 +23,24 @@
* questions.
*/
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang;
+import java.util.stream.IntStream;
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
- return JVM_InternString(env, this);
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface CharSequence {
+
+public int length();
+
+public char charAt(int index);
+
+public java.lang.CharSequence subSequence(int start, int end);
+
+@libcore.util.NonNull public java.lang.String toString();
+
+public default java.util.stream.IntStream chars() { throw new RuntimeException("Stub!"); }
+
+public default java.util.stream.IntStream codePoints() { throw new RuntimeException("Stub!"); }
}
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
-void register_java_lang_String(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Character.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Character.annotated.java
new file mode 100644
index 0000000..d50474f
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Character.annotated.java
@@ -0,0 +1,1140 @@
+/*
+ * Copyright (c) 2002, 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
+ * 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 java.lang;
+
+import java.util.Locale;
+import java.util.Map;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Character implements java.io.Serializable, java.lang.Comparable<java.lang.Character> {
+
+public Character(char value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Character valueOf(char c) { throw new RuntimeException("Stub!"); }
+
+public char charValue() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(char value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(char c) { throw new RuntimeException("Stub!"); }
+
+public static boolean isValidCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isBmpCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSupplementaryCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isHighSurrogate(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLowSurrogate(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSurrogate(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSurrogatePair(char high, char low) { throw new RuntimeException("Stub!"); }
+
+public static int charCount(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int toCodePoint(char high, char low) { throw new RuntimeException("Stub!"); }
+
+public static int codePointAt(@libcore.util.NonNull java.lang.CharSequence seq, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointAt(char[] a, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointAt(char[] a, int index, int limit) { throw new RuntimeException("Stub!"); }
+
+public static int codePointBefore(@libcore.util.NonNull java.lang.CharSequence seq, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointBefore(char[] a, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointBefore(char[] a, int index, int start) { throw new RuntimeException("Stub!"); }
+
+public static char highSurrogate(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char lowSurrogate(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int toChars(int codePoint, char[] dst, int dstIndex) { throw new RuntimeException("Stub!"); }
+
+public static char[] toChars(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int codePointCount(@libcore.util.NonNull java.lang.CharSequence seq, int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public static int codePointCount(char[] a, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+public static int offsetByCodePoints(@libcore.util.NonNull java.lang.CharSequence seq, int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public static int offsetByCodePoints(char[] a, int start, int count, int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLowerCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLowerCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUpperCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUpperCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isTitleCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isTitleCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDigit(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDigit(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDefined(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDefined(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetter(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetter(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetterOrDigit(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetterOrDigit(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public static boolean isJavaLetter(char ch) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public static boolean isJavaLetterOrDigit(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isAlphabetic(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isIdeographic(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierStart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierStart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierPart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierPart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierStart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierStart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierPart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierPart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isIdentifierIgnorable(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isIdentifierIgnorable(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char toLowerCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int toLowerCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char toUpperCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int toUpperCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char toTitleCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int toTitleCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int digit(char ch, int radix) { throw new RuntimeException("Stub!"); }
+
+public static int digit(int codePoint, int radix) { throw new RuntimeException("Stub!"); }
+
+public static int getNumericValue(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int getNumericValue(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public static boolean isSpace(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSpaceChar(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSpaceChar(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isWhitespace(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isWhitespace(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isISOControl(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isISOControl(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int getType(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int getType(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char forDigit(int digit, int radix) { throw new RuntimeException("Stub!"); }
+
+public static byte getDirectionality(char ch) { throw new RuntimeException("Stub!"); }
+
+public static byte getDirectionality(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isMirrored(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isMirrored(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Character anotherCharacter) { throw new RuntimeException("Stub!"); }
+
+public static int compare(char x, char y) { throw new RuntimeException("Stub!"); }
+
+public static char reverseBytes(char ch) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.String getName(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 2; // 0x2
+
+public static final byte COMBINING_SPACING_MARK = 8; // 0x8
+
+public static final byte CONNECTOR_PUNCTUATION = 23; // 0x17
+
+public static final byte CONTROL = 15; // 0xf
+
+public static final byte CURRENCY_SYMBOL = 26; // 0x1a
+
+public static final byte DASH_PUNCTUATION = 20; // 0x14
+
+public static final byte DECIMAL_DIGIT_NUMBER = 9; // 0x9
+
+public static final byte DIRECTIONALITY_ARABIC_NUMBER = 6; // 0x6
+
+public static final byte DIRECTIONALITY_BOUNDARY_NEUTRAL = 9; // 0x9
+
+public static final byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = 7; // 0x7
+
+public static final byte DIRECTIONALITY_EUROPEAN_NUMBER = 3; // 0x3
+
+public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = 4; // 0x4
+
+public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = 5; // 0x5
+
+public static final byte DIRECTIONALITY_LEFT_TO_RIGHT = 0; // 0x0
+
+public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = 14; // 0xe
+
+public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = 15; // 0xf
+
+public static final byte DIRECTIONALITY_NONSPACING_MARK = 8; // 0x8
+
+public static final byte DIRECTIONALITY_OTHER_NEUTRALS = 13; // 0xd
+
+public static final byte DIRECTIONALITY_PARAGRAPH_SEPARATOR = 10; // 0xa
+
+public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18; // 0x12
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT = 1; // 0x1
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = 2; // 0x2
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = 16; // 0x10
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = 17; // 0x11
+
+public static final byte DIRECTIONALITY_SEGMENT_SEPARATOR = 11; // 0xb
+
+public static final byte DIRECTIONALITY_UNDEFINED = -1; // 0xffffffff
+
+public static final byte DIRECTIONALITY_WHITESPACE = 12; // 0xc
+
+public static final byte ENCLOSING_MARK = 7; // 0x7
+
+public static final byte END_PUNCTUATION = 22; // 0x16
+
+public static final byte FINAL_QUOTE_PUNCTUATION = 30; // 0x1e
+
+public static final byte FORMAT = 16; // 0x10
+
+public static final byte INITIAL_QUOTE_PUNCTUATION = 29; // 0x1d
+
+public static final byte LETTER_NUMBER = 10; // 0xa
+
+public static final byte LINE_SEPARATOR = 13; // 0xd
+
+public static final byte LOWERCASE_LETTER = 2; // 0x2
+
+public static final byte MATH_SYMBOL = 25; // 0x19
+
+public static final int MAX_CODE_POINT = 1114111; // 0x10ffff
+
+public static final char MAX_HIGH_SURROGATE = 56319; // 0xdbff '\udbff'
+
+public static final char MAX_LOW_SURROGATE = 57343; // 0xdfff '\udfff'
+
+public static final int MAX_RADIX = 36; // 0x24
+
+public static final char MAX_SURROGATE = 57343; // 0xdfff '\udfff'
+
+public static final char MAX_VALUE = 65535; // 0xffff '\uffff'
+
+public static final int MIN_CODE_POINT = 0; // 0x0
+
+public static final char MIN_HIGH_SURROGATE = 55296; // 0xd800 '\ud800'
+
+public static final char MIN_LOW_SURROGATE = 56320; // 0xdc00 '\udc00'
+
+public static final int MIN_RADIX = 2; // 0x2
+
+public static final int MIN_SUPPLEMENTARY_CODE_POINT = 65536; // 0x10000
+
+public static final char MIN_SURROGATE = 55296; // 0xd800 '\ud800'
+
+public static final char MIN_VALUE = 0; // 0x0000 '\u0000'
+
+public static final byte MODIFIER_LETTER = 4; // 0x4
+
+public static final byte MODIFIER_SYMBOL = 27; // 0x1b
+
+public static final byte NON_SPACING_MARK = 6; // 0x6
+
+public static final byte OTHER_LETTER = 5; // 0x5
+
+public static final byte OTHER_NUMBER = 11; // 0xb
+
+public static final byte OTHER_PUNCTUATION = 24; // 0x18
+
+public static final byte OTHER_SYMBOL = 28; // 0x1c
+
+public static final byte PARAGRAPH_SEPARATOR = 14; // 0xe
+
+public static final byte PRIVATE_USE = 18; // 0x12
+
+public static final int SIZE = 16; // 0x10
+
+public static final byte SPACE_SEPARATOR = 12; // 0xc
+
+public static final byte START_PUNCTUATION = 21; // 0x15
+
+public static final byte SURROGATE = 19; // 0x13
+
+public static final byte TITLECASE_LETTER = 3; // 0x3
+
+public static final java.lang.Class<java.lang.Character> TYPE;
+static { TYPE = null; }
+
+public static final byte UNASSIGNED = 0; // 0x0
+
+public static final byte UPPERCASE_LETTER = 1; // 0x1
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static class Subset {
+
+protected Subset(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public final boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public final int hashCode() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.lang.String toString() { throw new RuntimeException("Stub!"); }
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static final class UnicodeBlock extends java.lang.Character.Subset {
+
+UnicodeBlock(java.lang.String idName) { super(null); throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Character.UnicodeBlock of(char c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Character.UnicodeBlock of(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Character.UnicodeBlock forName(@libcore.util.NonNull java.lang.String blockName) { throw new RuntimeException("Stub!"); }
+
+public static final java.lang.Character.UnicodeBlock AEGEAN_NUMBERS;
+static { AEGEAN_NUMBERS = null; }
+
+public static final java.lang.Character.UnicodeBlock ALCHEMICAL_SYMBOLS;
+static { ALCHEMICAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock ALPHABETIC_PRESENTATION_FORMS;
+static { ALPHABETIC_PRESENTATION_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock ANCIENT_GREEK_MUSICAL_NOTATION;
+static { ANCIENT_GREEK_MUSICAL_NOTATION = null; }
+
+public static final java.lang.Character.UnicodeBlock ANCIENT_GREEK_NUMBERS;
+static { ANCIENT_GREEK_NUMBERS = null; }
+
+public static final java.lang.Character.UnicodeBlock ANCIENT_SYMBOLS;
+static { ANCIENT_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC;
+static { ARABIC = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_EXTENDED_A;
+static { ARABIC_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS;
+static { ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_A;
+static { ARABIC_PRESENTATION_FORMS_A = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_B;
+static { ARABIC_PRESENTATION_FORMS_B = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_SUPPLEMENT;
+static { ARABIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock ARMENIAN;
+static { ARMENIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock ARROWS;
+static { ARROWS = null; }
+
+public static final java.lang.Character.UnicodeBlock AVESTAN;
+static { AVESTAN = null; }
+
+public static final java.lang.Character.UnicodeBlock BALINESE;
+static { BALINESE = null; }
+
+public static final java.lang.Character.UnicodeBlock BAMUM;
+static { BAMUM = null; }
+
+public static final java.lang.Character.UnicodeBlock BAMUM_SUPPLEMENT;
+static { BAMUM_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock BASIC_LATIN;
+static { BASIC_LATIN = null; }
+
+public static final java.lang.Character.UnicodeBlock BATAK;
+static { BATAK = null; }
+
+public static final java.lang.Character.UnicodeBlock BENGALI;
+static { BENGALI = null; }
+
+public static final java.lang.Character.UnicodeBlock BLOCK_ELEMENTS;
+static { BLOCK_ELEMENTS = null; }
+
+public static final java.lang.Character.UnicodeBlock BOPOMOFO;
+static { BOPOMOFO = null; }
+
+public static final java.lang.Character.UnicodeBlock BOPOMOFO_EXTENDED;
+static { BOPOMOFO_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock BOX_DRAWING;
+static { BOX_DRAWING = null; }
+
+public static final java.lang.Character.UnicodeBlock BRAHMI;
+static { BRAHMI = null; }
+
+public static final java.lang.Character.UnicodeBlock BRAILLE_PATTERNS;
+static { BRAILLE_PATTERNS = null; }
+
+public static final java.lang.Character.UnicodeBlock BUGINESE;
+static { BUGINESE = null; }
+
+public static final java.lang.Character.UnicodeBlock BUHID;
+static { BUHID = null; }
+
+public static final java.lang.Character.UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS;
+static { BYZANTINE_MUSICAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock CARIAN;
+static { CARIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock CHAKMA;
+static { CHAKMA = null; }
+
+public static final java.lang.Character.UnicodeBlock CHAM;
+static { CHAM = null; }
+
+public static final java.lang.Character.UnicodeBlock CHEROKEE;
+static { CHEROKEE = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY;
+static { CJK_COMPATIBILITY = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_FORMS;
+static { CJK_COMPATIBILITY_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS;
+static { CJK_COMPATIBILITY_IDEOGRAPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT;
+static { CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_RADICALS_SUPPLEMENT;
+static { CJK_RADICALS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_STROKES;
+static { CJK_STROKES = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION;
+static { CJK_SYMBOLS_AND_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS;
+static { CJK_UNIFIED_IDEOGRAPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS;
+static { COMBINING_DIACRITICAL_MARKS = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS_SUPPLEMENT;
+static { COMBINING_DIACRITICAL_MARKS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_HALF_MARKS;
+static { COMBINING_HALF_MARKS = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS;
+static { COMBINING_MARKS_FOR_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock COMMON_INDIC_NUMBER_FORMS;
+static { COMMON_INDIC_NUMBER_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock CONTROL_PICTURES;
+static { CONTROL_PICTURES = null; }
+
+public static final java.lang.Character.UnicodeBlock COPTIC;
+static { COPTIC = null; }
+
+public static final java.lang.Character.UnicodeBlock COUNTING_ROD_NUMERALS;
+static { COUNTING_ROD_NUMERALS = null; }
+
+public static final java.lang.Character.UnicodeBlock CUNEIFORM;
+static { CUNEIFORM = null; }
+
+public static final java.lang.Character.UnicodeBlock CUNEIFORM_NUMBERS_AND_PUNCTUATION;
+static { CUNEIFORM_NUMBERS_AND_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock CURRENCY_SYMBOLS;
+static { CURRENCY_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock CYPRIOT_SYLLABARY;
+static { CYPRIOT_SYLLABARY = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC;
+static { CYRILLIC = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC_EXTENDED_A;
+static { CYRILLIC_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC_EXTENDED_B;
+static { CYRILLIC_EXTENDED_B = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC_SUPPLEMENTARY;
+static { CYRILLIC_SUPPLEMENTARY = null; }
+
+public static final java.lang.Character.UnicodeBlock DESERET;
+static { DESERET = null; }
+
+public static final java.lang.Character.UnicodeBlock DEVANAGARI;
+static { DEVANAGARI = null; }
+
+public static final java.lang.Character.UnicodeBlock DEVANAGARI_EXTENDED;
+static { DEVANAGARI_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock DINGBATS;
+static { DINGBATS = null; }
+
+public static final java.lang.Character.UnicodeBlock DOMINO_TILES;
+static { DOMINO_TILES = null; }
+
+public static final java.lang.Character.UnicodeBlock EGYPTIAN_HIEROGLYPHS;
+static { EGYPTIAN_HIEROGLYPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock EMOTICONS;
+static { EMOTICONS = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_ALPHANUMERICS;
+static { ENCLOSED_ALPHANUMERICS = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_ALPHANUMERIC_SUPPLEMENT;
+static { ENCLOSED_ALPHANUMERIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS;
+static { ENCLOSED_CJK_LETTERS_AND_MONTHS = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_IDEOGRAPHIC_SUPPLEMENT;
+static { ENCLOSED_IDEOGRAPHIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC;
+static { ETHIOPIC = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC_EXTENDED;
+static { ETHIOPIC_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC_EXTENDED_A;
+static { ETHIOPIC_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC_SUPPLEMENT;
+static { ETHIOPIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock GENERAL_PUNCTUATION;
+static { GENERAL_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock GEOMETRIC_SHAPES;
+static { GEOMETRIC_SHAPES = null; }
+
+public static final java.lang.Character.UnicodeBlock GEORGIAN;
+static { GEORGIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock GEORGIAN_SUPPLEMENT;
+static { GEORGIAN_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock GLAGOLITIC;
+static { GLAGOLITIC = null; }
+
+public static final java.lang.Character.UnicodeBlock GOTHIC;
+static { GOTHIC = null; }
+
+public static final java.lang.Character.UnicodeBlock GREEK;
+static { GREEK = null; }
+
+public static final java.lang.Character.UnicodeBlock GREEK_EXTENDED;
+static { GREEK_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock GUJARATI;
+static { GUJARATI = null; }
+
+public static final java.lang.Character.UnicodeBlock GURMUKHI;
+static { GURMUKHI = null; }
+
+public static final java.lang.Character.UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS;
+static { HALFWIDTH_AND_FULLWIDTH_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_COMPATIBILITY_JAMO;
+static { HANGUL_COMPATIBILITY_JAMO = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_JAMO;
+static { HANGUL_JAMO = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_JAMO_EXTENDED_A;
+static { HANGUL_JAMO_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_JAMO_EXTENDED_B;
+static { HANGUL_JAMO_EXTENDED_B = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_SYLLABLES;
+static { HANGUL_SYLLABLES = null; }
+
+public static final java.lang.Character.UnicodeBlock HANUNOO;
+static { HANUNOO = null; }
+
+public static final java.lang.Character.UnicodeBlock HEBREW;
+static { HEBREW = null; }
+
+public static final java.lang.Character.UnicodeBlock HIGH_PRIVATE_USE_SURROGATES;
+static { HIGH_PRIVATE_USE_SURROGATES = null; }
+
+public static final java.lang.Character.UnicodeBlock HIGH_SURROGATES;
+static { HIGH_SURROGATES = null; }
+
+public static final java.lang.Character.UnicodeBlock HIRAGANA;
+static { HIRAGANA = null; }
+
+public static final java.lang.Character.UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS;
+static { IDEOGRAPHIC_DESCRIPTION_CHARACTERS = null; }
+
+public static final java.lang.Character.UnicodeBlock IMPERIAL_ARAMAIC;
+static { IMPERIAL_ARAMAIC = null; }
+
+public static final java.lang.Character.UnicodeBlock INSCRIPTIONAL_PAHLAVI;
+static { INSCRIPTIONAL_PAHLAVI = null; }
+
+public static final java.lang.Character.UnicodeBlock INSCRIPTIONAL_PARTHIAN;
+static { INSCRIPTIONAL_PARTHIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock IPA_EXTENSIONS;
+static { IPA_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock JAVANESE;
+static { JAVANESE = null; }
+
+public static final java.lang.Character.UnicodeBlock KAITHI;
+static { KAITHI = null; }
+
+public static final java.lang.Character.UnicodeBlock KANA_SUPPLEMENT;
+static { KANA_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock KANBUN;
+static { KANBUN = null; }
+
+public static final java.lang.Character.UnicodeBlock KANGXI_RADICALS;
+static { KANGXI_RADICALS = null; }
+
+public static final java.lang.Character.UnicodeBlock KANNADA;
+static { KANNADA = null; }
+
+public static final java.lang.Character.UnicodeBlock KATAKANA;
+static { KATAKANA = null; }
+
+public static final java.lang.Character.UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS;
+static { KATAKANA_PHONETIC_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock KAYAH_LI;
+static { KAYAH_LI = null; }
+
+public static final java.lang.Character.UnicodeBlock KHAROSHTHI;
+static { KHAROSHTHI = null; }
+
+public static final java.lang.Character.UnicodeBlock KHMER;
+static { KHMER = null; }
+
+public static final java.lang.Character.UnicodeBlock KHMER_SYMBOLS;
+static { KHMER_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock LAO;
+static { LAO = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_1_SUPPLEMENT;
+static { LATIN_1_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_A;
+static { LATIN_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_ADDITIONAL;
+static { LATIN_EXTENDED_ADDITIONAL = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_B;
+static { LATIN_EXTENDED_B = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_C;
+static { LATIN_EXTENDED_C = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_D;
+static { LATIN_EXTENDED_D = null; }
+
+public static final java.lang.Character.UnicodeBlock LEPCHA;
+static { LEPCHA = null; }
+
+public static final java.lang.Character.UnicodeBlock LETTERLIKE_SYMBOLS;
+static { LETTERLIKE_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock LIMBU;
+static { LIMBU = null; }
+
+public static final java.lang.Character.UnicodeBlock LINEAR_B_IDEOGRAMS;
+static { LINEAR_B_IDEOGRAMS = null; }
+
+public static final java.lang.Character.UnicodeBlock LINEAR_B_SYLLABARY;
+static { LINEAR_B_SYLLABARY = null; }
+
+public static final java.lang.Character.UnicodeBlock LISU;
+static { LISU = null; }
+
+public static final java.lang.Character.UnicodeBlock LOW_SURROGATES;
+static { LOW_SURROGATES = null; }
+
+public static final java.lang.Character.UnicodeBlock LYCIAN;
+static { LYCIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock LYDIAN;
+static { LYDIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock MAHJONG_TILES;
+static { MAHJONG_TILES = null; }
+
+public static final java.lang.Character.UnicodeBlock MALAYALAM;
+static { MALAYALAM = null; }
+
+public static final java.lang.Character.UnicodeBlock MANDAIC;
+static { MANDAIC = null; }
+
+public static final java.lang.Character.UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS;
+static { MATHEMATICAL_ALPHANUMERIC_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock MATHEMATICAL_OPERATORS;
+static { MATHEMATICAL_OPERATORS = null; }
+
+public static final java.lang.Character.UnicodeBlock MEETEI_MAYEK;
+static { MEETEI_MAYEK = null; }
+
+public static final java.lang.Character.UnicodeBlock MEETEI_MAYEK_EXTENSIONS;
+static { MEETEI_MAYEK_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock MEROITIC_CURSIVE;
+static { MEROITIC_CURSIVE = null; }
+
+public static final java.lang.Character.UnicodeBlock MEROITIC_HIEROGLYPHS;
+static { MEROITIC_HIEROGLYPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock MIAO;
+static { MIAO = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A;
+static { MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B;
+static { MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS;
+static { MISCELLANEOUS_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS;
+static { MISCELLANEOUS_SYMBOLS_AND_ARROWS = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS;
+static { MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_TECHNICAL;
+static { MISCELLANEOUS_TECHNICAL = null; }
+
+public static final java.lang.Character.UnicodeBlock MODIFIER_TONE_LETTERS;
+static { MODIFIER_TONE_LETTERS = null; }
+
+public static final java.lang.Character.UnicodeBlock MONGOLIAN;
+static { MONGOLIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock MUSICAL_SYMBOLS;
+static { MUSICAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock MYANMAR;
+static { MYANMAR = null; }
+
+public static final java.lang.Character.UnicodeBlock MYANMAR_EXTENDED_A;
+static { MYANMAR_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock NEW_TAI_LUE;
+static { NEW_TAI_LUE = null; }
+
+public static final java.lang.Character.UnicodeBlock NKO;
+static { NKO = null; }
+
+public static final java.lang.Character.UnicodeBlock NUMBER_FORMS;
+static { NUMBER_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock OGHAM;
+static { OGHAM = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_ITALIC;
+static { OLD_ITALIC = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_PERSIAN;
+static { OLD_PERSIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_SOUTH_ARABIAN;
+static { OLD_SOUTH_ARABIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_TURKIC;
+static { OLD_TURKIC = null; }
+
+public static final java.lang.Character.UnicodeBlock OL_CHIKI;
+static { OL_CHIKI = null; }
+
+public static final java.lang.Character.UnicodeBlock OPTICAL_CHARACTER_RECOGNITION;
+static { OPTICAL_CHARACTER_RECOGNITION = null; }
+
+public static final java.lang.Character.UnicodeBlock ORIYA;
+static { ORIYA = null; }
+
+public static final java.lang.Character.UnicodeBlock OSMANYA;
+static { OSMANYA = null; }
+
+public static final java.lang.Character.UnicodeBlock PHAGS_PA;
+static { PHAGS_PA = null; }
+
+public static final java.lang.Character.UnicodeBlock PHAISTOS_DISC;
+static { PHAISTOS_DISC = null; }
+
+public static final java.lang.Character.UnicodeBlock PHOENICIAN;
+static { PHOENICIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock PHONETIC_EXTENSIONS;
+static { PHONETIC_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock PHONETIC_EXTENSIONS_SUPPLEMENT;
+static { PHONETIC_EXTENSIONS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock PLAYING_CARDS;
+static { PLAYING_CARDS = null; }
+
+public static final java.lang.Character.UnicodeBlock PRIVATE_USE_AREA;
+static { PRIVATE_USE_AREA = null; }
+
+public static final java.lang.Character.UnicodeBlock REJANG;
+static { REJANG = null; }
+
+public static final java.lang.Character.UnicodeBlock RUMI_NUMERAL_SYMBOLS;
+static { RUMI_NUMERAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock RUNIC;
+static { RUNIC = null; }
+
+public static final java.lang.Character.UnicodeBlock SAMARITAN;
+static { SAMARITAN = null; }
+
+public static final java.lang.Character.UnicodeBlock SAURASHTRA;
+static { SAURASHTRA = null; }
+
+public static final java.lang.Character.UnicodeBlock SHARADA;
+static { SHARADA = null; }
+
+public static final java.lang.Character.UnicodeBlock SHAVIAN;
+static { SHAVIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock SINHALA;
+static { SINHALA = null; }
+
+public static final java.lang.Character.UnicodeBlock SMALL_FORM_VARIANTS;
+static { SMALL_FORM_VARIANTS = null; }
+
+public static final java.lang.Character.UnicodeBlock SORA_SOMPENG;
+static { SORA_SOMPENG = null; }
+
+public static final java.lang.Character.UnicodeBlock SPACING_MODIFIER_LETTERS;
+static { SPACING_MODIFIER_LETTERS = null; }
+
+public static final java.lang.Character.UnicodeBlock SPECIALS;
+static { SPECIALS = null; }
+
+public static final java.lang.Character.UnicodeBlock SUNDANESE;
+static { SUNDANESE = null; }
+
+public static final java.lang.Character.UnicodeBlock SUNDANESE_SUPPLEMENT;
+static { SUNDANESE_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS;
+static { SUPERSCRIPTS_AND_SUBSCRIPTS = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_ARROWS_A;
+static { SUPPLEMENTAL_ARROWS_A = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_ARROWS_B;
+static { SUPPLEMENTAL_ARROWS_B = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS;
+static { SUPPLEMENTAL_MATHEMATICAL_OPERATORS = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_PUNCTUATION;
+static { SUPPLEMENTAL_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A;
+static { SUPPLEMENTARY_PRIVATE_USE_AREA_A = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B;
+static { SUPPLEMENTARY_PRIVATE_USE_AREA_B = null; }
+
+@Deprecated public static final java.lang.Character.UnicodeBlock SURROGATES_AREA;
+static { SURROGATES_AREA = null; }
+
+public static final java.lang.Character.UnicodeBlock SYLOTI_NAGRI;
+static { SYLOTI_NAGRI = null; }
+
+public static final java.lang.Character.UnicodeBlock SYRIAC;
+static { SYRIAC = null; }
+
+public static final java.lang.Character.UnicodeBlock TAGALOG;
+static { TAGALOG = null; }
+
+public static final java.lang.Character.UnicodeBlock TAGBANWA;
+static { TAGBANWA = null; }
+
+public static final java.lang.Character.UnicodeBlock TAGS;
+static { TAGS = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_LE;
+static { TAI_LE = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_THAM;
+static { TAI_THAM = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_VIET;
+static { TAI_VIET = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_XUAN_JING_SYMBOLS;
+static { TAI_XUAN_JING_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock TAKRI;
+static { TAKRI = null; }
+
+public static final java.lang.Character.UnicodeBlock TAMIL;
+static { TAMIL = null; }
+
+public static final java.lang.Character.UnicodeBlock TELUGU;
+static { TELUGU = null; }
+
+public static final java.lang.Character.UnicodeBlock THAANA;
+static { THAANA = null; }
+
+public static final java.lang.Character.UnicodeBlock THAI;
+static { THAI = null; }
+
+public static final java.lang.Character.UnicodeBlock TIBETAN;
+static { TIBETAN = null; }
+
+public static final java.lang.Character.UnicodeBlock TIFINAGH;
+static { TIFINAGH = null; }
+
+public static final java.lang.Character.UnicodeBlock TRANSPORT_AND_MAP_SYMBOLS;
+static { TRANSPORT_AND_MAP_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock UGARITIC;
+static { UGARITIC = null; }
+
+public static final java.lang.Character.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS;
+static { UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS = null; }
+
+public static final java.lang.Character.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED;
+static { UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock VAI;
+static { VAI = null; }
+
+public static final java.lang.Character.UnicodeBlock VARIATION_SELECTORS;
+static { VARIATION_SELECTORS = null; }
+
+public static final java.lang.Character.UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT;
+static { VARIATION_SELECTORS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock VEDIC_EXTENSIONS;
+static { VEDIC_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock VERTICAL_FORMS;
+static { VERTICAL_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock YIJING_HEXAGRAM_SYMBOLS;
+static { YIJING_HEXAGRAM_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock YI_RADICALS;
+static { YI_RADICALS = null; }
+
+public static final java.lang.Character.UnicodeBlock YI_SYLLABLES;
+static { YI_SYLLABLES = null; }
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static enum UnicodeScript {
+COMMON,
+LATIN,
+GREEK,
+CYRILLIC,
+ARMENIAN,
+HEBREW,
+ARABIC,
+SYRIAC,
+THAANA,
+DEVANAGARI,
+BENGALI,
+GURMUKHI,
+GUJARATI,
+ORIYA,
+TAMIL,
+TELUGU,
+KANNADA,
+MALAYALAM,
+SINHALA,
+THAI,
+LAO,
+TIBETAN,
+MYANMAR,
+GEORGIAN,
+HANGUL,
+ETHIOPIC,
+CHEROKEE,
+CANADIAN_ABORIGINAL,
+OGHAM,
+RUNIC,
+KHMER,
+MONGOLIAN,
+HIRAGANA,
+KATAKANA,
+BOPOMOFO,
+HAN,
+YI,
+OLD_ITALIC,
+GOTHIC,
+DESERET,
+INHERITED,
+TAGALOG,
+HANUNOO,
+BUHID,
+TAGBANWA,
+LIMBU,
+TAI_LE,
+LINEAR_B,
+UGARITIC,
+SHAVIAN,
+OSMANYA,
+CYPRIOT,
+BRAILLE,
+BUGINESE,
+COPTIC,
+NEW_TAI_LUE,
+GLAGOLITIC,
+TIFINAGH,
+SYLOTI_NAGRI,
+OLD_PERSIAN,
+KHAROSHTHI,
+BALINESE,
+CUNEIFORM,
+PHOENICIAN,
+PHAGS_PA,
+NKO,
+SUNDANESE,
+BATAK,
+LEPCHA,
+OL_CHIKI,
+VAI,
+SAURASHTRA,
+KAYAH_LI,
+REJANG,
+LYCIAN,
+CARIAN,
+LYDIAN,
+CHAM,
+TAI_THAM,
+TAI_VIET,
+AVESTAN,
+EGYPTIAN_HIEROGLYPHS,
+SAMARITAN,
+MANDAIC,
+LISU,
+BAMUM,
+JAVANESE,
+MEETEI_MAYEK,
+IMPERIAL_ARAMAIC,
+OLD_SOUTH_ARABIAN,
+INSCRIPTIONAL_PARTHIAN,
+INSCRIPTIONAL_PAHLAVI,
+OLD_TURKIC,
+BRAHMI,
+KAITHI,
+MEROITIC_HIEROGLYPHS,
+MEROITIC_CURSIVE,
+SORA_SOMPENG,
+CHAKMA,
+SHARADA,
+TAKRI,
+MIAO,
+UNKNOWN;
+
+@libcore.util.NonNull public static java.lang.Character.UnicodeScript of(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Character.UnicodeScript forName(@libcore.util.NonNull java.lang.String scriptName) { throw new RuntimeException("Stub!"); }
+}
+
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Class.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Class.annotated.java
new file mode 100644
index 0000000..dfbbd9b
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Class.annotated.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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. 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 java.lang;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Type;
+import java.lang.reflect.GenericDeclaration;
+import java.lang.reflect.TypeVariable;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.io.InputStream;
+import java.util.HashMap;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Class<T> implements java.io.Serializable, java.lang.reflect.GenericDeclaration, java.lang.reflect.Type, java.lang.reflect.AnnotatedElement {
+
+Class() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Class<?> forName(@libcore.util.NonNull java.lang.String className) throws java.lang.ClassNotFoundException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Class<?> forName(@libcore.util.NonNull java.lang.String name, boolean initialize, @libcore.util.Nullable java.lang.ClassLoader loader) throws java.lang.ClassNotFoundException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public native T newInstance() throws java.lang.IllegalAccessException, java.lang.InstantiationException;
+
+public boolean isInstance(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public boolean isAssignableFrom(@libcore.util.NonNull java.lang.Class<?> cls) { throw new RuntimeException("Stub!"); }
+
+public boolean isInterface() { throw new RuntimeException("Stub!"); }
+
+public boolean isArray() { throw new RuntimeException("Stub!"); }
+
+public boolean isPrimitive() { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotation() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.ClassLoader getClassLoader() { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.reflect.@libcore.util.NonNull TypeVariable<java.lang.@libcore.util.NonNull Class<T>> @libcore.util.NonNull [] getTypeParameters() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.Class<? super T> getSuperclass() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.reflect.Type getGenericSuperclass() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.Package getPackage() { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull Class<?> @libcore.util.NonNull [] getInterfaces() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getGenericInterfaces() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.Class<?> getComponentType() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull Object @libcore.util.Nullable [] getSigners() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.reflect.Method getEnclosingMethod() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.reflect.Constructor<?> getEnclosingConstructor() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public native java.lang.Class<?> getDeclaringClass();
+
+@libcore.util.Nullable public native java.lang.Class<?> getEnclosingClass();
+
+@libcore.util.NonNull public java.lang.String getSimpleName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getTypeName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.String getCanonicalName() { throw new RuntimeException("Stub!"); }
+
+public native boolean isAnonymousClass();
+
+public boolean isLocalClass() { throw new RuntimeException("Stub!"); }
+
+public boolean isMemberClass() { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull Class<?> @libcore.util.NonNull [] getClasses() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.@libcore.util.NonNull Field @libcore.util.NonNull [] getFields() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.@libcore.util.NonNull Method @libcore.util.NonNull [] getMethods() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.@libcore.util.NonNull Constructor<?> @libcore.util.NonNull [] getConstructors() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Field getField(@libcore.util.NonNull java.lang.String name) throws java.lang.NoSuchFieldException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Method getMethod(@libcore.util.NonNull java.lang.String name, java.lang.@libcore.util.NonNull Class<?> @libcore.util.Nullable ... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Constructor<T> getConstructor(java.lang.@libcore.util.NonNull Class<?> @libcore.util.Nullable ... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public native java.lang.@libcore.util.NonNull Class<?> @libcore.util.NonNull [] getDeclaredClasses();
+
+public native java.lang.reflect.@libcore.util.NonNull Field @libcore.util.NonNull [] getDeclaredFields();
+
+public java.lang.reflect.@libcore.util.NonNull Method @libcore.util.NonNull [] getDeclaredMethods() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.@libcore.util.NonNull Constructor<?> @libcore.util.NonNull [] getDeclaredConstructors() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public native java.lang.reflect.Field getDeclaredField(@libcore.util.NonNull java.lang.String name) throws java.lang.NoSuchFieldException;
+
+@libcore.util.NonNull public java.lang.reflect.Method getDeclaredMethod(@libcore.util.NonNull java.lang.String name, java.lang.@libcore.util.NonNull Class<?> @libcore.util.Nullable ... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Constructor<T> getDeclaredConstructor(java.lang.@libcore.util.NonNull Class<?> @libcore.util.Nullable ... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.io.InputStream getResourceAsStream(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public java.net.URL getResource(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public java.security.ProtectionDomain getProtectionDomain() { throw new RuntimeException("Stub!"); }
+
+public boolean desiredAssertionStatus() { throw new RuntimeException("Stub!"); }
+
+public boolean isEnum() { throw new RuntimeException("Stub!"); }
+
+// TODO: Make return type @NonNull T @Nullable [] once metalava supports TYPE_USE.
+public T @libcore.util.Nullable [] getEnumConstants() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public T cast(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public <U> java.lang.Class<? extends U> asSubclass(@libcore.util.NonNull java.lang.Class<U> clazz) { throw new RuntimeException("Stub!"); }
+
+public <A extends java.lang.annotation.Annotation> A getAnnotation(@libcore.util.NonNull java.lang.Class<A> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotationPresent(@libcore.util.NonNull java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <A extends java.lang.annotation.Annotation> @libcore.util.NonNull A @libcore.util.NonNull [] getAnnotationsByType(@libcore.util.NonNull java.lang.Class<A> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getAnnotations() { throw new RuntimeException("Stub!"); }
+
+public native <A extends java.lang.annotation.Annotation> @libcore.util.Nullable A getDeclaredAnnotation(@libcore.util.NonNull java.lang.Class<A> annotationClass);
+
+public native java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getDeclaredAnnotations();
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Double.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Double.annotated.java
new file mode 100644
index 0000000..8f565fc
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Double.annotated.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1994, 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
+ * 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 java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Double extends java.lang.Number implements java.lang.Comparable<java.lang.Double> {
+
+public Double(double value) { throw new RuntimeException("Stub!"); }
+
+public Double(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(double d) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toHexString(double d) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Double valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Double valueOf(double d) { throw new RuntimeException("Stub!"); }
+
+public static double parseDouble(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static boolean isNaN(double v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isInfinite(double v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isFinite(double d) { throw new RuntimeException("Stub!"); }
+
+public boolean isNaN() { throw new RuntimeException("Stub!"); }
+
+public boolean isInfinite() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(double value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static long doubleToLongBits(double value) { throw new RuntimeException("Stub!"); }
+
+public static native long doubleToRawLongBits(double value);
+
+public static native double longBitsToDouble(long bits);
+
+public int compareTo(@libcore.util.NonNull java.lang.Double anotherDouble) { throw new RuntimeException("Stub!"); }
+
+public static int compare(double d1, double d2) { throw new RuntimeException("Stub!"); }
+
+public static double sum(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static double max(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static double min(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 8; // 0x8
+
+public static final int MAX_EXPONENT = 1023; // 0x3ff
+
+public static final double MAX_VALUE = 1.7976931348623157E308;
+
+public static final int MIN_EXPONENT = -1022; // 0xfffffc02
+
+public static final double MIN_NORMAL = 2.2250738585072014E-308;
+
+public static final double MIN_VALUE = 4.9E-324;
+
+public static final double NEGATIVE_INFINITY = (-1.0/0.0);
+
+public static final double NaN = (0.0/0.0);
+
+public static final double POSITIVE_INFINITY = (1.0/0.0);
+
+public static final int SIZE = 64; // 0x40
+
+public static final java.lang.Class<java.lang.Double> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Enum.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Enum.annotated.java
new file mode 100644
index 0000000..75c7662
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Enum.annotated.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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 java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Enum<E extends java.lang.Enum<E>> implements java.lang.Comparable<E>, java.io.Serializable {
+
+protected Enum(java.lang.String name, int ordinal) { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String name() { throw new RuntimeException("Stub!"); }
+
+public final int ordinal() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public final boolean equals(java.lang.Object other) { throw new RuntimeException("Stub!"); }
+
+public final int hashCode() { throw new RuntimeException("Stub!"); }
+
+protected final java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
+public final int compareTo(E o) { throw new RuntimeException("Stub!"); }
+
+public final java.lang.Class<E> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
+public static <T extends java.lang.Enum<T>> T valueOf(java.lang.Class<T> enumType, java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+protected final void finalize() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Float.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Float.annotated.java
new file mode 100644
index 0000000..a459ec1
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Float.annotated.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1994, 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
+ * 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 java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Float extends java.lang.Number implements java.lang.Comparable<java.lang.Float> {
+
+public Float(float value) { throw new RuntimeException("Stub!"); }
+
+public Float(double value) { throw new RuntimeException("Stub!"); }
+
+public Float(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(float f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toHexString(float f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Float valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Float valueOf(float f) { throw new RuntimeException("Stub!"); }
+
+public static float parseFloat(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static boolean isNaN(float v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isInfinite(float v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isFinite(float f) { throw new RuntimeException("Stub!"); }
+
+public boolean isNaN() { throw new RuntimeException("Stub!"); }
+
+public boolean isInfinite() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(float value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static int floatToIntBits(float value) { throw new RuntimeException("Stub!"); }
+
+public static native int floatToRawIntBits(float value);
+
+public static native float intBitsToFloat(int bits);
+
+public int compareTo(@libcore.util.NonNull java.lang.Float anotherFloat) { throw new RuntimeException("Stub!"); }
+
+public static int compare(float f1, float f2) { throw new RuntimeException("Stub!"); }
+
+public static float sum(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static float max(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static float min(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 4; // 0x4
+
+public static final int MAX_EXPONENT = 127; // 0x7f
+
+public static final float MAX_VALUE = 3.4028235E38f;
+
+public static final int MIN_EXPONENT = -126; // 0xffffff82
+
+public static final float MIN_NORMAL = 1.17549435E-38f;
+
+public static final float MIN_VALUE = 1.4E-45f;
+
+public static final float NEGATIVE_INFINITY = (-1.0f/0.0f);
+
+public static final float NaN = (0.0f/0.0f);
+
+public static final float POSITIVE_INFINITY = (1.0f/0.0f);
+
+public static final int SIZE = 32; // 0x20
+
+public static final java.lang.Class<java.lang.Float> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Integer.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Integer.annotated.java
new file mode 100644
index 0000000..d3f6753
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Integer.annotated.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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
+ * 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 java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Integer extends java.lang.Number implements java.lang.Comparable<java.lang.Integer> {
+
+public Integer(int value) { throw new RuntimeException("Stub!"); }
+
+public Integer(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(int i, int radix) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toUnsignedString(int i, int radix) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toHexString(int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toOctalString(int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toBinaryString(int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toUnsignedString(int i) { throw new RuntimeException("Stub!"); }
+
+public static int parseInt(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static int parseInt(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static int parseUnsignedInt(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static int parseUnsignedInt(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Integer valueOf(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Integer valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Integer valueOf(int i) { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(int value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Integer getInteger(@libcore.util.NonNull java.lang.String nm) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Integer getInteger(@libcore.util.NonNull java.lang.String nm, int val) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Integer getInteger(@libcore.util.NonNull java.lang.String nm, @libcore.util.Nullable java.lang.Integer val) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Integer decode(@libcore.util.NonNull java.lang.String nm) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Integer anotherInteger) { throw new RuntimeException("Stub!"); }
+
+public static int compare(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static int compareUnsigned(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long toUnsignedLong(int x) { throw new RuntimeException("Stub!"); }
+
+public static int divideUnsigned(int dividend, int divisor) { throw new RuntimeException("Stub!"); }
+
+public static int remainderUnsigned(int dividend, int divisor) { throw new RuntimeException("Stub!"); }
+
+public static int highestOneBit(int i) { throw new RuntimeException("Stub!"); }
+
+public static int lowestOneBit(int i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfLeadingZeros(int i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfTrailingZeros(int i) { throw new RuntimeException("Stub!"); }
+
+public static int bitCount(int i) { throw new RuntimeException("Stub!"); }
+
+public static int rotateLeft(int i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static int rotateRight(int i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static int reverse(int i) { throw new RuntimeException("Stub!"); }
+
+public static int signum(int i) { throw new RuntimeException("Stub!"); }
+
+public static int reverseBytes(int i) { throw new RuntimeException("Stub!"); }
+
+public static int sum(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static int max(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static int min(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 4; // 0x4
+
+public static final int MAX_VALUE = 2147483647; // 0x7fffffff
+
+public static final int MIN_VALUE = -2147483648; // 0x80000000
+
+public static final int SIZE = 32; // 0x20
+
+public static final java.lang.Class<java.lang.Integer> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/Iterable.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/Iterable.annotated.java
index 011089d..b331a7a 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/Iterable.annotated.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, 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
@@ -22,23 +22,17 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+package java.lang;
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
+import java.util.Iterator;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import libcore.util.NonNull;
+import libcore.util.NullFromTypeParam;
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+public interface Iterable<T> {
-
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
- return JVM_InternString(env, this);
-}
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
-
-void register_java_lang_String(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
+ public @NonNull Iterator<@NullFromTypeParam T> iterator();
+ public default void forEach(Consumer<? super T> action) { throw new RuntimeException("Stub!"); }
+ public default Spliterator<T> spliterator() { throw new RuntimeException("Stub!"); }
}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Long.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Long.annotated.java
new file mode 100644
index 0000000..b077ef5
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Long.annotated.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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
+ * 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 java.lang;
+
+import java.math.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Long extends java.lang.Number implements java.lang.Comparable<java.lang.Long> {
+
+public Long(long value) { throw new RuntimeException("Stub!"); }
+
+public Long(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(long i, int radix) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toUnsignedString(long i, int radix) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toHexString(long i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toOctalString(long i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toBinaryString(long i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(long i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toUnsignedString(long i) { throw new RuntimeException("Stub!"); }
+
+public static long parseLong(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static long parseLong(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static long parseUnsignedLong(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static long parseUnsignedLong(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Long valueOf(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Long valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Long valueOf(long l) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Long decode(@libcore.util.NonNull java.lang.String nm) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(long value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Long getLong(@libcore.util.NonNull java.lang.String nm) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Long getLong(@libcore.util.NonNull java.lang.String nm, long val) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Long getLong(@libcore.util.NonNull java.lang.String nm, @libcore.util.Nullable java.lang.Long val) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Long anotherLong) { throw new RuntimeException("Stub!"); }
+
+public static int compare(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int compareUnsigned(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static long divideUnsigned(long dividend, long divisor) { throw new RuntimeException("Stub!"); }
+
+public static long remainderUnsigned(long dividend, long divisor) { throw new RuntimeException("Stub!"); }
+
+public static long highestOneBit(long i) { throw new RuntimeException("Stub!"); }
+
+public static long lowestOneBit(long i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfLeadingZeros(long i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfTrailingZeros(long i) { throw new RuntimeException("Stub!"); }
+
+public static int bitCount(long i) { throw new RuntimeException("Stub!"); }
+
+public static long rotateLeft(long i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static long rotateRight(long i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static long reverse(long i) { throw new RuntimeException("Stub!"); }
+
+public static int signum(long i) { throw new RuntimeException("Stub!"); }
+
+public static long reverseBytes(long i) { throw new RuntimeException("Stub!"); }
+
+public static long sum(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static long max(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static long min(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 8; // 0x8
+
+public static final long MAX_VALUE = 9223372036854775807L; // 0x7fffffffffffffffL
+
+public static final long MIN_VALUE = -9223372036854775808L; // 0x8000000000000000L
+
+public static final int SIZE = 64; // 0x40
+
+public static final java.lang.Class<java.lang.Long> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Object.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Object.annotated.java
new file mode 100644
index 0000000..61c4fd1
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Object.annotated.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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
+ * 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 java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Object {
+
+public Object() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.lang.Class<?> getClass() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+protected java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public final native void notify();
+
+public final native void notifyAll();
+
+public final void wait(long timeout) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public final native void wait(long timeout, int nanos) throws java.lang.InterruptedException;
+
+public final void wait() throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+protected void finalize() throws java.lang.Throwable { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/String.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/String.annotated.java
new file mode 100644
index 0000000..a8cf1de
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/String.annotated.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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
+ * 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 java.lang;
+
+import java.nio.charset.Charset;
+import java.io.UnsupportedEncodingException;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+import java.util.StringJoiner;
+import java.util.Locale;
+import java.util.Formatter;
+import java.util.Comparator;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class String implements java.io.Serializable, java.lang.Comparable<java.lang.String>, java.lang.CharSequence {
+
+public String() { throw new RuntimeException("Stub!"); }
+
+public String(@libcore.util.NonNull java.lang.String original) { throw new RuntimeException("Stub!"); }
+
+public String(char[] value) { throw new RuntimeException("Stub!"); }
+
+public String(char[] value, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+public String(int[] codePoints, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public String(byte[] ascii, int hibyte, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public String(byte[] ascii, int hibyte) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, int offset, int length, @libcore.util.NonNull java.lang.String charsetName) throws java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, int offset, int length, @libcore.util.NonNull java.nio.charset.Charset charset) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, @libcore.util.NonNull java.lang.String charsetName) throws java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, @libcore.util.NonNull java.nio.charset.Charset charset) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes) { throw new RuntimeException("Stub!"); }
+
+public String(@libcore.util.NonNull java.lang.StringBuffer buffer) { throw new RuntimeException("Stub!"); }
+
+public String(@libcore.util.NonNull java.lang.StringBuilder builder) { throw new RuntimeException("Stub!"); }
+
+public int length() { throw new RuntimeException("Stub!"); }
+
+public boolean isEmpty() { throw new RuntimeException("Stub!"); }
+
+public native char charAt(int index);
+
+public int codePointAt(int index) { throw new RuntimeException("Stub!"); }
+
+public int codePointBefore(int index) { throw new RuntimeException("Stub!"); }
+
+public int codePointCount(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public int offsetByCodePoints(int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+public byte[] getBytes(@libcore.util.NonNull java.lang.String charsetName) throws java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public byte[] getBytes(@libcore.util.NonNull java.nio.charset.Charset charset) { throw new RuntimeException("Stub!"); }
+
+public byte[] getBytes() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object anObject) { throw new RuntimeException("Stub!"); }
+
+public boolean contentEquals(@libcore.util.NonNull java.lang.StringBuffer sb) { throw new RuntimeException("Stub!"); }
+
+public boolean contentEquals(@libcore.util.NonNull java.lang.CharSequence cs) { throw new RuntimeException("Stub!"); }
+
+public boolean equalsIgnoreCase(@libcore.util.Nullable java.lang.String anotherString) { throw new RuntimeException("Stub!"); }
+
+public native int compareTo(@libcore.util.NonNull java.lang.String anotherString);
+
+public int compareToIgnoreCase(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public boolean regionMatches(int toffset, @libcore.util.NonNull java.lang.String other, int ooffset, int len) { throw new RuntimeException("Stub!"); }
+
+public boolean regionMatches(boolean ignoreCase, int toffset, @libcore.util.NonNull java.lang.String other, int ooffset, int len) { throw new RuntimeException("Stub!"); }
+
+public boolean startsWith(@libcore.util.NonNull java.lang.String prefix, int toffset) { throw new RuntimeException("Stub!"); }
+
+public boolean startsWith(@libcore.util.NonNull java.lang.String prefix) { throw new RuntimeException("Stub!"); }
+
+public boolean endsWith(@libcore.util.NonNull java.lang.String suffix) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public int indexOf(int ch) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(int ch, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(int ch) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(int ch, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String substring(int beginIndex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String substring(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.CharSequence subSequence(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public native java.lang.String concat(@libcore.util.NonNull java.lang.String str);
+
+@libcore.util.NonNull public java.lang.String replace(char oldChar, char newChar) { throw new RuntimeException("Stub!"); }
+
+public boolean matches(@libcore.util.NonNull java.lang.String regex) { throw new RuntimeException("Stub!"); }
+
+public boolean contains(@libcore.util.NonNull java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String replaceFirst(@libcore.util.NonNull java.lang.String regex, @libcore.util.NonNull java.lang.String replacement) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String replaceAll(@libcore.util.NonNull java.lang.String regex, @libcore.util.NonNull java.lang.String replacement) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String replace(@libcore.util.NonNull java.lang.CharSequence target, @libcore.util.NonNull java.lang.CharSequence replacement) { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull String @libcore.util.NonNull [] split(@libcore.util.NonNull java.lang.String regex, int limit) { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull String @libcore.util.NonNull [] split(@libcore.util.NonNull java.lang.String regex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String join(@libcore.util.NonNull java.lang.CharSequence delimiter, java.lang.@libcore.util.NonNull CharSequence @libcore.util.Nullable ... elements) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String join(@libcore.util.NonNull java.lang.CharSequence delimiter, @libcore.util.NonNull java.lang.Iterable<? extends @libcore.util.Nullable java.lang.CharSequence> elements) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toLowerCase(@libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toLowerCase() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toUpperCase(@libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toUpperCase() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String trim() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public native char[] toCharArray();
+
+@libcore.util.NonNull public static java.lang.String format(@libcore.util.NonNull java.lang.String format, java.lang.@libcore.util.Nullable Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String format(@libcore.util.NonNull java.util.Locale l, @libcore.util.NonNull java.lang.String format, java.lang.@libcore.util.Nullable Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(char[] data) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(char[] data, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String copyValueOf(char[] data, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String copyValueOf(char[] data) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(char c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(long l) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(float f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(double d) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public native java.lang.String intern();
+
+public static final java.util.Comparator<java.lang.String> CASE_INSENSITIVE_ORDER;
+static { CASE_INSENSITIVE_ORDER = null; }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/StringBuffer.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/StringBuffer.annotated.java
new file mode 100644
index 0000000..4baff67
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/StringBuffer.annotated.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 1994, 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
+ * 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 java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class StringBuffer implements java.lang.Appendable, java.lang.CharSequence, java.io.Serializable {
+
+public StringBuffer() { throw new RuntimeException("Stub!"); }
+
+public StringBuffer(int capacity) { throw new RuntimeException("Stub!"); }
+
+public StringBuffer(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public StringBuffer(@libcore.util.NonNull java.lang.CharSequence seq) { throw new RuntimeException("Stub!"); }
+
+public synchronized int length() { throw new RuntimeException("Stub!"); }
+
+public synchronized int capacity() { throw new RuntimeException("Stub!"); }
+
+public synchronized void ensureCapacity(int minimumCapacity) { throw new RuntimeException("Stub!"); }
+
+public synchronized void trimToSize() { throw new RuntimeException("Stub!"); }
+
+public synchronized void setLength(int newLength) { throw new RuntimeException("Stub!"); }
+
+public synchronized char charAt(int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized int codePointAt(int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized int codePointBefore(int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized int codePointCount(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public synchronized int offsetByCodePoints(int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public synchronized void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+public synchronized void setCharAt(int index, char ch) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.StringBuffer sb) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(char[] str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(char c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer appendCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(long lng) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(float f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(double d) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer delete(int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer deleteCharAt(int index) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer replace(int start, int end, @libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.String substring(int start) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.CharSequence subSequence(int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.String substring(int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer insert(int index, char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer insert(int offset, @libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer insert(int offset, @libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer insert(int offset, char[] str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuffer insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuffer insert(int offset, boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer insert(int offset, char c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuffer insert(int offset, int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuffer insert(int offset, long l) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuffer insert(int offset, float f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuffer insert(int offset, double d) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public synchronized int indexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public synchronized int lastIndexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer reverse() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.String toString() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/StringBuilder.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/StringBuilder.annotated.java
new file mode 100644
index 0000000..9ec4039
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/StringBuilder.annotated.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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 java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class StringBuilder implements java.lang.Appendable, java.lang.CharSequence, java.io.Serializable {
+
+public StringBuilder() { throw new RuntimeException("Stub!"); }
+
+public StringBuilder(int capacity) { throw new RuntimeException("Stub!"); }
+
+public StringBuilder(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public StringBuilder(@libcore.util.NonNull java.lang.CharSequence seq) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.StringBuffer sb) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(char[] str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(char c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(long lng) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(float f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(double d) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder appendCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder delete(int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder deleteCharAt(int index) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder replace(int start, int end, @libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int index, char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, @libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, @libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, char[] str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, char c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, long l) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, float f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, double d) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder reverse() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public void trimToSize() { throw new RuntimeException("Stub!"); }
+
+public int codePointAt(int index) { throw new RuntimeException("Stub!"); }
+
+public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+public int length() { throw new RuntimeException("Stub!"); }
+
+public void setCharAt(int index, char ch) { throw new RuntimeException("Stub!"); }
+
+public java.lang.CharSequence subSequence(int start, int end) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String substring(int start) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String substring(int start, int end) { throw new RuntimeException("Stub!"); }
+
+public int capacity() { throw new RuntimeException("Stub!"); }
+
+public void setLength(int newLength) { throw new RuntimeException("Stub!"); }
+
+public void ensureCapacity(int minimumCapacity) { throw new RuntimeException("Stub!"); }
+
+public int codePointBefore(int index) { throw new RuntimeException("Stub!"); }
+
+public char charAt(int index) { throw new RuntimeException("Stub!"); }
+
+public int codePointCount(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public int offsetByCodePoints(int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/System.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/System.annotated.java
new file mode 100644
index 0000000..82e62b8
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/System.annotated.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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
+ * 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 java.lang;
+
+import java.io.*;
+import java.nio.channels.spi.SelectorProvider;
+import java.nio.channels.Channel;
+import java.util.Properties;
+import java.util.PropertyPermission;
+import java.util.Map;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class System {
+
+System() { throw new RuntimeException("Stub!"); }
+
+public static void setIn(@libcore.util.Nullable java.io.InputStream in) { throw new RuntimeException("Stub!"); }
+
+public static void setOut(@libcore.util.Nullable java.io.PrintStream out) { throw new RuntimeException("Stub!"); }
+
+public static void setErr(@libcore.util.Nullable java.io.PrintStream err) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.io.Console console() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.nio.channels.Channel inheritedChannel() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public static void setSecurityManager(@libcore.util.Nullable java.lang.SecurityManager s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.SecurityManager getSecurityManager() { throw new RuntimeException("Stub!"); }
+
+public static native long currentTimeMillis();
+
+public static native long nanoTime();
+
+public static native void arraycopy(@libcore.util.NonNull java.lang.Object src, int srcPos, java.lang.Object dest, int destPos, int length);
+
+public static int identityHashCode(@libcore.util.Nullable java.lang.Object x) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Properties getProperties() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String lineSeparator() { throw new RuntimeException("Stub!"); }
+
+public static void setProperties(@libcore.util.Nullable java.util.Properties props) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.String getProperty(@libcore.util.NonNull java.lang.String key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.String getProperty(@libcore.util.NonNull java.lang.String key, @libcore.util.Nullable java.lang.String def) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.String setProperty(@libcore.util.NonNull java.lang.String key, @libcore.util.Nullable java.lang.String value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.String clearProperty(@libcore.util.NonNull java.lang.String key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.String getenv(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public static java.util.Map<java.lang.String,java.lang.String> getenv() { throw new RuntimeException("Stub!"); }
+
+public static void exit(int status) { throw new RuntimeException("Stub!"); }
+
+public static void gc() { throw new RuntimeException("Stub!"); }
+
+public static void runFinalization() { throw new RuntimeException("Stub!"); }
+
+@Deprecated public static void runFinalizersOnExit(boolean value) { throw new RuntimeException("Stub!"); }
+
+public static void load(@libcore.util.NonNull java.lang.String filename) { throw new RuntimeException("Stub!"); }
+
+public static void loadLibrary(@libcore.util.NonNull java.lang.String libname) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static native java.lang.String mapLibraryName(@libcore.util.NonNull java.lang.String libname);
+
+public static final java.io.PrintStream err;
+static { err = null; }
+
+public static final java.io.InputStream in;
+static { in = null; }
+
+public static final java.io.PrintStream out;
+static { out = null; }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Thread.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Thread.annotated.java
new file mode 100644
index 0000000..27a0114
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Thread.annotated.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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
+ * 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 java.lang;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.util.Map;
+import java.util.concurrent.locks.LockSupport;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Thread implements java.lang.Runnable {
+
+public Thread() { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.Runnable target) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.Runnable target) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.Runnable target, java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.Runnable target, java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.Runnable target, java.lang.String name, long stackSize) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static native java.lang.Thread currentThread();
+
+public static native void yield();
+
+public static void sleep(long millis) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public static void sleep(long millis, int nanos) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+protected java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
+public synchronized void start() { throw new RuntimeException("Stub!"); }
+
+public void run() { throw new RuntimeException("Stub!"); }
+
+@Deprecated public final void stop() { throw new RuntimeException("Stub!"); }
+
+@Deprecated public final synchronized void stop(java.lang.Throwable obj) { throw new RuntimeException("Stub!"); }
+
+public void interrupt() { throw new RuntimeException("Stub!"); }
+
+public static native boolean interrupted();
+
+public native boolean isInterrupted();
+
+@Deprecated public void destroy() { throw new RuntimeException("Stub!"); }
+
+public final boolean isAlive() { throw new RuntimeException("Stub!"); }
+
+@Deprecated public final void suspend() { throw new RuntimeException("Stub!"); }
+
+@Deprecated public final void resume() { throw new RuntimeException("Stub!"); }
+
+public final void setPriority(int newPriority) { throw new RuntimeException("Stub!"); }
+
+public final int getPriority() { throw new RuntimeException("Stub!"); }
+
+public final synchronized void setName(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.ThreadGroup getThreadGroup() { throw new RuntimeException("Stub!"); }
+
+public static int activeCount() { throw new RuntimeException("Stub!"); }
+
+public static int enumerate(java.lang.Thread[] tarray) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public int countStackFrames() { throw new RuntimeException("Stub!"); }
+
+public final void join(long millis) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public final void join(long millis, int nanos) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public final void join() throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public static void dumpStack() { throw new RuntimeException("Stub!"); }
+
+public final void setDaemon(boolean on) { throw new RuntimeException("Stub!"); }
+
+public final boolean isDaemon() { throw new RuntimeException("Stub!"); }
+
+public final void checkAccess() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public java.lang.ClassLoader getContextClassLoader() { throw new RuntimeException("Stub!"); }
+
+public void setContextClassLoader(java.lang.ClassLoader cl) { throw new RuntimeException("Stub!"); }
+
+public static native boolean holdsLock(java.lang.Object obj);
+
+public java.lang.StackTraceElement[] getStackTrace() { throw new RuntimeException("Stub!"); }
+
+public static java.util.Map<java.lang.Thread,java.lang.StackTraceElement[]> getAllStackTraces() { throw new RuntimeException("Stub!"); }
+
+public long getId() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Thread.State getState() { throw new RuntimeException("Stub!"); }
+
+public static void setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler eh) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() { throw new RuntimeException("Stub!"); }
+
+public void setUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler eh) { throw new RuntimeException("Stub!"); }
+
+public static final int MAX_PRIORITY = 10; // 0xa
+
+public static final int MIN_PRIORITY = 1; // 0x1
+
+public static final int NORM_PRIORITY = 5; // 0x5
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static enum State {
+NEW,
+RUNNABLE,
+BLOCKED,
+WAITING,
+TIMED_WAITING,
+TERMINATED;
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+@java.lang.FunctionalInterface
+public static interface UncaughtExceptionHandler {
+
+public void uncaughtException(java.lang.Thread t, java.lang.Throwable e);
+}
+
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/ThreadLocal.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/ThreadLocal.annotated.java
new file mode 100644
index 0000000..3b7e93a
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/ThreadLocal.annotated.java
@@ -0,0 +1,48 @@
+/*
+ * 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
+ * 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 java.lang;
+
+import java.lang.ref.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Supplier;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ThreadLocal<T> {
+
+public ThreadLocal() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable protected T initialValue() { throw new RuntimeException("Stub!"); }
+
+public static <S> java.lang.ThreadLocal<S> withInitial(@libcore.util.NonNull java.util.function.Supplier<? extends S> supplier) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public T get() { throw new RuntimeException("Stub!"); }
+
+public void set(@libcore.util.NullFromTypeParam T value) { throw new RuntimeException("Stub!"); }
+
+public void remove() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/AccessibleObject.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/AccessibleObject.annotated.java
new file mode 100644
index 0000000..4846fc7
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/AccessibleObject.annotated.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 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. 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 java.lang.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class AccessibleObject implements java.lang.reflect.AnnotatedElement {
+
+protected AccessibleObject() { throw new RuntimeException("Stub!"); }
+
+public static void setAccessible(java.lang.reflect.AccessibleObject[] array, boolean flag) throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public void setAccessible(boolean flag) throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public boolean isAccessible() { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getAnnotations() { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/AnnotatedElement.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/AnnotatedElement.annotated.java
new file mode 100644
index 0000000..b6f67b7
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/AnnotatedElement.annotated.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * 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
+ * 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 java.lang.reflect;
+
+import java.lang.annotation.AnnotationFormatError;
+import java.lang.annotation.Annotation;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface AnnotatedElement {
+
+public default boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.Class<T> annotationClass);
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getAnnotations();
+
+public default <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public default <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public default <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getDeclaredAnnotations();
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Array.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Array.annotated.java
new file mode 100644
index 0000000..fb09931
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Array.annotated.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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 java.lang.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Array {
+
+Array() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Object newInstance(java.lang.Class<?> componentType, int length) throws java.lang.NegativeArraySizeException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Object newInstance(java.lang.Class<?> componentType, int... dimensions) throws java.lang.IllegalArgumentException, java.lang.NegativeArraySizeException { throw new RuntimeException("Stub!"); }
+
+public static int getLength(java.lang.Object array) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Object get(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static boolean getBoolean(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static byte getByte(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static char getChar(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static short getShort(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static int getInt(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static long getLong(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static float getFloat(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static double getDouble(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void set(java.lang.Object array, int index, java.lang.Object value) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setBoolean(java.lang.Object array, int index, boolean z) { throw new RuntimeException("Stub!"); }
+
+public static void setByte(java.lang.Object array, int index, byte b) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setChar(java.lang.Object array, int index, char c) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setShort(java.lang.Object array, int index, short s) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setInt(java.lang.Object array, int index, int i) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setLong(java.lang.Object array, int index, long l) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setFloat(java.lang.Object array, int index, float f) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setDouble(java.lang.Object array, int index, double d) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Constructor.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Constructor.annotated.java
new file mode 100644
index 0000000..2ebfbe6
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Constructor.annotated.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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 java.lang.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Constructor<T> extends java.lang.reflect.Executable {
+
+Constructor() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Class<T> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.TypeVariable<java.lang.reflect.Constructor<T>>[] getTypeParameters() { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull Class<?> @libcore.util.NonNull [] getParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public int getParameterCount() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Type[] getGenericParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Class<?>[] getExceptionTypes();
+
+public java.lang.reflect.Type[] getGenericExceptionTypes() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public T newInstance(java.lang.Object... initargs) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.InstantiationException, java.lang.reflect.InvocationTargetException { throw new RuntimeException("Stub!"); }
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.Annotation[] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.Annotation[][] getParameterAnnotations() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Executable.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Executable.annotated.java
new file mode 100644
index 0000000..dade51c
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Executable.annotated.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 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
+ * 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 java.lang.reflect;
+
+import java.lang.annotation.Annotation;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Executable extends java.lang.reflect.AccessibleObject implements java.lang.reflect.Member, java.lang.reflect.GenericDeclaration {
+
+Executable() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public abstract java.lang.Class<?> getDeclaringClass();
+
+@libcore.util.NonNull public abstract java.lang.String getName();
+
+public abstract int getModifiers();
+
+public abstract java.lang.reflect.@libcore.util.NonNull TypeVariable<?> @libcore.util.NonNull [] getTypeParameters();
+
+public abstract java.lang.@libcore.util.NonNull Class<?> @libcore.util.NonNull [] getParameterTypes();
+
+public int getParameterCount() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getGenericParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.@libcore.util.NonNull Parameter @libcore.util.NonNull [] getParameters() { throw new RuntimeException("Stub!"); }
+
+public abstract java.lang.@libcore.util.NonNull Class<?> @libcore.util.NonNull [] getExceptionTypes();
+
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getGenericExceptionTypes() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public abstract java.lang.String toGenericString();
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public abstract java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] @libcore.util.NonNull [] getParameterAnnotations();
+
+public <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
+public final boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType) { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Field.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Field.annotated.java
new file mode 100644
index 0000000..d212353
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Field.annotated.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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 java.lang.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Field extends java.lang.reflect.AccessibleObject implements java.lang.reflect.Member {
+
+Field() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Class<?> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public boolean isEnumConstant() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Class<?> getType() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Type getGenericType() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Object get(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native boolean getBoolean(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native byte getByte(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native char getChar(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native short getShort(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native int getInt(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native long getLong(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native float getFloat(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native double getDouble(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void set(java.lang.Object obj, java.lang.Object value) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setBoolean(java.lang.Object obj, boolean z) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setByte(java.lang.Object obj, byte b) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setChar(java.lang.Object obj, char c) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setShort(java.lang.Object obj, short s) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setInt(java.lang.Object obj, int i) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setLong(java.lang.Object obj, long l) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setFloat(java.lang.Object obj, float f) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setDouble(java.lang.Object obj, double d) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType) { throw new RuntimeException("Stub!"); }
+
+public native java.lang.annotation.Annotation[] getDeclaredAnnotations();
+}
+
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/reflect/GenericArrayType.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/reflect/GenericArrayType.annotated.java
index 011089d..c173408 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/GenericArrayType.annotated.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2004, 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
@@ -23,22 +23,13 @@
* questions.
*/
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang.reflect;
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
- return JVM_InternString(env, this);
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface GenericArrayType extends java.lang.reflect.Type {
+
+@libcore.util.NonNull public java.lang.reflect.Type getGenericComponentType();
}
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
-void register_java_lang_String(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/reflect/GenericDeclaration.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/reflect/GenericDeclaration.annotated.java
index 011089d..3614d84 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/GenericDeclaration.annotated.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, 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
@@ -23,22 +23,13 @@
* questions.
*/
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang.reflect;
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
- return JVM_InternString(env, this);
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface GenericDeclaration extends java.lang.reflect.AnnotatedElement {
+
+@libcore.util.NonNull public java.lang.reflect.TypeVariable<?>[] getTypeParameters();
}
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
-void register_java_lang_String(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/reflect/Member.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/reflect/Member.annotated.java
index 011089d..0552ce2 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Member.annotated.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, 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
@@ -23,22 +23,23 @@
* questions.
*/
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang.reflect;
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
- return JVM_InternString(env, this);
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Member {
+
+@libcore.util.NonNull public java.lang.Class<?> getDeclaringClass();
+
+@libcore.util.NonNull public java.lang.String getName();
+
+public int getModifiers();
+
+public boolean isSynthetic();
+
+public static final int DECLARED = 1; // 0x1
+
+public static final int PUBLIC = 0; // 0x0
}
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
-void register_java_lang_String(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Method.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Method.annotated.java
new file mode 100644
index 0000000..1c37b2e
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Method.annotated.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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 java.lang.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Method extends java.lang.reflect.Executable {
+
+Method() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Class<?> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.TypeVariable<java.lang.reflect.Method>[] getTypeParameters() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Class<?> getReturnType() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Type getGenericReturnType() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Class<?>[] getParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public int getParameterCount() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Type[] getGenericParameterTypes() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public native java.lang.Class<?>[] getExceptionTypes();
+
+@libcore.util.NonNull public java.lang.reflect.Type[] getGenericExceptionTypes() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Object invoke(java.lang.Object obj, java.lang.Object... args) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
+
+public boolean isBridge() { throw new RuntimeException("Stub!"); }
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public boolean isDefault() { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Object getDefaultValue();
+
+public <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.annotation.Annotation[][] getParameterAnnotations() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Parameter.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Parameter.annotated.java
new file mode 100644
index 0000000..5d7ddb6
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Parameter.annotated.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 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
+ * 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 java.lang.reflect;
+
+import java.lang.annotation.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Parameter implements java.lang.reflect.AnnotatedElement {
+
+Parameter(java.lang.String name, int modifiers, java.lang.reflect.Executable executable, int index) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean isNamePresent() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Executable getDeclaringExecutable() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Type getParameterizedType() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Class<?> getType() { throw new RuntimeException("Stub!"); }
+
+public boolean isImplicit() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getAnnotations() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/reflect/ParameterizedType.annotated.java
similarity index 65%
rename from ojluni/src/main/native/String.c
rename to ojluni/annotations/sdk/nullability/java/lang/reflect/ParameterizedType.annotated.java
index 011089d..6d72f3f 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/ParameterizedType.annotated.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2004, 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
@@ -23,22 +23,16 @@
* questions.
*/
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang.reflect;
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
- return JVM_InternString(env, this);
-}
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface ParameterizedType extends java.lang.reflect.Type {
-void register_java_lang_String(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getActualTypeArguments();
+
+@libcore.util.NonNull public java.lang.reflect.Type getRawType();
+
+public java.lang.reflect.Type getOwnerType();
}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Proxy.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Proxy.annotated.java
new file mode 100644
index 0000000..781308d
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Proxy.annotated.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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 java.lang.reflect;
+
+import java.security.Permission;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Proxy implements java.io.Serializable {
+
+protected Proxy(java.lang.reflect.InvocationHandler h) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Class<?> getProxyClass(java.lang.ClassLoader loader, java.lang.Class<?>... interfaces) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Object newProxyInstance(java.lang.ClassLoader loader, java.lang.Class<?>[] interfaces, java.lang.reflect.InvocationHandler h) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static boolean isProxyClass(java.lang.Class<?> cl) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.reflect.InvocationHandler getInvocationHandler(java.lang.Object proxy) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+protected java.lang.reflect.InvocationHandler h;
+}
+
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/reflect/Type.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/reflect/Type.annotated.java
index 011089d..f2b646b 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Type.annotated.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, 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
@@ -23,22 +23,13 @@
* questions.
*/
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang.reflect;
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
- return JVM_InternString(env, this);
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Type {
+
+@libcore.util.NonNull public default java.lang.String getTypeName() { throw new RuntimeException("Stub!"); }
}
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
-void register_java_lang_String(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/reflect/TypeVariable.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/reflect/TypeVariable.annotated.java
index 011089d..5654963 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/TypeVariable.annotated.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, 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
@@ -23,22 +23,16 @@
* questions.
*/
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang.reflect;
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
- return JVM_InternString(env, this);
-}
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface TypeVariable<D extends java.lang.reflect.GenericDeclaration> extends java.lang.reflect.Type {
-void register_java_lang_String(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getBounds();
+
+@libcore.util.NonNull public D getGenericDeclaration();
+
+@libcore.util.NonNull public java.lang.String getName();
}
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/reflect/WildcardType.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/reflect/WildcardType.annotated.java
index 011089d..c8b90a0 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/WildcardType.annotated.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2004, 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
@@ -23,22 +23,14 @@
* questions.
*/
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang.reflect;
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
- return JVM_InternString(env, this);
-}
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface WildcardType extends java.lang.reflect.Type {
-void register_java_lang_String(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getUpperBounds();
+
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getLowerBounds();
}
diff --git a/ojluni/annotations/sdk/nullability/java/util/ArrayList.annotated.java b/ojluni/annotations/sdk/nullability/java/util/ArrayList.annotated.java
new file mode 100644
index 0000000..255c4be
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/ArrayList.annotated.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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 java.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ArrayList<E> extends java.util.AbstractList<E> implements java.util.List<E>, java.util.RandomAccess, java.lang.Cloneable, java.io.Serializable {
+
+public ArrayList(int initialCapacity) { throw new RuntimeException("Stub!"); }
+
+public ArrayList() { throw new RuntimeException("Stub!"); }
+
+public ArrayList(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+public void trimToSize() { throw new RuntimeException("Stub!"); }
+
+public void ensureCapacity(int minCapacity) { throw new RuntimeException("Stub!"); }
+
+public int size() { throw new RuntimeException("Stub!"); }
+
+public boolean isEmpty() { throw new RuntimeException("Stub!"); }
+
+public boolean contains(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Object clone() { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.Nullable Object @libcore.util.NonNull [] toArray() { throw new RuntimeException("Stub!"); }
+
+// TODO: Make param and return types @Nullable T @NonNull [] once metalava supports TYPE_USE.
+public <T> T @libcore.util.NonNull [] toArray(T @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E get(int index) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E set(int index, @libcore.util.NullFromTypeParam E element) { throw new RuntimeException("Stub!"); }
+
+public boolean add(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+public void add(int index, @libcore.util.NullFromTypeParam E element) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E remove(int index) { throw new RuntimeException("Stub!"); }
+
+public boolean remove(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public void clear() { throw new RuntimeException("Stub!"); }
+
+public boolean addAll(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+public boolean addAll(int index, @libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+protected void removeRange(int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public boolean removeAll(@libcore.util.NonNull java.util.Collection<?> c) { throw new RuntimeException("Stub!"); }
+
+public boolean retainAll(@libcore.util.NonNull java.util.Collection<?> c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.ListIterator<@libcore.util.NullFromTypeParam E> listIterator(int index) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.ListIterator<@libcore.util.NullFromTypeParam E> listIterator() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Iterator<@libcore.util.NullFromTypeParam E> iterator() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.List<@libcore.util.NullFromTypeParam E> subList(int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public void forEach(@libcore.util.NonNull java.util.function.Consumer<? super @libcore.util.NullFromTypeParam E> action) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Spliterator<@libcore.util.NullFromTypeParam E> spliterator() { throw new RuntimeException("Stub!"); }
+
+public boolean removeIf(@libcore.util.NonNull java.util.function.Predicate<? super @libcore.util.NullFromTypeParam E> filter) { throw new RuntimeException("Stub!"); }
+
+public void replaceAll(@libcore.util.NonNull java.util.function.UnaryOperator<@libcore.util.NullFromTypeParam E> operator) { throw new RuntimeException("Stub!"); }
+
+public void sort(@libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/HashMap.annotated.java b/ojluni/annotations/sdk/nullability/java/util/HashMap.annotated.java
new file mode 100644
index 0000000..567354a
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/HashMap.annotated.java
@@ -0,0 +1,88 @@
+/*
+ * 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
+ * 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 java.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class HashMap<K, V> extends java.util.AbstractMap<K,V> implements java.util.Map<K,V>, java.lang.Cloneable, java.io.Serializable {
+
+public HashMap(int initialCapacity, float loadFactor) { throw new RuntimeException("Stub!"); }
+
+public HashMap(int initialCapacity) { throw new RuntimeException("Stub!"); }
+
+public HashMap() { throw new RuntimeException("Stub!"); }
+
+public HashMap(@libcore.util.NonNull java.util.Map<? extends @libcore.util.NullFromTypeParam K, ? extends @libcore.util.NullFromTypeParam V> m) { throw new RuntimeException("Stub!"); }
+
+public int size() { throw new RuntimeException("Stub!"); }
+
+public boolean isEmpty() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V get(@libcore.util.Nullable java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+public boolean containsKey(@libcore.util.Nullable java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V put(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+public void putAll(@libcore.util.NonNull java.util.Map<? extends @libcore.util.NullFromTypeParam K,? extends @libcore.util.NullFromTypeParam V> m) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V remove(@libcore.util.Nullable java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+public void clear() { throw new RuntimeException("Stub!"); }
+
+public boolean containsValue(@libcore.util.Nullable java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Set<@libcore.util.NullFromTypeParam K> keySet() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Collection<@libcore.util.NullFromTypeParam V> values() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Set<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V>> entrySet() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V getOrDefault(@libcore.util.Nullable java.lang.Object key, @libcore.util.Nullable V defaultValue) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V putIfAbsent(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+public boolean remove(@libcore.util.Nullable java.lang.Object key, @libcore.util.Nullable java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+public boolean replace(@libcore.util.NullFromTypeParam K key, @libcore.util.Nullable V oldValue, @libcore.util.NullFromTypeParam V newValue) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V replace(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V computeIfAbsent(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull java.util.function.Function<? super @libcore.util.NullFromTypeParam K,? extends @libcore.util.Nullable V> mappingFunction) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V computeIfPresent(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.NonNull V,? extends Nu V> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V compute(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.Nullable V,? extends @libcore.util.Nullable V> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V merge(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull V value, @libcore.util.NonNull java.util.function.BiFunction<? super Nn V,? super @libcore.util.NonNull V,? extends @libcore.util.Nullable V> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+public void forEach(@libcore.util.NonNull java.util.function.BiConsumer<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.NullFromTypeParam V> action) { throw new RuntimeException("Stub!"); }
+
+public void replaceAll(@libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.NullFromTypeParam V,? extends @libcore.util.NullFromTypeParam V> function) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Object clone() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/util/Iterator.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/util/Iterator.annotated.java
index 011089d..b4f4522 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/util/Iterator.annotated.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, 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
@@ -23,22 +23,14 @@
* questions.
*/
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
+package java.util;
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+import java.util.function.Consumer;
+public interface Iterator<E> {
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
- return JVM_InternString(env, this);
-}
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
-
-void register_java_lang_String(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
+ public boolean hasNext();
+ public @libcore.util.NullFromTypeParam E next();
+ public default void remove() { throw new RuntimeException("Stub!"); }
+ public default void forEachRemaining(@libcore.util.NonNull Consumer<? super @libcore.util.NullFromTypeParam E> action) { throw new RuntimeException("Stub!"); }
}
diff --git a/ojluni/annotations/sdk/nullability/java/util/List.annotated.java b/ojluni/annotations/sdk/nullability/java/util/List.annotated.java
new file mode 100644
index 0000000..958b335
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/List.annotated.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1997, 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. 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 java.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface List<E> extends java.util.Collection<E> {
+
+public int size();
+
+public boolean isEmpty();
+
+public boolean contains(@libcore.util.Nullable java.lang.Object o);
+
+@libcore.util.NonNull public java.util.Iterator<@libcore.util.NullFromTypeParam E> iterator();
+
+public java.lang.@libcore.util.Nullable Object @libcore.util.NonNull [] toArray();
+
+// TODO: Make param and return types @Nullable T @NonNull [] once metalava supports TYPE_USE.
+public <T> T @libcore.util.NonNull [] toArray(T @libcore.util.NonNull [] a);
+
+public boolean add(@libcore.util.NullFromTypeParam E e);
+
+public boolean remove(@libcore.util.Nullable java.lang.Object o);
+
+public boolean containsAll(@libcore.util.NonNull java.util.Collection<?> c);
+
+public boolean addAll(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c);
+
+public boolean addAll(int index, @libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c);
+
+public boolean removeAll(@libcore.util.NonNull java.util.Collection<?> c);
+
+public boolean retainAll(@libcore.util.NonNull java.util.Collection<?> c);
+
+public default void replaceAll(@libcore.util.NonNull java.util.function.UnaryOperator<@libcore.util.NullFromTypeParam E> operator) { throw new RuntimeException("Stub!"); }
+
+public default void sort(@libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+public void clear();
+
+public boolean equals(@libcore.util.Nullable java.lang.Object o);
+
+public int hashCode();
+
+@libcore.util.NullFromTypeParam public E get(int index);
+
+@libcore.util.NullFromTypeParam public E set(int index, @libcore.util.NullFromTypeParam E element);
+
+public void add(int index, @libcore.util.NullFromTypeParam E element);
+
+@libcore.util.NullFromTypeParam public E remove(int index);
+
+public int indexOf(@libcore.util.Nullable java.lang.Object o);
+
+public int lastIndexOf(@libcore.util.Nullable java.lang.Object o);
+
+@libcore.util.NonNull public java.util.ListIterator<@libcore.util.NullFromTypeParam E> listIterator();
+
+@libcore.util.NonNull public java.util.ListIterator<@libcore.util.NullFromTypeParam E> listIterator(int index);
+
+@libcore.util.NonNull public java.util.List<@libcore.util.NullFromTypeParam E> subList(int fromIndex, int toIndex);
+
+@libcore.util.NonNull public default java.util.Spliterator<@libcore.util.NullFromTypeParam E> spliterator() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/Map.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Map.annotated.java
new file mode 100644
index 0000000..2c89e2b3
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/Map.annotated.java
@@ -0,0 +1,105 @@
+/*
+ * 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
+ * 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 java.util;
+
+import java.util.function.Function;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Map<K, V> {
+
+public int size();
+
+public boolean isEmpty();
+
+public boolean containsKey(@libcore.util.Nullable java.lang.Object key);
+
+public boolean containsValue(@libcore.util.Nullable java.lang.Object value);
+
+@libcore.util.Nullable public V get(@libcore.util.Nullable java.lang.Object key);
+
+@libcore.util.Nullable public V put(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value);
+
+@libcore.util.Nullable public V remove(@libcore.util.Nullable java.lang.Object key);
+
+public void putAll(@libcore.util.NonNull java.util.Map<? extends @libcore.util.NullFromTypeParam K,? extends @libcore.util.NullFromTypeParam V> m);
+
+public void clear();
+
+@libcore.util.NonNull public java.util.Set<@libcore.util.NullFromTypeParam K> keySet();
+
+@libcore.util.NonNull public java.util.Collection<@libcore.util.NullFromTypeParam V> values();
+
+@libcore.util.NonNull public java.util.Set<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V>> entrySet();
+
+public boolean equals(@libcore.util.Nullable java.lang.Object o);
+
+public int hashCode();
+
+@libcore.util.Nullable public default V getOrDefault(@libcore.util.Nullable java.lang.Object key, @libcore.util.Nullable V defaultValue) { throw new RuntimeException("Stub!"); }
+
+public default void forEach(@libcore.util.NonNull java.util.function.BiConsumer<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.NullFromTypeParam V> action) { throw new RuntimeException("Stub!"); }
+
+public default void replaceAll(@libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.NullFromTypeParam V,? extends @libcore.util.NullFromTypeParam V> function) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public default V putIfAbsent(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+public default boolean remove(@libcore.util.Nullable java.lang.Object key, @libcore.util.Nullable java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+public default boolean replace(@libcore.util.NullFromTypeParam K key, @libcore.util.Nullable V oldValue, @libcore.util.NullFromTypeParam V newValue) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public default V replace(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public default V computeIfAbsent(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull java.util.function.Function<? super @libcore.util.NullFromTypeParam K,? extends @libcore.util.Nullable V> mappingFunction) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public default V computeIfPresent(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.NonNull V,? extends @libcore.util.Nullable V> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public default V compute(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.Nullable V,? extends @libcore.util.Nullable V> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public default V merge(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull V value, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NonNull V,? super @libcore.util.NonNull V,? extends @libcore.util.Nullable V> remappingFunction) { throw new RuntimeException("Stub!"); }
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static interface Entry<K, V> {
+
+@libcore.util.NullFromTypeParam public K getKey();
+
+@libcore.util.NullFromTypeParam public V getValue();
+
+@libcore.util.NullFromTypeParam public V setValue(@libcore.util.NullFromTypeParam V value);
+
+public boolean equals(@libcore.util.Nullable java.lang.Object o);
+
+public int hashCode();
+
+public static <K extends java.lang.Comparable<? super K>, V> @libcore.util.NonNull java.util.Comparator<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NonNull K, @libcore.util.Nullable V>> comparingByKey() { throw new RuntimeException("Stub!"); }
+
+public static <K, V extends java.lang.Comparable<? super V>> @libcore.util.NonNull java.util.Comparator<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.Nullable K, @libcore.util.NonNull V>> comparingByValue() { throw new RuntimeException("Stub!"); }
+
+public static <K, V> @libcore.util.NonNull java.util.Comparator<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NullFromTypeParam K, @libcore.util.Nullable V>> comparingByKey(@libcore.util.NonNull java.util.Comparator<? super @libcore.util.NullFromTypeParam K> cmp) { throw new RuntimeException("Stub!"); }
+
+public static <K, V> @libcore.util.NonNull java.util.Comparator<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.Nullable K, @libcore.util.NullFromTypeParam V>> comparingByValue(@libcore.util.NonNull java.util.Comparator<? super @libcore.util.NullFromTypeParam V> cmp) { throw new RuntimeException("Stub!"); }
+}
+
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/Set.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Set.annotated.java
new file mode 100644
index 0000000..1257b5c
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/Set.annotated.java
@@ -0,0 +1,65 @@
+/*
+ * 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
+ * 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 java.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Set<E> extends java.util.Collection<E> {
+
+public int size();
+
+public boolean isEmpty();
+
+public boolean contains(@libcore.util.Nullable java.lang.Object o);
+
+@libcore.util.NonNull public java.util.Iterator<@libcore.util.NullFromTypeParam E> iterator();
+
+public java.lang.@libcore.util.Nullable Object @libcore.util.NonNull [] toArray();
+
+// TODO: Make param and return types @Nullable T @NonNull [] once metalava supports TYPE_USE.
+public <T> T @libcore.util.NonNull [] toArray(T @libcore.util.NonNull [] a);
+
+public boolean add(@libcore.util.NullFromTypeParam E e);
+
+public boolean remove(@libcore.util.Nullable java.lang.Object o);
+
+public boolean containsAll(@libcore.util.NonNull java.util.Collection<?> c);
+
+public boolean addAll(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c);
+
+public boolean retainAll(@libcore.util.NonNull java.util.Collection<?> c);
+
+public boolean removeAll(@libcore.util.NonNull java.util.Collection<?> c);
+
+public void clear();
+
+public boolean equals(@libcore.util.Nullable java.lang.Object o);
+
+public int hashCode();
+
+@libcore.util.NonNull public default java.util.Spliterator<@libcore.util.NullFromTypeParam E> spliterator() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/src/main/java/java/awt/font/TextAttribute.java b/ojluni/src/main/java/java/awt/font/TextAttribute.java
index 7dff4ad..af0dca3 100644
--- a/ojluni/src/main/java/java/awt/font/TextAttribute.java
+++ b/ojluni/src/main/java/java/awt/font/TextAttribute.java
@@ -491,6 +491,8 @@
public static final TextAttribute FONT =
new TextAttribute("font");
+ // Android-changed: Removed @see tag (target does not exist on Android):
+ // @see GraphicAttribute
/**
* Attribute key for a user-defined glyph to display in lieu
* of the font's standard glyph for a character. Values are
@@ -509,8 +511,6 @@
*
* <p>The GraphicAttribute determines the logical and visual
* bounds of the text; the actual Font values are ignored.
- *
- * @see GraphicAttribute
*/
public static final TextAttribute CHAR_REPLACEMENT =
new TextAttribute("char_replacement");
@@ -519,6 +519,8 @@
// Adornments added to text.
//
+ // Android-changed: Removed @see tag (target does not exist on Android):
+ // @see java.awt.Paint
/**
* Attribute key for the paint used to render the text. Values are
* instances of <b><code>Paint</code></b>. The default value is
@@ -529,12 +531,13 @@
* <code>Paint</code> regardless of the <code>Paint</code> value
* set on the <code>Graphics</code> (but see {@link #SWAP_COLORS}).
*
- * @see java.awt.Paint
* @see #SWAP_COLORS
*/
public static final TextAttribute FOREGROUND =
new TextAttribute("foreground");
+ // Android-changed: Removed @see tag (target does not exist on Android):
+ // @see java.awt.Paint
/**
* Attribute key for the paint used to render the background of
* the text. Values are instances of <b><code>Paint</code></b>.
@@ -548,7 +551,6 @@
* <p>The visual bounds of the text is extended to include the
* logical bounds, if necessary. The outline is not affected.
*
- * @see java.awt.Paint
* @see #SWAP_COLORS
*/
public static final TextAttribute BACKGROUND =
@@ -661,6 +663,8 @@
public static final TextAttribute BIDI_EMBEDDING =
new TextAttribute("bidi_embedding");
+ // Android-changed: Removed @see tag (target does not exist on Android):
+ // @see TextLayout#getJustifiedLayout
/**
* Attribute key for the justification of a paragraph. Values are
* instances of <b><code>Number</code></b>. The default value is
@@ -679,8 +683,6 @@
*
* <p><em>Note:</em> This should have the same value for all the
* text in a paragraph, otherwise the behavior is undetermined.
- *
- * @see TextLayout#getJustifiedLayout
*/
public static final TextAttribute JUSTIFICATION =
new TextAttribute("justification");
diff --git a/ojluni/src/main/java/java/beans/PropertyChangeSupport.java b/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
index d55ae76..b99f481 100644
--- a/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
+++ b/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
@@ -32,6 +32,8 @@
import java.util.Hashtable;
import java.util.Map.Entry;
+// Android-changed: Removed @see tag (target does not exist on Android):
+// @see VetoableChangeSupport
/**
* This is a utility class that can be used by beans that support bound
* properties. It manages a list of listeners and dispatches
@@ -75,8 +77,6 @@
* This class is serializable. When it is serialized it will save
* (and restore) any listeners that are themselves serializable. Any
* non-serializable listeners will be skipped during serialization.
- *
- * @see VetoableChangeSupport
*/
public class PropertyChangeSupport implements Serializable {
private PropertyChangeListenerMap map = new PropertyChangeListenerMap();
diff --git a/ojluni/src/main/java/java/io/FileDescriptor.java b/ojluni/src/main/java/java/io/FileDescriptor.java
index f0017ee..a2c833d 100644
--- a/ojluni/src/main/java/java/io/FileDescriptor.java
+++ b/ojluni/src/main/java/java/io/FileDescriptor.java
@@ -54,6 +54,15 @@
// fetching the descriptor value.
private int descriptor;
+ // Android-added: Track fd owner to guard against accidental closure. http://b/110100358
+ // The owner on the libc side is an pointer-sized value that can be set to an arbitrary
+ // value (with 0 meaning 'unowned'). libcore chooses to use System.identityHashCode.
+ private long ownerId = NO_OWNER;
+
+ // Android-added: value of ownerId indicating that a FileDescriptor is unowned.
+ /** @hide */
+ public static final long NO_OWNER = 0L;
+
/**
* Constructs an (invalid) FileDescriptor
* object.
@@ -140,26 +149,63 @@
/* This routine initializes JNI field offsets for the class */
//private static native void initIDs();
+ // Android-added: Needed for framework to access descriptor value
/**
* Returns the int descriptor. It's highly unlikely you should be calling this. Please discuss
* your needs with a libcore maintainer before using this method.
* @hide internal use only
*/
- // Android-added: Needed for framework to access descriptor value
public final int getInt$() {
return descriptor;
}
+ // Android-added: Needed for framework to access descriptor value
/**
* Sets the int descriptor. It's highly unlikely you should be calling this. Please discuss
* your needs with a libcore maintainer before using this method.
* @hide internal use only
*/
- // Android-added: Needed for framework to access descriptor value
public final void setInt$(int fd) {
this.descriptor = fd;
}
+ // BEGIN Android-added: Methods to enable ownership enforcement of Unix file descriptors.
+ /**
+ * Returns the owner ID of this FileDescriptor. It's highly unlikely you should be calling this.
+ * Please discuss your needs with a libcore maintainer before using this method.
+ * @hide internal use only
+ */
+ public long getOwnerId$() {
+ return this.ownerId;
+ }
+
+ /**
+ * Sets the owner ID of this FileDescriptor. The owner ID does not need to be unique, but it is
+ * assumed that clashes are rare. See bionic/include/android/fdsan.h for more details.
+ *
+ * It's highly unlikely you should be calling this.
+ * Please discuss your needs with a libcore maintainer before using this method.
+ * @param owner the owner ID of the Object that is responsible for closing this FileDescriptor
+ * @hide internal use only
+ */
+ public void setOwnerId$(long newOwnerId) {
+ this.ownerId = newOwnerId;
+ }
+
+ /**
+ * Returns a copy of this FileDescriptor, and sets this to an invalid state.
+ * @hide internal use only
+ */
+ public FileDescriptor release$() {
+ FileDescriptor result = new FileDescriptor();
+ result.descriptor = this.descriptor;
+ result.ownerId = this.ownerId;
+ this.descriptor = -1;
+ this.ownerId = FileDescriptor.NO_OWNER;
+ return result;
+ }
+ // END Android-added: Methods to enable ownership enforcement of Unix file descriptors.
+
/**
* @hide internal use only
*/
diff --git a/ojluni/src/main/java/java/io/FileInputStream.java b/ojluni/src/main/java/java/io/FileInputStream.java
index db7ba65..03a67dc 100755
--- a/ojluni/src/main/java/java/io/FileInputStream.java
+++ b/ojluni/src/main/java/java/io/FileInputStream.java
@@ -26,6 +26,8 @@
package java.io;
+import static android.system.OsConstants.O_RDONLY;
+
import java.nio.channels.FileChannel;
import dalvik.annotation.optimization.ReachabilitySensitive;
@@ -34,6 +36,7 @@
import sun.nio.ch.FileChannelImpl;
import libcore.io.IoBridge;
import libcore.io.IoTracker;
+import libcore.io.IoUtils;
/**
@@ -151,7 +154,9 @@
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
- fd = new FileDescriptor();
+ // Android-changed: Open files through common bridge code.
+ // fd = new FileDescriptor();
+ fd = IoBridge.open(name, O_RDONLY);
// Android-changed: Tracking mechanism for FileDescriptor sharing.
// fd.attach(this);
@@ -159,10 +164,11 @@
path = name;
- // Android-added: BlockGuard support.
- BlockGuard.getThreadPolicy().onReadFromDisk();
+ // Android-removed: Open files through common bridge code.
+ // open(name);
- open(name);
+ // Android-added: File descriptor ownership tracking.
+ IoUtils.setFdOwner(this.fd, this);
// Android-added: CloseGuard support.
guard.open("close");
diff --git a/ojluni/src/main/java/java/io/FileOutputStream.java b/ojluni/src/main/java/java/io/FileOutputStream.java
index f29a741..95ad1be 100755
--- a/ojluni/src/main/java/java/io/FileOutputStream.java
+++ b/ojluni/src/main/java/java/io/FileOutputStream.java
@@ -26,6 +26,11 @@
package java.io;
+import static android.system.OsConstants.O_APPEND;
+import static android.system.OsConstants.O_CREAT;
+import static android.system.OsConstants.O_TRUNC;
+import static android.system.OsConstants.O_WRONLY;
+
import java.nio.channels.FileChannel;
import dalvik.annotation.optimization.ReachabilitySensitive;
@@ -34,6 +39,7 @@
import sun.nio.ch.FileChannelImpl;
import libcore.io.IoBridge;
import libcore.io.IoTracker;
+import libcore.io.IoUtils;
/**
* A file output stream is an output stream for writing data to a
@@ -223,7 +229,11 @@
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
- this.fd = new FileDescriptor();
+ // BEGIN Android-changed: Open files through common bridge code.
+ // this.fd = new FileDescriptor();
+ int flags = O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC);
+ this.fd = IoBridge.open(name, flags);
+ // END Android-changed: Open files through common bridge code.
// Android-changed: Tracking mechanism for FileDescriptor sharing.
// fd.attach(this);
@@ -232,10 +242,11 @@
this.append = append;
this.path = name;
- // Android-added: BlockGuard support.
- BlockGuard.getThreadPolicy().onWriteToDisk();
+ // Android-removed: Open files through common bridge code.
+ // open(name, append);
- open(name, append);
+ // Android-added: File descriptor ownership tracking.
+ IoUtils.setFdOwner(this.fd, this);
// Android-added: CloseGuard support.
guard.open("close");
diff --git a/ojluni/src/main/java/java/io/FilenameFilter.java b/ojluni/src/main/java/java/io/FilenameFilter.java
index 71b88af..25d866b 100644
--- a/ojluni/src/main/java/java/io/FilenameFilter.java
+++ b/ojluni/src/main/java/java/io/FilenameFilter.java
@@ -25,6 +25,8 @@
package java.io;
+// Android-changed: Removed @see tag (target does not exist on Android):
+// @see java.awt.FileDialog#setFilenameFilter(java.io.FilenameFilter)
/**
* Instances of classes that implement this interface are used to
* filter filenames. These instances are used to filter directory
@@ -34,7 +36,6 @@
*
* @author Arthur van Hoff
* @author Jonathan Payne
- * @see java.awt.FileDialog#setFilenameFilter(java.io.FilenameFilter)
* @see java.io.File
* @see java.io.File#list(java.io.FilenameFilter)
* @since JDK1.0
diff --git a/ojluni/src/main/java/java/io/ObjectInputStream.java b/ojluni/src/main/java/java/io/ObjectInputStream.java
index f722df0..e06306d 100644
--- a/ojluni/src/main/java/java/io/ObjectInputStream.java
+++ b/ojluni/src/main/java/java/io/ObjectInputStream.java
@@ -239,12 +239,54 @@
new ReferenceQueue<>();
}
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ /*
+ static {
+ /* Setup access so sun.misc can invoke package private functions. *
+ sun.misc.SharedSecrets.setJavaOISAccess(new JavaOISAccess() {
+ public void setObjectInputFilter(ObjectInputStream stream, ObjectInputFilter filter) {
+ stream.setInternalObjectInputFilter(filter);
+ }
+
+ public ObjectInputFilter getObjectInputFilter(ObjectInputStream stream) {
+ return stream.getInternalObjectInputFilter();
+ }
+ });
+ }
+
+ /*
+ * Separate class to defer initialization of logging until needed.
+ *
+ private static class Logging {
+
+ /*
+ * Logger for ObjectInputFilter results.
+ * Setup the filter logger if it is set to INFO or WARNING.
+ * (Assuming it will not change).
+ *
+ private static final PlatformLogger traceLogger;
+ private static final PlatformLogger infoLogger;
+ static {
+ PlatformLogger filterLog = PlatformLogger.getLogger("java.io.serialization");
+ infoLogger = (filterLog != null &&
+ filterLog.isLoggable(PlatformLogger.Level.INFO)) ? filterLog : null;
+ traceLogger = (filterLog != null &&
+ filterLog.isLoggable(PlatformLogger.Level.FINER)) ? filterLog : null;
+ }
+ }
+ */
+
/** filter stream for handling block data conversion */
private final BlockDataInputStream bin;
/** validation callback list */
private final ValidationList vlist;
/** recursion depth */
+ // Android-changed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ // private long depth;
private int depth;
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ // /** Total number of references to any type of object, class, enum, proxy, etc. */
+ // private long totalObjectRefs;
/** whether stream is closed */
private boolean closed;
@@ -270,6 +312,14 @@
*/
private SerialCallbackContext curContext;
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ /**
+ * Filter of class descriptors and classes read from the stream;
+ * may be null.
+ *
+ private ObjectInputFilter serialFilter;
+ */
+
/**
* Creates an ObjectInputStream that reads from the specified InputStream.
* A serialization stream header is read from the stream and verified.
@@ -297,6 +347,8 @@
bin = new BlockDataInputStream(in);
handles = new HandleTable(10);
vlist = new ValidationList();
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ // serialFilter = ObjectInputFilter.Config.getSerialFilter();
enableOverride = false;
readStreamHeader();
bin.setBlockDataMode(true);
@@ -327,6 +379,8 @@
bin = null;
handles = null;
vlist = null;
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ // serialFilter = ObjectInputFilter.Config.getSerialFilter();
enableOverride = true;
}
@@ -334,7 +388,7 @@
* Read an object from the ObjectInputStream. The class of the object, the
* signature of the class, and the values of the non-transient and
* non-static fields of the class and all of its supertypes are read.
- * Default deserializing for a class can be overriden using the writeObject
+ * Default deserializing for a class can be overridden using the writeObject
* and readObject methods. Objects referenced by this object are read
* transitively so that a complete equivalent graph of objects is
* reconstructed by readObject.
@@ -1075,6 +1129,9 @@
return bin.readUTF();
}
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ // Removed ObjectInputFilter related methods.
+
/**
* Provide access to the persistent fields read from the input stream.
*/
@@ -1324,6 +1381,8 @@
}
depth++;
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ // totalObjectRefs++;
try {
switch (tc) {
case TC_NULL:
@@ -1400,6 +1459,18 @@
}
Object rep = resolveObject(obj);
if (rep != obj) {
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ /*
+ // The type of the original object has been filtered but resolveObject
+ // may have replaced it; filter the replacement's type
+ if (rep != null) {
+ if (rep.getClass().isArray()) {
+ filterCheck(rep.getClass(), Array.getLength(rep));
+ } else {
+ filterCheck(rep.getClass(), -1);
+ }
+ }
+ */
handles.setObject(passHandle, rep);
}
return rep;
@@ -1470,6 +1541,8 @@
throw new InvalidObjectException(
"cannot read back reference to unshared object");
}
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ // filterCheck(null, -1); // just a check for number of references, depth, no class
return obj;
}
@@ -1506,23 +1579,29 @@
throws IOException
{
byte tc = bin.peekByte();
+ ObjectStreamClass descriptor;
switch (tc) {
case TC_NULL:
- return (ObjectStreamClass) readNull();
-
+ descriptor = (ObjectStreamClass) readNull();
+ break;
case TC_REFERENCE:
- return (ObjectStreamClass) readHandle(unshared);
-
+ descriptor = (ObjectStreamClass) readHandle(unshared);
+ break;
case TC_PROXYCLASSDESC:
- return readProxyDesc(unshared);
-
+ descriptor = readProxyDesc(unshared);
+ break;
case TC_CLASSDESC:
- return readNonProxyDesc(unshared);
-
+ descriptor = readNonProxyDesc(unshared);
+ break;
default:
throw new StreamCorruptedException(
String.format("invalid type code: %02X", tc));
}
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ // if (descriptor != null) {
+ // validateDescriptor(descriptor);
+ // }
+ return descriptor;
}
private boolean isCustomSubclass() {
@@ -1569,6 +1648,11 @@
ReflectUtil.checkProxyPackageAccess(
getClass().getClassLoader(),
cl.getInterfaces());
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ // // Filter the interfaces
+ // for (Class<?> clazz : cl.getInterfaces()) {
+ // filterCheck(clazz, -1);
+ // }
}
} catch (ClassNotFoundException ex) {
resolveEx = ex;
@@ -1577,6 +1661,10 @@
desc.initProxy(cl, resolveEx, readClassDesc(false));
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ // // Call filterCheck on the definition
+ // filterCheck(desc.forClass(), -1);
+
handles.finish(descHandle);
passHandle = descHandle;
return desc;
@@ -1624,8 +1712,13 @@
desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));
+ // Android-removed: ObjectInputFilter unsupported - removed filterCheck() call.
+ // // Call filterCheck on the definition
+ // filterCheck(desc.forClass(), -1);
+
handles.finish(descHandle);
passHandle = descHandle;
+
return desc;
}
@@ -1666,6 +1759,9 @@
ObjectStreamClass desc = readClassDesc(false);
int len = bin.readInt();
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ // filterCheck(desc.forClass(), len);
+
Object array = null;
Class<?> cl, ccl = null;
if ((cl = desc.forClass()) != null) {
@@ -1814,6 +1910,17 @@
rep = cloneArray(rep);
}
if (rep != obj) {
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ /*
+ // Filter the replacement object
+ if (rep != null) {
+ if (rep.getClass().isArray()) {
+ filterCheck(rep.getClass(), Array.getLength(rep));
+ } else {
+ filterCheck(rep.getClass(), -1);
+ }
+ }
+ */
handles.setObject(passHandle, obj = rep);
}
}
@@ -1892,6 +1999,10 @@
if (obj == null || handles.lookupException(passHandle) != null) {
defaultReadFields(null, slotDesc); // skip field values
} else if (slotDesc.hasReadObjectMethod()) {
+ // BEGIN Android-changed: ThreadDeath cannot cause corruption on Android.
+ // Android does not support Thread.stop() or Thread.stop(Throwable) so this
+ // does not need to protect against state corruption that can occur when a
+ // ThreadDeath Error is thrown in the middle of the finally block.
SerialCallbackContext oldContext = curContext;
if (oldContext != null)
oldContext.check();
@@ -1914,6 +2025,7 @@
if (oldContext!= null)
oldContext.check();
curContext = oldContext;
+ // END Android-changed: ThreadDeath cannot cause corruption on Android.
}
/*
@@ -1924,7 +2036,7 @@
defaultDataEnd = false;
} else {
defaultReadFields(obj, slotDesc);
- }
+ }
if (slotDesc.hasWriteObjectData()) {
skipCustomData();
@@ -1940,7 +2052,7 @@
}
}
}
- }
+ }
/**
* Skips over all block data and objects until TC_ENDBLOCKDATA is
@@ -1988,7 +2100,7 @@
if (primVals == null || primVals.length < primDataSize) {
primVals = new byte[primDataSize];
}
- bin.readFully(primVals, 0, primDataSize, false);
+ bin.readFully(primVals, 0, primDataSize, false);
if (obj != null) {
desc.setPrimFieldValues(obj, primVals);
}
@@ -2287,6 +2399,9 @@
}
}
+ // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+ // Removed FilterValues class.
+
/**
* Input stream supporting single-byte peek operations.
*/
@@ -2296,6 +2411,8 @@
private final InputStream in;
/** peeked byte */
private int peekb = -1;
+ /** total bytes read from the stream */
+ private long totalBytesRead = 0;
/**
* Creates new PeekInputStream on top of given underlying stream.
@@ -2309,7 +2426,12 @@
* that it does not consume the read value.
*/
int peek() throws IOException {
- return (peekb >= 0) ? peekb : (peekb = in.read());
+ if (peekb >= 0) {
+ return peekb;
+ }
+ peekb = in.read();
+ totalBytesRead += peekb >= 0 ? 1 : 0;
+ return peekb;
}
public int read() throws IOException {
@@ -2318,21 +2440,27 @@
peekb = -1;
return v;
} else {
- return in.read();
+ int nbytes = in.read();
+ totalBytesRead += nbytes >= 0 ? 1 : 0;
+ return nbytes;
}
}
public int read(byte[] b, int off, int len) throws IOException {
+ int nbytes;
if (len == 0) {
return 0;
} else if (peekb < 0) {
- return in.read(b, off, len);
+ nbytes = in.read(b, off, len);
+ totalBytesRead += nbytes >= 0 ? nbytes : 0;
+ return nbytes;
} else {
b[off++] = (byte) peekb;
len--;
peekb = -1;
- int n = in.read(b, off, len);
- return (n >= 0) ? (n + 1) : 1;
+ nbytes = in.read(b, off, len);
+ totalBytesRead += nbytes >= 0 ? nbytes : 0;
+ return (nbytes >= 0) ? (nbytes + 1) : 1;
}
}
@@ -2357,7 +2485,9 @@
skipped++;
n--;
}
- return skipped + skip(n);
+ n = skipped + in.skip(n);
+ totalBytesRead += n;
+ return n;
}
public int available() throws IOException {
@@ -2367,6 +2497,10 @@
public void close() throws IOException {
in.close();
}
+
+ public long getBytesRead() {
+ return totalBytesRead;
+ }
}
/**
@@ -3222,6 +3356,14 @@
throw new UTFDataFormatException();
}
}
+
+ /**
+ * Returns the number of bytes read from the input stream.
+ * @return the number of bytes read from the input stream
+ */
+ long getBytesRead() {
+ return in.getBytesRead();
+ }
}
/**
@@ -3552,4 +3694,23 @@
}
}
+ // Android-removed: Logic related to ObjectStreamClassValidator, unused on Android
+ /*
+ private void validateDescriptor(ObjectStreamClass descriptor) {
+ ObjectStreamClassValidator validating = validator;
+ if (validating != null) {
+ validating.validateDescriptor(descriptor);
+ }
+ }
+
+ // controlled access to ObjectStreamClassValidator
+ private volatile ObjectStreamClassValidator validator;
+
+ private static void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator) {
+ ois.validator = validator;
+ }
+ static {
+ SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator);
+ }
+ */
}
diff --git a/ojluni/src/main/java/java/io/ObjectStreamClass.java b/ojluni/src/main/java/java/io/ObjectStreamClass.java
index b2651b8..4a183f8 100644
--- a/ojluni/src/main/java/java/io/ObjectStreamClass.java
+++ b/ojluni/src/main/java/java/io/ObjectStreamClass.java
@@ -53,7 +53,7 @@
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
import dalvik.system.VMRuntime;
-import dalvik.system.VMStack;
+
/**
* Serialization's descriptor for classes. It contains the name and
* serialVersionUID of the class. The ObjectStreamClass for a specific class
@@ -279,9 +279,8 @@
}
requireInitialized();
if (System.getSecurityManager() != null) {
- // Android-changed: Class loader obtained from VMStack
- if (ReflectUtil.needsPackageAccessCheck(VMStack.getCallingClassLoader(),
- cl.getClassLoader())) {
+ Class<?> caller = Reflection.getCallerClass();
+ if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), cl.getClassLoader())) {
ReflectUtil.checkPackageAccess(cl);
}
}
diff --git a/ojluni/src/main/java/java/io/ObjectStreamField.java b/ojluni/src/main/java/java/io/ObjectStreamField.java
index 957972e..d26535f 100644
--- a/ojluni/src/main/java/java/io/ObjectStreamField.java
+++ b/ojluni/src/main/java/java/io/ObjectStreamField.java
@@ -162,14 +162,16 @@
*/
@CallerSensitive
public Class<?> getType() {
- /* BEGIN Android-removed: Security manager is always null on Android.
+ // BEGIN Android-removed: Security manager is always null on Android.
+ /*
if (System.getSecurityManager() != null) {
- Class<?> caller = Reflection.getCallerClass();
+ Class<?> caller = Reflection.getCallerClass();
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), type.getClassLoader())) {
ReflectUtil.checkPackageAccess(type);
}
}
- END Android-removed: Security manager is always null on Android. */
+ */
+ // END Android-removed: Security manager is always null on Android.
return type;
}
diff --git a/ojluni/src/main/java/java/io/RandomAccessFile.java b/ojluni/src/main/java/java/io/RandomAccessFile.java
index a83829f..06683ad 100755
--- a/ojluni/src/main/java/java/io/RandomAccessFile.java
+++ b/ojluni/src/main/java/java/io/RandomAccessFile.java
@@ -34,6 +34,7 @@
import dalvik.system.CloseGuard;
import libcore.io.IoBridge;
import libcore.io.IoTracker;
+import libcore.io.IoUtils;
import libcore.io.Libcore;
import static android.system.OsConstants.*;
@@ -286,6 +287,7 @@
// BEGIN Android-changed: Use IoBridge.open() instead of open.
fd = IoBridge.open(name, imode);
+ IoUtils.setFdOwner(fd, this);
maybeSync();
guard.open("close");
// END Android-changed: Use IoBridge.open() instead of open.
diff --git a/ojluni/src/main/java/java/io/UnixFileSystem.java b/ojluni/src/main/java/java/io/UnixFileSystem.java
index 1659b17..6e1298d 100644
--- a/ojluni/src/main/java/java/io/UnixFileSystem.java
+++ b/ojluni/src/main/java/java/io/UnixFileSystem.java
@@ -166,7 +166,10 @@
}
}
if (res == null) {
+ // BEGIN Android-added: BlockGuard support.
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
+ // END Android-added: BlockGuard support.
res = canonicalize0(path);
cache.put(path, res);
if (useCanonPrefixCache &&
@@ -236,9 +239,11 @@
private native int getBooleanAttributes0(String abspath);
- // Android-changed: Added thread policy check
public int getBooleanAttributes(File f) {
+ // BEGIN Android-added: BlockGuard support.
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(f.getPath());
+ // END Android-added: BlockGuard support.
int rv = getBooleanAttributes0(f.getPath());
String name = f.getName();
@@ -246,43 +251,47 @@
return rv | (hidden ? BA_HIDDEN : 0);
}
- // Android-changed: Added thread policy check
+ // Android-changed: Add method to intercept native method call; BlockGuard support.
public boolean checkAccess(File f, int access) {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(f.getPath());
return checkAccess0(f, access);
}
private native boolean checkAccess0(File f, int access);
- // Android-changed: Added thread policy check
+ // Android-changed: Add method to intercept native method call; BlockGuard support.
public long getLastModifiedTime(File f) {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(f.getPath());
return getLastModifiedTime0(f);
}
private native long getLastModifiedTime0(File f);
- // Android-changed: Added thread policy check
+ // Android-changed: Add method to intercept native method call; BlockGuard support.
public long getLength(File f) {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(f.getPath());
return getLength0(f);
}
private native long getLength0(File f);
- // Android-changed: Added thread policy check
+ // Android-changed: Add method to intercept native method call; BlockGuard support.
public boolean setPermission(File f, int access, boolean enable, boolean owneronly) {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(f.getPath());
return setPermission0(f, access, enable, owneronly);
}
private native boolean setPermission0(File f, int access, boolean enable, boolean owneronly);
/* -- File operations -- */
- // Android-changed: Added thread policy check
+ // Android-changed: Add method to intercept native method call; BlockGuard support.
public boolean createFileExclusively(String path) throws IOException {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(path);
return createFileExclusively0(path);
}
private native boolean createFileExclusively0(String path) throws IOException;
- // Android-changed: Added thread policy check
public boolean delete(File f) {
// Keep canonicalization caches in sync after file deletion
// and renaming operations. Could be more clever than this
@@ -291,27 +300,31 @@
// anyway.
cache.clear();
javaHomePrefixCache.clear();
+ // BEGIN Android-added: BlockGuard support.
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(f.getPath());
+ // END Android-added: BlockGuard support.
return delete0(f);
}
private native boolean delete0(File f);
- // Android-changed: Added thread policy check
+ // Android-changed: Add method to intercept native method call; BlockGuard support.
public String[] list(File f) {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(f.getPath());
return list0(f);
}
private native String[] list0(File f);
- // Android-changed: Added thread policy check
+ // Android-changed: Add method to intercept native method call; BlockGuard support.
public boolean createDirectory(File f) {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(f.getPath());
return createDirectory0(f);
}
private native boolean createDirectory0(File f);
- // Android-changed: Added thread policy check
public boolean rename(File f1, File f2) {
// Keep canonicalization caches in sync after file deletion
// and renaming operations. Could be more clever than this
@@ -320,22 +333,28 @@
// anyway.
cache.clear();
javaHomePrefixCache.clear();
+ // BEGIN Android-added: BlockGuard support.
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(f1.getPath());
+ BlockGuard.getVmPolicy().onPathAccess(f2.getPath());
+ // END Android-added: BlockGuard support.
return rename0(f1, f2);
}
private native boolean rename0(File f1, File f2);
- // Android-changed: Added thread policy check
+ // Android-changed: Add method to intercept native method call; BlockGuard support.
public boolean setLastModifiedTime(File f, long time) {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(f.getPath());
return setLastModifiedTime0(f, time);
}
private native boolean setLastModifiedTime0(File f, long time);
- // Android-changed: Added thread policy check
+ // Android-changed: Add method to intercept native method call; BlockGuard support.
public boolean setReadOnly(File f) {
BlockGuard.getThreadPolicy().onWriteToDisk();
+ BlockGuard.getVmPolicy().onPathAccess(f.getPath());
return setReadOnly0(f);
}
private native boolean setReadOnly0(File f);
@@ -356,9 +375,10 @@
}
/* -- Disk usage -- */
- // Android-changed: Added thread policy check
+ // Android-changed: Add method to intercept native method call; BlockGuard support.
public long getSpace(File f, int t) {
BlockGuard.getThreadPolicy().onReadFromDisk();
+ BlockGuard.getVmPolicy().onPathAccess(f.getPath());
return getSpace0(f, t);
}
diff --git a/ojluni/src/main/java/java/lang/AbstractStringBuilder.java b/ojluni/src/main/java/java/lang/AbstractStringBuilder.java
index cc24e96..4c31e23 100644
--- a/ojluni/src/main/java/java/lang/AbstractStringBuilder.java
+++ b/ojluni/src/main/java/java/lang/AbstractStringBuilder.java
@@ -1,5 +1,4 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -419,7 +418,6 @@
*
* @param obj an {@code Object}.
* @return a reference to this object.
- * @hide
*/
public AbstractStringBuilder append(Object obj) {
return append(String.valueOf(obj));
@@ -442,7 +440,6 @@
*
* @param str a string.
* @return a reference to this object.
- * @hide
*/
public AbstractStringBuilder append(String str) {
if (str == null)
@@ -455,7 +452,6 @@
}
// Documentation in subclasses because of synchro difference
- /** @hide */
public AbstractStringBuilder append(StringBuffer sb) {
if (sb == null)
return appendNull();
@@ -468,7 +464,6 @@
/**
* @since 1.8
- * @hide
*/
AbstractStringBuilder append(AbstractStringBuilder asb) {
if (asb == null)
@@ -481,7 +476,6 @@
}
// Documentation in subclasses because of synchro difference
- /** @hide */
@Override
public AbstractStringBuilder append(CharSequence s) {
if (s == null)
@@ -534,7 +528,6 @@
* {@code start} is negative, or
* {@code start} is greater than {@code end} or
* {@code end} is greater than {@code s.length()}
- * @hide
*/
@Override
public AbstractStringBuilder append(CharSequence s, int start, int end) {
@@ -567,7 +560,6 @@
*
* @param str the characters to be appended.
* @return a reference to this object.
- * @hide
*/
public AbstractStringBuilder append(char[] str) {
int len = str.length;
@@ -598,7 +590,6 @@
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code len < 0}
* or {@code offset+len > str.length}
- * @hide
*/
public AbstractStringBuilder append(char str[], int offset, int len) {
if (len > 0) // let arraycopy report AIOOBE for len < 0
@@ -619,7 +610,6 @@
*
* @param b a {@code boolean}.
* @return a reference to this object.
- * @hide
*/
public AbstractStringBuilder append(boolean b) {
if (b) {
@@ -653,7 +643,6 @@
*
* @param c a {@code char}.
* @return a reference to this object.
- * @hide
*/
@Override
public AbstractStringBuilder append(char c) {
@@ -673,7 +662,6 @@
*
* @param i an {@code int}.
* @return a reference to this object.
- * @hide
*/
public AbstractStringBuilder append(int i) {
if (i == Integer.MIN_VALUE) {
@@ -700,7 +688,6 @@
*
* @param l a {@code long}.
* @return a reference to this object.
- * @hide
*/
public AbstractStringBuilder append(long l) {
if (l == Long.MIN_VALUE) {
@@ -727,7 +714,6 @@
*
* @param f a {@code float}.
* @return a reference to this object.
- * @hide
*/
public AbstractStringBuilder append(float f) {
FloatingDecimal.appendTo(f,this);
@@ -745,7 +731,6 @@
*
* @param d a {@code double}.
* @return a reference to this object.
- * @hide
*/
public AbstractStringBuilder append(double d) {
FloatingDecimal.appendTo(d,this);
@@ -765,7 +750,6 @@
* @throws StringIndexOutOfBoundsException if {@code start}
* is negative, greater than {@code length()}, or
* greater than {@code end}.
- * @hide
*/
public AbstractStringBuilder delete(int start, int end) {
if (start < 0)
@@ -800,7 +784,6 @@
* @return a reference to this object.
* @exception IllegalArgumentException if the specified
* {@code codePoint} isn't a valid Unicode code point
- * @hide
*/
public AbstractStringBuilder appendCodePoint(int codePoint) {
final int count = this.count;
@@ -835,7 +818,6 @@
* @throws StringIndexOutOfBoundsException if the {@code index}
* is negative or greater than or equal to
* {@code length()}.
- * @hide
*/
public AbstractStringBuilder deleteCharAt(int index) {
if ((index < 0) || (index >= count))
@@ -863,7 +845,6 @@
* @throws StringIndexOutOfBoundsException if {@code start}
* is negative, greater than {@code length()}, or
* greater than {@code end}.
- * @hide
*/
public AbstractStringBuilder replace(int start, int end, String str) {
if (start < 0)
@@ -975,7 +956,6 @@
* {@code offset} or {@code len} are negative, or
* {@code (offset+len)} is greater than
* {@code str.length}.
- * @hide
*/
public AbstractStringBuilder insert(int index, char[] str, int offset,
int len)
@@ -1011,7 +991,6 @@
* @param obj an {@code Object}.
* @return a reference to this object.
* @throws StringIndexOutOfBoundsException if the offset is invalid.
- * @hide
*/
public AbstractStringBuilder insert(int offset, Object obj) {
return insert(offset, String.valueOf(obj));
@@ -1047,7 +1026,6 @@
* @param str a string.
* @return a reference to this object.
* @throws StringIndexOutOfBoundsException if the offset is invalid.
- * @hide
*/
public AbstractStringBuilder insert(int offset, String str) {
if ((offset < 0) || (offset > length()))
@@ -1085,7 +1063,6 @@
* @param str a character array.
* @return a reference to this object.
* @throws StringIndexOutOfBoundsException if the offset is invalid.
- * @hide
*/
public AbstractStringBuilder insert(int offset, char[] str) {
if ((offset < 0) || (offset > length()))
@@ -1118,7 +1095,6 @@
* @param s the sequence to be inserted
* @return a reference to this object.
* @throws IndexOutOfBoundsException if the offset is invalid.
- * @hide
*/
public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
if (s == null)
@@ -1171,7 +1147,6 @@
* {@code start} or {@code end} are negative, or
* {@code start} is greater than {@code end} or
* {@code end} is greater than {@code s.length()}
- * @hide
*/
public AbstractStringBuilder insert(int dstOffset, CharSequence s,
int start, int end) {
@@ -1211,7 +1186,6 @@
* @param b a {@code boolean}.
* @return a reference to this object.
* @throws StringIndexOutOfBoundsException if the offset is invalid.
- * @hide
*/
public AbstractStringBuilder insert(int offset, boolean b) {
return insert(offset, String.valueOf(b));
@@ -1235,7 +1209,6 @@
* @param c a {@code char}.
* @return a reference to this object.
* @throws IndexOutOfBoundsException if the offset is invalid.
- * @hide
*/
public AbstractStringBuilder insert(int offset, char c) {
ensureCapacityInternal(count + 1);
@@ -1263,7 +1236,6 @@
* @param i an {@code int}.
* @return a reference to this object.
* @throws StringIndexOutOfBoundsException if the offset is invalid.
- * @hide
*/
public AbstractStringBuilder insert(int offset, int i) {
return insert(offset, String.valueOf(i));
@@ -1287,7 +1259,6 @@
* @param l a {@code long}.
* @return a reference to this object.
* @throws StringIndexOutOfBoundsException if the offset is invalid.
- * @hide
*/
public AbstractStringBuilder insert(int offset, long l) {
return insert(offset, String.valueOf(l));
@@ -1311,7 +1282,6 @@
* @param f a {@code float}.
* @return a reference to this object.
* @throws StringIndexOutOfBoundsException if the offset is invalid.
- * @hide
*/
public AbstractStringBuilder insert(int offset, float f) {
return insert(offset, String.valueOf(f));
@@ -1335,7 +1305,6 @@
* @param d a {@code double}.
* @return a reference to this object.
* @throws StringIndexOutOfBoundsException if the offset is invalid.
- * @hide
*/
public AbstractStringBuilder insert(int offset, double d) {
return insert(offset, String.valueOf(d));
@@ -1376,8 +1345,7 @@
* specified substring, starting at the specified index.
*/
public int indexOf(String str, int fromIndex) {
- return String.indexOf(value, 0, count,
- str.toCharArray(), 0, str.length(), fromIndex);
+ return String.indexOf(value, 0, count, str, fromIndex);
}
/**
@@ -1416,8 +1384,7 @@
* specified substring.
*/
public int lastIndexOf(String str, int fromIndex) {
- return String.lastIndexOf(value, 0, count,
- str.toCharArray(), 0, str.length(), fromIndex);
+ return String.lastIndexOf(value, 0, count, str, fromIndex);
}
/**
@@ -1441,7 +1408,6 @@
* a valid surrogate pair.
*
* @return a reference to this object.
- * @hide
*/
public AbstractStringBuilder reverse() {
boolean hasSurrogates = false;
diff --git a/ojluni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java b/ojluni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
index 9c85456..d07a4b2 100644
--- a/ojluni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
+++ b/ojluni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
@@ -65,22 +65,4 @@
public ArrayIndexOutOfBoundsException(String s) {
super(s);
}
-
- // Android-added: Additional constructor for internal use.
- /**
- * @hide
- */
- public ArrayIndexOutOfBoundsException(int sourceLength, int index) {
- super("length=" + sourceLength + "; index=" + index);
- }
-
- // Android-added: Additional constructor for internal use.
- /**
- * @hide
- */
- public ArrayIndexOutOfBoundsException(int sourceLength, int offset,
- int count) {
- super("length=" + sourceLength + "; regionStart=" + offset
- + "; regionLength=" + count);
- }
}
diff --git a/ojluni/src/main/java/java/lang/Character.java b/ojluni/src/main/java/java/lang/Character.java
index 454cbbb..0b3081f 100644
--- a/ojluni/src/main/java/java/lang/Character.java
+++ b/ojluni/src/main/java/java/lang/Character.java
@@ -6000,6 +6000,8 @@
@FastNative
static native boolean isIdeographicImpl(int codePoint);
+ // Android-changed: Removed @see tag (target does not exist on Android):
+ // @see javax.lang.model.SourceVersion#isIdentifier(CharSequence)
/**
* Determines if the specified character is
* permissible as the first character in a Java identifier.
@@ -6024,13 +6026,14 @@
* @see Character#isJavaIdentifierPart(char)
* @see Character#isLetter(char)
* @see Character#isUnicodeIdentifierStart(char)
- * @see javax.lang.model.SourceVersion#isIdentifier(CharSequence)
* @since 1.1
*/
public static boolean isJavaIdentifierStart(char ch) {
return isJavaIdentifierStart((int)ch);
}
+ // Android-changed: Removed @see tag (target does not exist on Android):
+ // @see javax.lang.model.SourceVersion#isIdentifier(CharSequence)
/**
* Determines if the character (Unicode code point) is
* permissible as the first character in a Java identifier.
@@ -6053,7 +6056,6 @@
* @see Character#isJavaIdentifierPart(int)
* @see Character#isLetter(int)
* @see Character#isUnicodeIdentifierStart(int)
- * @see javax.lang.model.SourceVersion#isIdentifier(CharSequence)
* @since 1.5
*/
public static boolean isJavaIdentifierStart(int codePoint) {
@@ -6074,6 +6076,8 @@
| (1 << LETTER_NUMBER))) != 0;
}
+ // Android-changed: Removed @see tag (target does not exist on Android):
+ // @see javax.lang.model.SourceVersion#isIdentifier(CharSequence)
/**
* Determines if the specified character may be part of a Java
* identifier as other than the first character.
@@ -6104,13 +6108,14 @@
* @see Character#isJavaIdentifierStart(char)
* @see Character#isLetterOrDigit(char)
* @see Character#isUnicodeIdentifierPart(char)
- * @see javax.lang.model.SourceVersion#isIdentifier(CharSequence)
* @since 1.1
*/
public static boolean isJavaIdentifierPart(char ch) {
return isJavaIdentifierPart((int)ch);
}
+ // Android-changed: Removed @see tag (target does not exist on Android):
+ // @see javax.lang.model.SourceVersion#isIdentifier(CharSequence)
/**
* Determines if the character (Unicode code point) may be part of a Java
* identifier as other than the first character.
@@ -6137,7 +6142,6 @@
* @see Character#isJavaIdentifierStart(int)
* @see Character#isLetterOrDigit(int)
* @see Character#isUnicodeIdentifierPart(int)
- * @see javax.lang.model.SourceVersion#isIdentifier(CharSequence)
* @since 1.5
*/
public static boolean isJavaIdentifierPart(int codePoint) {
diff --git a/ojluni/src/main/java/java/lang/Class.java b/ojluni/src/main/java/java/lang/Class.java
index f31a42c..f792248 100644
--- a/ojluni/src/main/java/java/lang/Class.java
+++ b/ojluni/src/main/java/java/lang/Class.java
@@ -57,8 +57,8 @@
import libcore.util.EmptyArray;
import dalvik.system.ClassExt;
-import dalvik.system.VMStack;
import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
/**
* Instances of the class {@code Class} represent classes and
@@ -375,7 +375,8 @@
@CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
- return forName(className, true, VMStack.getCallingClassLoader());
+ Class<?> caller = Reflection.getCallerClass();
+ return forName(className, true, ClassLoader.getClassLoader(caller));
}
@@ -778,6 +779,8 @@
if (isPrimitive()) {
return null;
}
+ // Android-note: The RI returns null in the case where Android returns BootClassLoader.
+ // Noted in http://b/111850480#comment3
return (classLoader == null) ? BootClassLoader.getInstance() : classLoader;
}
@@ -2065,7 +2068,8 @@
// Fail if we didn't find the method or it was expected to be public.
if (result == null ||
(recursivePublicMethods && !Modifier.isPublic(result.getAccessFlags()))) {
- throw new NoSuchMethodException(name + " " + Arrays.toString(parameterTypes));
+ throw new NoSuchMethodException(getName() + "." + name + " "
+ + Arrays.toString(parameterTypes));
}
return result;
}
@@ -2324,7 +2328,8 @@
}
Constructor<T> result = getDeclaredConstructorInternal(parameterTypes);
if (result == null || which == Member.PUBLIC && !Modifier.isPublic(result.getAccessFlags())) {
- throw new NoSuchMethodException("<init> " + Arrays.toString(parameterTypes));
+ throw new NoSuchMethodException(getName() + ".<init> "
+ + Arrays.toString(parameterTypes));
}
return result;
}
diff --git a/ojluni/src/main/java/java/lang/ClassLoader.java b/ojluni/src/main/java/java/lang/ClassLoader.java
index 08dee73..0a8b08a 100644
--- a/ojluni/src/main/java/java/lang/ClassLoader.java
+++ b/ojluni/src/main/java/java/lang/ClassLoader.java
@@ -1098,6 +1098,18 @@
return SystemClassLoader.loader;
}
+ // Returns the class's class loader, or null if none.
+ static ClassLoader getClassLoader(Class<?> caller) {
+ // This can be null if the VM is requesting it
+ if (caller == null) {
+ return null;
+ }
+ // Android-changed: Use Class.getClassLoader(); there is no Class.getClassLoader0().
+ // // Circumvent security check since this is package-private
+ // return caller.getClassLoader0();
+ return caller.getClassLoader();
+ }
+
// -- Package --
/**
diff --git a/ojluni/src/main/java/java/lang/Enum.java b/ojluni/src/main/java/java/lang/Enum.java
index 8ada57f..988c133 100644
--- a/ojluni/src/main/java/java/lang/Enum.java
+++ b/ojluni/src/main/java/java/lang/Enum.java
@@ -33,6 +33,7 @@
import java.io.ObjectStreamException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.Objects;
import libcore.util.BasicLruCache;
import libcore.util.EmptyArray;
@@ -232,15 +233,13 @@
* is null
* @since 1.5
*/
+ // BEGIN Android-changed: Use a static BasicLruCache mapping Enum class -> Enum instance array.
+ // This change was made to fix a performance regression. See b/4087759 and b/109791362 for more
+ // background information.
public static <T extends Enum<T>> T valueOf(Class<T> enumType,
String name) {
- // Android-changed: Use a static BasicLruCache mapping Enum class -> Enum instance array.
- if (enumType == null) {
- throw new NullPointerException("enumType == null");
- }
- if (name == null) {
- throw new NullPointerException("name == null");
- }
+ Objects.requireNonNull(enumType, "enumType == null");
+ Objects.requireNonNull(enumType, "name == null");
T[] values = getSharedConstants(enumType);
if (values == null) {
throw new IllegalArgumentException(enumType.toString() + " is not an enum type.");
@@ -258,23 +257,24 @@
"No enum constant " + enumType.getCanonicalName() + "." + name);
}
+ private static Object[] enumValues(Class<? extends Enum> clazz) {
+ if (!clazz.isEnum()) {
+ // Either clazz is Enum.class itself, or it is not an enum class and the method was
+ // called unsafely e.g. using an unchecked cast or via reflection.
+ return null;
+ }
+ try {
+ Method valueMethod = clazz.getDeclaredMethod("values");
+ return (Object[]) valueMethod.invoke(null);
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private static final BasicLruCache<Class<? extends Enum>, Object[]> sharedConstantsCache
= new BasicLruCache<Class<? extends Enum>, Object[]>(64) {
@Override protected Object[] create(Class<? extends Enum> enumType) {
- if (!enumType.isEnum()) {
- return null;
- }
- try {
- Method method = enumType.getDeclaredMethod("values", EmptyArray.CLASS);
- method.setAccessible(true);
- return (Object[]) method.invoke((Object[]) null);
- } catch (NoSuchMethodException impossible) {
- throw new AssertionError("impossible", impossible);
- } catch (IllegalAccessException impossible) {
- throw new AssertionError("impossible", impossible);
- } catch (InvocationTargetException impossible) {
- throw new AssertionError("impossible", impossible);
- }
+ return enumValues(enumType);
}
};
@@ -288,6 +288,7 @@
public static <T extends Enum<T>> T[] getSharedConstants(Class<T> enumType) {
return (T[]) sharedConstantsCache.get(enumType);
}
+ // END Android-changed: Use a static BasicLruCache mapping Enum class -> Enum instance array.
/**
* enum classes cannot have finalize methods.
diff --git a/ojluni/src/main/java/java/lang/Object.java b/ojluni/src/main/java/java/lang/Object.java
index e9728e0..d307144 100644
--- a/ojluni/src/main/java/java/lang/Object.java
+++ b/ojluni/src/main/java/java/lang/Object.java
@@ -39,6 +39,13 @@
*/
public class Object {
+ // Android-removed: registerNatives() not used on Android
+ // private static native void registerNatives();
+ // static {
+ // registerNatives();
+ // }
+
+ // Android-added: Use Android specific fields for Class and monitor.
private transient Class<?> shadow$_klass_;
private transient int shadow$_monitor_;
@@ -61,6 +68,8 @@
* class of this object.
* @jls 15.8.2 Class Literals
*/
+ // Android-changed: Use Android specific fields for Class and monitor.
+ // public final native Class<?> getClass();
public final Class<?> getClass() {
return shadow$_klass_;
}
@@ -100,11 +109,12 @@
* @see java.lang.Object#equals(java.lang.Object)
* @see java.lang.System#identityHashCode
*/
+ // BEGIN Android-changed: Added a local helper for identityHashCode.
+ // public native int hashCode();
public int hashCode() {
return identityHashCode(this);
}
- // Android-changed: add a local helper for identityHashCode.
// Package-private to be used by j.l.System. We do the implementation here
// to avoid Object.hashCode doing a clinit check on j.l.System, and also
// to avoid leaking shadow$_monitor_ outside of this class.
@@ -119,8 +129,13 @@
return identityHashCodeNative(obj);
}
+ /**
+ * Return the identity hash code when the information in the monitor field
+ * is not sufficient.
+ */
@FastNative
private static native int identityHashCodeNative(Object obj);
+ // END Android-changed: Added a local helper for identityHashCode.
/**
* Indicates whether some other object is "equal to" this one.
@@ -232,6 +247,9 @@
* be cloned.
* @see java.lang.Cloneable
*/
+ // BEGIN Android-changed: Use native local helper for clone()
+ // Checks whether cloning is allowed before calling native local helper.
+ // protected native Object clone() throws CloneNotSupportedException;
protected Object clone() throws CloneNotSupportedException {
if (!(this instanceof Cloneable)) {
throw new CloneNotSupportedException("Class " + getClass().getName() +
@@ -246,7 +264,7 @@
*/
@FastNative
private native Object internalClone();
-
+ // END Android-changed: Use native local helper for clone()
/**
* Returns a string representation of the object. In general, the
@@ -405,7 +423,7 @@
* description of the ways in which a thread can become the owner of
* a monitor.
*
- * @param millis the maximum time to wait in milliseconds.
+ * @param timeout the maximum time to wait in milliseconds.
* @throws IllegalArgumentException if the value of timeout is
* negative.
* @throws IllegalMonitorStateException if the current thread is not
@@ -418,8 +436,10 @@
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
*/
- public final void wait(long millis) throws InterruptedException {
- wait(millis, 0);
+ // Android-changed: Implement wait(long) non-natively.
+ // public final native void wait(long timeout) throws InterruptedException;
+ public final void wait(long timeout) throws InterruptedException {
+ wait(timeout, 0);
}
/**
@@ -470,7 +490,7 @@
* description of the ways in which a thread can become the owner of
* a monitor.
*
- * @param millis the maximum time to wait in milliseconds.
+ * @param timeout the maximum time to wait in milliseconds.
* @param nanos additional time, in nanoseconds range
* 0-999999.
* @throws IllegalArgumentException if the value of timeout is
@@ -484,8 +504,27 @@
* status</i> of the current thread is cleared when
* this exception is thrown.
*/
+ // Android-changed: Implement wait(long, int) natively.
+ /*
+ public final void wait(long timeout, int nanos) throws InterruptedException {
+ if (timeout < 0) {
+ throw new IllegalArgumentException("timeout value is negative");
+ }
+
+ if (nanos < 0 || nanos > 999999) {
+ throw new IllegalArgumentException(
+ "nanosecond timeout value out of range");
+ }
+
+ if (nanos > 0) {
+ timeout++;
+ }
+
+ wait(timeout);
+ }
+ */
@FastNative
- public final native void wait(long millis, int nanos) throws InterruptedException;
+ public final native void wait(long timeout, int nanos) throws InterruptedException;
/**
* Causes the current thread to wait until another thread invokes the
@@ -525,8 +564,9 @@
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
*/
- @FastNative
- public final native void wait() throws InterruptedException;
+ public final void wait() throws InterruptedException {
+ wait(0);
+ }
/**
* Called by the garbage collector on an object when garbage collection
diff --git a/ojluni/src/main/java/java/lang/Package.java b/ojluni/src/main/java/java/lang/Package.java
index 33136f3..b6a37fd 100644
--- a/ojluni/src/main/java/java/lang/Package.java
+++ b/ojluni/src/main/java/java/lang/Package.java
@@ -52,7 +52,7 @@
import sun.net.www.ParseUtil;
import sun.reflect.CallerSensitive;
import dalvik.system.VMRuntime;
-import dalvik.system.VMStack;
+import sun.reflect.Reflection;
import java.lang.annotation.Annotation;
@@ -279,9 +279,7 @@
*/
@CallerSensitive
public static Package getPackage(String name) {
- // Android-changed: Use VMStack.getCallingClassLoader() to obtain the classloader.
- // ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
- ClassLoader l = VMStack.getCallingClassLoader();
+ ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
if (l != null) {
return l.getPackage(name);
} else {
@@ -303,9 +301,7 @@
*/
@CallerSensitive
public static Package[] getPackages() {
- // Android-changed: Use VMStack.getCallingClassLoader() to obtain the classloader.
- // ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
- ClassLoader l = VMStack.getCallingClassLoader();
+ ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
if (l != null) {
return l.getPackages();
} else {
diff --git a/ojluni/src/main/java/java/lang/ProcessImpl.java b/ojluni/src/main/java/java/lang/ProcessImpl.java
index 6b88585..39ea145 100644
--- a/ojluni/src/main/java/java/lang/ProcessImpl.java
+++ b/ojluni/src/main/java/java/lang/ProcessImpl.java
@@ -39,6 +39,9 @@
* @since 1.5
*/
final class ProcessImpl {
+ // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+ // private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
+ // = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
private ProcessImpl() {} // Not instantiable
@@ -101,6 +104,8 @@
std_fds[0] = 0;
else {
f0 = new FileInputStream(redirects[0].file());
+ // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+ // std_fds[0] = fdAccess.get(f0.getFD());
std_fds[0] = f0.getFD().getInt$();
}
@@ -111,6 +116,8 @@
else {
f1 = new FileOutputStream(redirects[1].file(),
redirects[1].append());
+ // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+ // std_fds[1] = fdAccess.get(f1.getFD());
std_fds[1] = f1.getFD().getInt$();
}
@@ -121,6 +128,8 @@
else {
f2 = new FileOutputStream(redirects[2].file(),
redirects[2].append());
+ // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+ // std_fds[2] = fdAccess.get(f2.getFD());
std_fds[2] = f2.getFD().getInt$();
}
}
diff --git a/ojluni/src/main/java/java/lang/Runtime.java b/ojluni/src/main/java/java/lang/Runtime.java
index acc75b0..2fc124c 100644
--- a/ojluni/src/main/java/java/lang/Runtime.java
+++ b/ojluni/src/main/java/java/lang/Runtime.java
@@ -29,14 +29,17 @@
import dalvik.annotation.optimization.FastNative;
import java.io.*;
import java.util.StringTokenizer;
+
+import dalvik.system.BlockGuard;
import sun.reflect.CallerSensitive;
import java.lang.ref.FinalizerReference;
import java.util.ArrayList;
import java.util.List;
import dalvik.system.BaseDexClassLoader;
import dalvik.system.VMDebug;
-import dalvik.system.VMStack;
import dalvik.system.VMRuntime;
+import sun.reflect.Reflection;
+
import libcore.io.IoUtils;
import libcore.io.Libcore;
import libcore.util.EmptyArray;
@@ -765,7 +768,14 @@
* The method {@link System#gc()} is the conventional and convenient
* means of invoking this method.
*/
- public native void gc();
+ // Android-changed: Added BlockGuard check to gc()
+ // public native void gc();
+ public void gc() {
+ BlockGuard.getThreadPolicy().onExplicitGc();
+ nativeGc();
+ }
+
+ private native void nativeGc();
/* Wormhole for calling java.lang.ref.Finalizer.runFinalization */
private static native void runFinalization0();
@@ -888,7 +898,7 @@
*/
@CallerSensitive
public void load(String filename) {
- load0(VMStack.getStackClass1(), filename);
+ load0(Reflection.getCallerClass(), filename);
}
/** Check target sdk, if it's higher than N, we throw an UnsupportedOperationException */
@@ -975,7 +985,26 @@
*/
@CallerSensitive
public void loadLibrary(String libname) {
- loadLibrary0(VMStack.getCallingClassLoader(), libname);
+ loadLibrary0(Reflection.getCallerClass(), libname);
+ }
+
+ // BEGIN Android-changed: Different implementation of loadLibrary0(Class, String).
+ /*
+ synchronized void loadLibrary0(Class<?> fromClass, String libname) {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkLink(libname);
+ }
+ if (libname.indexOf((int)File.separatorChar) != -1) {
+ throw new UnsatisfiedLinkError(
+ "Directory separator should not appear in library name: " + libname);
+ }
+ ClassLoader.loadLibrary(fromClass, libname, false);
+ }
+ */
+ void loadLibrary0(Class<?> fromClass, String libname) {
+ ClassLoader classLoader = ClassLoader.getClassLoader(fromClass);
+ loadLibrary0(classLoader, libname);
}
/**
@@ -1001,7 +1030,10 @@
"Directory separator should not appear in library name: " + libname);
}
String libraryName = libname;
- if (loader != null) {
+ // Android-note: BootClassLoader doesn't implement findLibrary(). http://b/111850480
+ // Android's class.getClassLoader() can return BootClassLoader where the RI would
+ // have returned null; therefore we treat BootClassLoader the same as null here.
+ if (loader != null && !(loader instanceof BootClassLoader)) {
String filename = loader.findLibrary(libraryName);
if (filename == null) {
// It's not necessarily true that the ClassLoader used
@@ -1069,6 +1101,7 @@
}
private static native String nativeLoad(String filename, ClassLoader loader);
+ // END Android-changed: Different implementation of loadLibrary0(Class, String).
/**
* Creates a localized version of an input stream. This method takes
diff --git a/ojluni/src/main/java/java/lang/StackTraceElement.java b/ojluni/src/main/java/java/lang/StackTraceElement.java
index e519fea..e3dad88 100644
--- a/ojluni/src/main/java/java/lang/StackTraceElement.java
+++ b/ojluni/src/main/java/java/lang/StackTraceElement.java
@@ -169,8 +169,22 @@
* @see Throwable#printStackTrace()
*/
public String toString() {
- // Android-changed: When ART cannot find a line number, the lineNumber field is set
- // to the dex_pc and the fileName field is set to null.
+ // BEGIN Android-changed: Fall back Unknown Source:<dex_pc> for unknown lineNumber.
+ // http://b/30183883
+ // The only behavior change is that "Unknown Source" is followed by a number
+ // (the value of the dex program counter, dex_pc), which never occurs on the
+ // RI. This value isn't a line number, but can be useful for debugging and
+ // avoids the need to ship line number information along with the dex code to
+ // get an accurate stack trace.
+ // Formatting it in this way might be more digestible to automated tools that
+ // are not specifically written to expect this behavior.
+ /*
+ return getClassName() + "." + methodName +
+ (isNativeMethod() ? "(Native Method)" :
+ (fileName != null && lineNumber >= 0 ?
+ "(" + fileName + ":" + lineNumber + ")" :
+ (fileName != null ? "("+fileName+")" : "(Unknown Source)")));
+ */
StringBuilder result = new StringBuilder();
result.append(getClassName()).append(".").append(methodName);
if (isNativeMethod()) {
@@ -190,6 +204,7 @@
}
}
return result.toString();
+ // END Android-changed: Fall back Unknown Source:<dex_pc> for unknown lineNumber.
}
/**
diff --git a/ojluni/src/main/java/java/lang/String.java b/ojluni/src/main/java/java/lang/String.java
index de54882..b5df9f0 100644
--- a/ojluni/src/main/java/java/lang/String.java
+++ b/ojluni/src/main/java/java/lang/String.java
@@ -1707,24 +1707,20 @@
* or {@code -1} if there is no such occurrence.
*/
public int indexOf(String str, int fromIndex) {
- // Android-changed: Change parameters to static indexOf to match new signature below.
+ // Android-changed: Delegate to the static indexOf method below.
return indexOf(this, str, fromIndex);
}
+ // BEGIN Android-added: Private static indexOf method that takes String parameters.
+ // The use of length(), charAt(), etc. makes it more efficient for compressed strings.
/**
- * Code shared by String and AbstractStringBuilder to do searches. The
- * source is the character array being searched, and the target
- * is the string being searched for.
+ * The source is the string being searched, and the target is the string being searched for.
*
* @param source the characters being searched.
* @param target the characters being searched for.
* @param fromIndex the index to begin searching from.
*/
- // BEGIN Android-changed: Change signature to take String object rather than char arrays.
- // The implementation using a java char array is replaced with one using length() & charAt().
- static int indexOf(String source,
- String target,
- int fromIndex) {
+ private static int indexOf(String source, String target, int fromIndex) {
final int sourceLength = source.length();
final int targetLength = target.length();
if (fromIndex >= sourceLength) {
@@ -1761,7 +1757,25 @@
}
return -1;
}
- // END Android-changed: Change signature to take String object rather than char arrays.
+ // END Android-added: Private static indexOf method that takes String parameters.
+
+ /**
+ * Code shared by String and AbstractStringBuilder to do searches. The
+ * source is the character array being searched, and the target
+ * is the string being searched for.
+ *
+ * @param source the characters being searched.
+ * @param sourceOffset offset of the source string.
+ * @param sourceCount count of the source string.
+ * @param target the characters being searched for.
+ * @param fromIndex the index to begin searching from.
+ */
+ static int indexOf(char[] source, int sourceOffset, int sourceCount,
+ String target, int fromIndex) {
+ return indexOf(source, sourceOffset, sourceCount,
+ target.toCharArray(), 0, target.length(),
+ fromIndex);
+ }
/**
* Code shared by String and StringBuffer to do searches. The
@@ -1854,20 +1868,16 @@
return lastIndexOf(this, str, fromIndex);
}
+ // BEGIN Android-added: Private static lastIndexOf method that takes String parameters.
+ // The use of length(), charAt(), etc. makes it more efficient for compressed strings.
/**
- * Code shared by String and AbstractStringBuilder to do searches. The
- * source is the character array being searched, and the target
- * is the string being searched for.
+ * The source is the string being searched, and the target is the string being searched for.
*
* @param source the characters being searched.
* @param target the characters being searched for.
* @param fromIndex the index to begin searching from.
*/
- // BEGIN Android-changed: Change signature to take String object rather than char arrays.
- // The implementation using a java char array is replaced with one using length() & charAt().
- static int lastIndexOf(String source,
- String target,
- int fromIndex) {
+ private static int lastIndexOf(String source, String target, int fromIndex) {
/*
* Check arguments; return immediately where possible. For
* consistency, don't check for null str.
@@ -1912,7 +1922,25 @@
return start + 1;
}
}
- // END Android-changed: Change signature to take String object rather than char arrays.
+ // END Android-added: Private static lastIndexOf method that takes String parameters.
+
+ /**
+ * Code shared by String and AbstractStringBuilder to do searches. The
+ * source is the character array being searched, and the target
+ * is the string being searched for.
+ *
+ * @param source the characters being searched.
+ * @param sourceOffset offset of the source string.
+ * @param sourceCount count of the source string.
+ * @param target the characters being searched for.
+ * @param fromIndex the index to begin searching from.
+ */
+ static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
+ String target, int fromIndex) {
+ return lastIndexOf(source, sourceOffset, sourceCount,
+ target.toCharArray(), 0, target.length(),
+ fromIndex);
+ }
/**
* Code shared by String and StringBuffer to do searches. The
@@ -2907,9 +2935,7 @@
* character array.
*/
public static String valueOf(char data[]) {
- // Android-changed: Replace constructor call with call to new StringFactory class.
- // return new String(data);
- return StringFactory.newStringFromChars(data);
+ return new String(data);
}
/**
@@ -2933,9 +2959,7 @@
* {@code data.length}.
*/
public static String valueOf(char data[], int offset, int count) {
- // Android-changed: Replace constructor call with call to new StringFactory class.
- // return new String(data, offset, count);
- return StringFactory.newStringFromChars(data, offset, count);
+ return new String(data, offset, count);
}
/**
@@ -2952,10 +2976,7 @@
* {@code data.length}.
*/
public static String copyValueOf(char data[], int offset, int count) {
- // Android-changed: Replace constructor call with call to new StringFactory class.
- // All public String constructors now copy the data.
- // return new String(data, offset, count);
- return StringFactory.newStringFromChars(data, offset, count);
+ return new String(data, offset, count);
}
/**
@@ -2966,9 +2987,7 @@
* character array.
*/
public static String copyValueOf(char data[]) {
- // Android-changed: Replace constructor call with call to new StringFactory class.
- // return new String(data);
- return StringFactory.newStringFromChars(data);
+ return new String(data);
}
/**
@@ -2992,7 +3011,8 @@
* as its single character the argument {@code c}.
*/
public static String valueOf(char c) {
- // Android-changed: Replace constructor call with call to new StringFactory class.
+ // Android-changed: Replace constructor call with call to StringFactory class.
+ // There is currently no String(char[], boolean) on Android to call. http://b/79902155
// char data[] = {c};
// return new String(data, true);
return StringFactory.newStringFromChars(0, 1, new char[] { c });
diff --git a/ojluni/src/main/java/java/lang/StringBuilder.java b/ojluni/src/main/java/java/lang/StringBuilder.java
index 42642c7..325c9c5 100644
--- a/ojluni/src/main/java/java/lang/StringBuilder.java
+++ b/ojluni/src/main/java/java/lang/StringBuilder.java
@@ -404,10 +404,13 @@
@Override
public String toString() {
+ // BEGIN Android-added: Return a constant "" for an empty buffer to keep historic behavior.
if (count == 0) {
return "";
}
- return StringFactory.newStringFromChars(0, count, value);
+ // END Android-added: Return a constant "" for an empty buffer to keep historic behavior.
+ // Create a copy, don't share the array
+ return new String(value, 0, count);
}
/**
diff --git a/ojluni/src/main/java/java/lang/System.java b/ojluni/src/main/java/java/lang/System.java
index 65a9d4a..2008380 100644
--- a/ojluni/src/main/java/java/lang/System.java
+++ b/ojluni/src/main/java/java/lang/System.java
@@ -30,7 +30,6 @@
import android.system.StructPasswd;
import android.system.StructUtsname;
import dalvik.system.VMRuntime;
-import dalvik.system.VMStack;
import java.io.*;
import java.lang.annotation.Annotation;
import java.nio.channels.Channel;
@@ -44,6 +43,7 @@
import libcore.util.TimeZoneDataFiles;
import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
/**
* The <code>System</code> class contains several useful class fields
@@ -1630,7 +1630,7 @@
*/
@CallerSensitive
public static void load(String filename) {
- Runtime.getRuntime().load0(VMStack.getStackClass1(), filename);
+ Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);
}
/**
@@ -1666,7 +1666,7 @@
*/
@CallerSensitive
public static void loadLibrary(String libname) {
- Runtime.getRuntime().loadLibrary0(VMStack.getCallingClassLoader(), libname);
+ Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);
}
/**
diff --git a/ojluni/src/main/java/java/lang/Thread.java b/ojluni/src/main/java/java/lang/Thread.java
index d462033..28b50a8 100644
--- a/ojluni/src/main/java/java/lang/Thread.java
+++ b/ojluni/src/main/java/java/lang/Thread.java
@@ -141,22 +141,33 @@
*/
public
class Thread implements Runnable {
- /* Make sure registerNatives is the first thing <clinit> does. */
+ // Android-removed: registerNatives() not used on Android.
+ /*
+ /* Make sure registerNatives is the first thing <clinit> does. *
+ private static native void registerNatives();
+ static {
+ registerNatives();
+ }
+ */
+ // BEGIN Android-added: Android specific fields, lock, nativePeer.
/**
* The synchronization object responsible for this thread's join/sleep/park operations.
*/
private final Object lock = new Object();
+ /**
+ * Reference to the native thread object.
+ *
+ * <p>Is 0 if the native thread has not yet been created/started, or has been destroyed.
+ */
private volatile long nativePeer;
-
- boolean started = false;
+ // END Android-added: Android specific fields, lock, nativePeer, started.
private volatile String name;
-
- private int priority;
- private Thread threadQ;
- private long eetop;
+ private int priority;
+ private Thread threadQ;
+ private long eetop;
/* Whether or not to single_step this thread. */
private boolean single_step;
@@ -219,7 +230,22 @@
* initialized to indicate thread 'not yet started'
*/
- private volatile int threadStatus = 0;
+ // BEGIN Android-changed: Replace unused threadStatus field with started field.
+ // Upstream this is modified by the native code and read in the start() and getState() methods
+ // but in Android it is unused. The threadStatus is essentially an internal representation of
+ // the Thread.State enum. Android uses two sources for that information, the native thread
+ // state and the started field. The reason two sources are needed is because the native thread
+ // is created when the thread is started and destroyed when the thread is stopped. That means
+ // that the native thread state does not exist before the Thread has started (in State.NEW) or
+ // after it has been stopped (in State.TERMINATED). In that case (i.e. when the nativePeer = 0)
+ // the started field differentiates between the two states, i.e. if started = false then the
+ // thread is in State.NEW and if started = true then the thread is in State.TERMINATED.
+ // private volatile int threadStatus = 0;
+ /**
+ * True if the the Thread has been started, even it has since been stopped.
+ */
+ boolean started = false;
+ // END Android-changed: Replace unused threadStatus field with started field.
private static synchronized long nextThreadID() {
@@ -241,11 +267,11 @@
private volatile Interruptible blocker;
private final Object blockerLock = new Object();
- /**
- * Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
- *
+ /** Set the blocker field
* @hide
*/
+ // Android-changed: Make blockedOn() @hide public, for internal use.
+ // Used by java.nio.channels.spi.AbstractInterruptibleChannel.
public void blockedOn(Interruptible b) {
synchronized (blockerLock) {
blocker = b;
@@ -310,13 +336,15 @@
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
+ // BEGIN Android-changed: Implement sleep() methods using a shared native implementation.
public static void sleep(long millis) throws InterruptedException {
- Thread.sleep(millis, 0);
+ sleep(millis, 0);
}
@FastNative
private static native void sleep(Object lock, long millis, int nanos)
throws InterruptedException;
+ // END Android-changed: Implement sleep() methods using a shared native implementation.
/**
* Causes the currently executing thread to sleep (temporarily cease
@@ -342,6 +370,17 @@
*/
public static void sleep(long millis, int nanos)
throws InterruptedException {
+ // BEGIN Android-changed: Improve exception messages.
+ /*
+ if (millis < 0) {
+ throw new IllegalArgumentException("timeout value is negative");
+ }
+
+ if (nanos < 0 || nanos > 999999) {
+ throw new IllegalArgumentException(
+ "nanosecond timeout value out of range");
+ }
+ */
if (millis < 0) {
throw new IllegalArgumentException("millis < 0: " + millis);
}
@@ -351,7 +390,18 @@
if (nanos > 999999) {
throw new IllegalArgumentException("nanos > 999999: " + nanos);
}
+ // END Android-changed: Improve exception messages.
+ // BEGIN Android-changed: Implement sleep() methods using a shared native implementation.
+ // Attempt nanosecond rather than millisecond accuracy for sleep();
+ // RI code rounds to the nearest millisecond.
+ /*
+ if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
+ millis++;
+ }
+
+ sleep(millis);
+ */
// The JLS 3rd edition, section 17.9 says: "...sleep for zero
// time...need not have observable effects."
if (millis == 0 && nanos == 0) {
@@ -367,7 +417,8 @@
Object lock = currentThread().lock;
- // Wait may return early, so loop until sleep duration passes.
+ // The native sleep(...) method actually performs a special type of wait, which may return
+ // early, so loop until sleep duration passes.
synchronized (lock) {
while (true) {
sleep(lock, millis, nanos);
@@ -385,6 +436,16 @@
nanos = (int) (duration % NANOS_PER_MILLI);
}
}
+ // END Android-changed: Implement sleep() methods using a shared native implementation.
+ }
+
+ /**
+ * Initializes a Thread with the current AccessControlContext.
+ * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext)
+ */
+ private void init(ThreadGroup g, Runnable target, String name,
+ long stackSize) {
+ init(g, target, name, stackSize, null);
}
/**
@@ -395,25 +456,83 @@
* @param name the name of the new Thread
* @param stackSize the desired stack size for the new thread, or
* zero to indicate that this parameter is to be ignored.
+ * @param acc the AccessControlContext to inherit, or
+ * AccessController.getContext() if null
*/
- private void init(ThreadGroup g, Runnable target, String name, long stackSize) {
- Thread parent = currentThread();
- if (g == null) {
- g = parent.getThreadGroup();
+ private void init(ThreadGroup g, Runnable target, String name,
+ long stackSize, AccessControlContext acc) {
+ if (name == null) {
+ throw new NullPointerException("name cannot be null");
}
+ this.name = name;
+
+ Thread parent = currentThread();
+ // Android-removed: SecurityManager stubbed out on Android
+ // SecurityManager security = System.getSecurityManager();
+ if (g == null) {
+ // Android-changed: SecurityManager stubbed out on Android
+ /*
+ /* Determine if it's an applet or not *
+
+ /* If there is a security manager, ask the security manager
+ what to do. *
+ if (security != null) {
+ g = security.getThreadGroup();
+ }
+
+ /* If the security doesn't have a strong opinion of the matter
+ use the parent thread group. *
+ if (g == null) {
+ */
+ g = parent.getThreadGroup();
+ // }
+ }
+
+ // Android-removed: SecurityManager stubbed out on Android
+ /*
+ /* checkAccess regardless of whether or not threadgroup is
+ explicitly passed in. *
+ g.checkAccess();
+
+ /*
+ * Do we have the required permissions?
+ *
+ if (security != null) {
+ if (isCCLOverridden(getClass())) {
+ security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
+ }
+ }
+ */
+
g.addUnstarted();
+
this.group = g;
-
- this.target = target;
- this.priority = parent.getPriority();
this.daemon = parent.isDaemon();
- setName(name);
-
+ this.priority = parent.getPriority();
+ // Android-changed: Moved into init2(Thread) helper method.
+ /*
+ if (security == null || isCCLOverridden(parent.getClass()))
+ this.contextClassLoader = parent.getContextClassLoader();
+ else
+ this.contextClassLoader = parent.contextClassLoader;
+ this.inheritedAccessControlContext =
+ acc != null ? acc : AccessController.getContext();
+ */
+ this.target = target;
+ // Android-removed: The priority parameter is unchecked on Android.
+ // It is unclear why this is not being done (b/80180276).
+ // setPriority(priority);
+ // Android-changed: Moved into init2(Thread) helper method.
+ // if (parent.inheritableThreadLocals != null)
+ // this.inheritableThreadLocals =
+ // ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
init2(parent);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;
+
+ /* Set thread ID */
tid = nextThreadID();
}
@@ -457,6 +576,14 @@
}
/**
+ * Creates a new Thread that inherits the given AccessControlContext.
+ * This is not a public constructor.
+ */
+ Thread(Runnable target, AccessControlContext acc) {
+ init(null, target, "Thread-" + nextThreadNum(), 0, acc);
+ }
+
+ /**
* Allocates a new {@code Thread} object. This constructor has the same
* effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
* {@code (group, target, gname)} ,where {@code gname} is a newly generated
@@ -519,7 +646,6 @@
init(group, null, name, 0);
}
-
/** @hide */
// Android-added: Private constructor - used by the runtime.
Thread(ThreadGroup group, String name, int priority, boolean daemon) {
@@ -541,6 +667,7 @@
tid = nextThreadID();
}
+ // Android-added: Helper method for previous constructor and init(...) method.
private void init2(Thread parent) {
this.contextClassLoader = parent.getContextClassLoader();
this.inheritedAccessControlContext = AccessController.getContext();
@@ -719,8 +846,9 @@
*
* A zero status value corresponds to state "NEW".
*/
- // Android-changed: throw if 'started' is true
- if (threadStatus != 0 || started)
+ // Android-changed: Replace unused threadStatus field with started field.
+ // The threadStatus field is unused on Android.
+ if (started)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
@@ -728,8 +856,14 @@
* and the group's unstarted count can be decremented. */
group.add(this);
+ // Android-changed: Use field instead of local variable.
+ // It is necessary to remember the state of this across calls to this method so that it
+ // can throw an IllegalThreadStateException if this method is called on an already
+ // started thread.
started = false;
try {
+ // Android-changed: Use Android specific nativeCreate() method to create/start thread.
+ // start0();
nativeCreate(this, stackSize, daemon);
started = true;
} finally {
@@ -744,6 +878,11 @@
}
}
+ // Android-changed: Use Android specific nativeCreate() method to create/start thread.
+ // The upstream native method start0() only takes a reference to this object and so must obtain
+ // the stack size and daemon status directly from the field whereas Android supplies the values
+ // explicitly on the method call.
+ // private native void start0();
private native static void nativeCreate(Thread t, long stackSize, boolean daemon);
/**
@@ -784,54 +923,13 @@
uncaughtExceptionHandler = null;
}
+ // Android-changed: Throws UnsupportedOperationException.
/**
- * Forces the thread to stop executing.
- * <p>
- * If there is a security manager installed, its <code>checkAccess</code>
- * method is called with <code>this</code>
- * as its argument. This may result in a
- * <code>SecurityException</code> being raised (in the current thread).
- * <p>
- * If this thread is different from the current thread (that is, the current
- * thread is trying to stop a thread other than itself), the
- * security manager's <code>checkPermission</code> method (with a
- * <code>RuntimePermission("stopThread")</code> argument) is called in
- * addition.
- * Again, this may result in throwing a
- * <code>SecurityException</code> (in the current thread).
- * <p>
- * The thread represented by this thread is forced to stop whatever
- * it is doing abnormally and to throw a newly created
- * <code>ThreadDeath</code> object as an exception.
- * <p>
- * It is permitted to stop a thread that has not yet been started.
- * If the thread is eventually started, it immediately terminates.
- * <p>
- * An application should not normally try to catch
- * <code>ThreadDeath</code> unless it must do some extraordinary
- * cleanup operation (note that the throwing of
- * <code>ThreadDeath</code> causes <code>finally</code> clauses of
- * <code>try</code> statements to be executed before the thread
- * officially dies). If a <code>catch</code> clause catches a
- * <code>ThreadDeath</code> object, it is important to rethrow the
- * object so that the thread actually dies.
- * <p>
- * The top-level error handler that reacts to otherwise uncaught
- * exceptions does not print out a message or otherwise notify the
- * application if the uncaught exception is an instance of
- * <code>ThreadDeath</code>.
+ * Throws {@code UnsupportedOperationException}.
*
- * @exception SecurityException if the current thread cannot
- * modify this thread.
- * @see #interrupt()
- * @see #checkAccess()
- * @see #run()
- * @see #start()
- * @see ThreadDeath
- * @see ThreadGroup#uncaughtException(Thread,Throwable)
- * @see SecurityManager#checkAccess(Thread)
- * @see SecurityManager#checkPermission
- * @deprecated This method is inherently unsafe. Stopping a thread with
+ * @deprecated This method was originally designed to force a thread to stop
+ * and throw a {@code ThreadDeath} as an exception. It was inherently unsafe.
+ * Stopping a thread with
* Thread.stop causes it to unlock all of the monitors that it
* has locked (as a natural consequence of the unchecked
* <code>ThreadDeath</code> exception propagating up the stack). If
@@ -852,7 +950,24 @@
*/
@Deprecated
public final void stop() {
- stop(new ThreadDeath());
+ /*
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ checkAccess();
+ if (this != Thread.currentThread()) {
+ security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
+ }
+ }
+ // A zero status value corresponds to "NEW", it can't change to
+ // not-NEW because we hold the lock.
+ if (threadStatus != 0) {
+ resume(); // Wake up thread if it was suspended; no-op otherwise
+ }
+
+ // The VM can handle all thread states
+ stop0(new ThreadDeath());
+ */
+ throw new UnsupportedOperationException();
}
/**
@@ -870,7 +985,7 @@
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
*/
@Deprecated
- public final void stop(Throwable obj) {
+ public final synchronized void stop(Throwable obj) {
throw new UnsupportedOperationException();
}
@@ -920,12 +1035,12 @@
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
- nativeInterrupt();
+ interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
- nativeInterrupt();
+ interrupt0();
}
/**
@@ -945,6 +1060,19 @@
* @see #isInterrupted()
* @revised 6.0
*/
+ // Android-changed: Use native interrupted()/isInterrupted() methods.
+ // Upstream has one native method for both these methods that takes a boolean parameter that
+ // determines whether the interrupted status of the thread should be cleared after reading
+ // it. While that approach does allow code reuse it is less efficient/more complex than having
+ // a native implementation of each method because:
+ // * The pure Java interrupted() method requires two native calls, one to get the current
+ // thread and one to get its interrupted status.
+ // * Updating the interrupted flag is more complex than simply reading it. Knowing that only
+ // the current thread can clear the interrupted status makes the code simpler as it does not
+ // need to be concerned about multiple threads trying to clear the status simultaneously.
+ // public static boolean interrupted() {
+ // return currentThread().isInterrupted(true);
+ // }
@FastNative
public static native boolean interrupted();
@@ -961,9 +1089,24 @@
* @see #interrupted()
* @revised 6.0
*/
+ // Android-changed: Use native interrupted()/isInterrupted() methods.
+ // public boolean isInterrupted() {
+ // return isInterrupted(false);
+ // }
@FastNative
public native boolean isInterrupted();
+ // Android-removed: Use native interrupted()/isInterrupted() methods.
+ /*
+ /**
+ * Tests if some Thread has been interrupted. The interrupted state
+ * is reset or not based on the value of ClearInterrupted that is
+ * passed.
+ *
+ private native boolean isInterrupted(boolean ClearInterrupted);
+ */
+
+ // Android-changed: Throw UnsupportedOperationException instead of NoSuchMethodError.
/**
* Throws {@link UnsupportedOperationException}.
*
@@ -981,8 +1124,6 @@
* Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
* @throws UnsupportedOperationException always
*/
- // Android-changed: Throw UnsupportedOperationException instead of
- // NoSuchMethodError.
@Deprecated
public void destroy() {
throw new UnsupportedOperationException();
@@ -995,24 +1136,16 @@
* @return <code>true</code> if this thread is alive;
* <code>false</code> otherwise.
*/
+ // Android-changed: Provide pure Java implementation of isAlive().
public final boolean isAlive() {
return nativePeer != 0;
}
+ // Android-changed: Updated JavaDoc as it always throws an UnsupportedOperationException.
/**
- * Suspends this thread.
- * <p>
- * First, the <code>checkAccess</code> method of this thread is called
- * with no arguments. This may result in throwing a
- * <code>SecurityException </code>(in the current thread).
- * <p>
- * If the thread is alive, it is suspended and makes no further
- * progress unless and until it is resumed.
+ * Throws {@link UnsupportedOperationException}.
*
- * @exception SecurityException if the current thread cannot modify
- * this thread.
- * @see #checkAccess
- * @deprecated This method has been deprecated, as it is
+ * @deprecated This method was designed to suspend the Thread but it was
* inherently deadlock-prone. If the target thread holds a lock on the
* monitor protecting a critical system resource when it is suspended, no
* thread can access this resource until the target thread is resumed. If
@@ -1022,34 +1155,33 @@
* For more information, see
* <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+ * @throws UnsupportedOperationException always
*/
@Deprecated
public final void suspend() {
+ // Android-changed: Unsupported on Android.
+ // checkAccess();
+ // suspend0();
+
throw new UnsupportedOperationException();
}
+ // Android-changed: Updated JavaDoc as it always throws an UnsupportedOperationException.
/**
- * Resumes a suspended thread.
- * <p>
- * First, the <code>checkAccess</code> method of this thread is called
- * with no arguments. This may result in throwing a
- * <code>SecurityException</code> (in the current thread).
- * <p>
- * If the thread is alive but suspended, it is resumed and is
- * permitted to make progress in its execution.
+ * Throws {@link UnsupportedOperationException}.
*
- * @exception SecurityException if the current thread cannot modify this
- * thread.
- * @see #checkAccess
- * @see #suspend()
* @deprecated This method exists solely for use with {@link #suspend},
* which has been deprecated because it is deadlock-prone.
* For more information, see
* <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+ * @throws UnsupportedOperationException always
*/
@Deprecated
public final void resume() {
+ // Android-changed: Unsupported on Android.
+ // checkAccess();
+ // resume0();
throw new UnsupportedOperationException();
}
@@ -1081,18 +1213,19 @@
ThreadGroup g;
checkAccess();
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
- // Android-changed: Improve exception message when the new priority
- // is out of bounds.
+ // Android-changed: Improve exception message when the new priority is out of bounds.
throw new IllegalArgumentException("Priority out of range: " + newPriority);
}
if((g = getThreadGroup()) != null) {
if (newPriority > g.getMaxPriority()) {
newPriority = g.getMaxPriority();
}
+ // Android-changed: Avoid native call if Thread is not yet started.
+ // setPriority0(priority = newPriority);
synchronized(this) {
this.priority = newPriority;
if (isAlive()) {
- nativeSetPriority(newPriority);
+ setPriority0(newPriority);
}
}
}
@@ -1122,17 +1255,18 @@
* @see #getName
* @see #checkAccess()
*/
- public final void setName(String name) {
+ public final synchronized void setName(String name) {
checkAccess();
if (name == null) {
- throw new NullPointerException("name == null");
+ throw new NullPointerException("name cannot be null");
}
- synchronized (this) {
- this.name = name;
- if (isAlive()) {
- nativeSetName(name);
- }
+ this.name = name;
+ // Android-changed: Use isAlive() not threadStatus to check whether Thread has started.
+ // The threadStatus field is not used in Android.
+ // if (threadStatus != 0) {
+ if (isAlive()) {
+ setNativeName(name);
}
}
@@ -1154,10 +1288,15 @@
* @return this thread's thread group.
*/
public final ThreadGroup getThreadGroup() {
- // Android-changed: Return null if the thread is terminated.
+ // BEGIN Android-added: Work around exit() not being called.
+ // Android runtime does not call exit() when a Thread exits so the group field is not
+ // set to null so it needs to pretend as if it did. If we are not going to call exit()
+ // then this should probably just check isAlive() here rather than getState() as the
+ // latter requires a native call.
if (getState() == Thread.State.TERMINATED) {
return null;
}
+ // END Android-added: Work around exit() not being called.
return group;
}
@@ -1223,6 +1362,8 @@
* were never well-defined.
*/
@Deprecated
+ // Android-changed: Provide non-native implementation of countStackFrames().
+ // public native int countStackFrames();
public int countStackFrames() {
return getStackTrace().length;
}
@@ -1248,7 +1389,10 @@
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
- public final void join(long millis) throws InterruptedException {
+ // BEGIN Android-changed: Synchronize on separate lock object not this Thread.
+ // public final synchronized void join(long millis)
+ public final void join(long millis)
+ throws InterruptedException {
synchronized(lock) {
long base = System.currentTimeMillis();
long now = 0;
@@ -1273,6 +1417,7 @@
}
}
}
+ // END Android-changed: Synchronize on separate lock object not this Thread.
/**
* Waits at most {@code millis} milliseconds plus
@@ -1299,8 +1444,11 @@
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
+ // BEGIN Android-changed: Synchronize on separate lock object not this Thread.
+ // public final synchronized void join(long millis, int nanos)
public final void join(long millis, int nanos)
throws InterruptedException {
+
synchronized(lock) {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
@@ -1318,6 +1466,7 @@
join(millis);
}
}
+ // END Android-changed: Synchronize on separate lock object not this Thread.
/**
* Waits for this thread to die.
@@ -1397,6 +1546,11 @@
* @see SecurityManager#checkAccess(Thread)
*/
public final void checkAccess() {
+ // Android-removed: SecurityManager stubbed out on Android
+ // SecurityManager security = System.getSecurityManager();
+ // if (security != null) {
+ // security.checkAccess(this);
+ // }
}
/**
@@ -1444,6 +1598,16 @@
*/
@CallerSensitive
public ClassLoader getContextClassLoader() {
+ // Android-removed: SecurityManager stubbed out on Android
+ /*
+ if (contextClassLoader == null)
+ return null;
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ ClassLoader.checkClassLoaderPermission(contextClassLoader,
+ Reflection.getCallerClass());
+ }
+ */
return contextClassLoader;
}
@@ -1470,6 +1634,11 @@
* @since 1.2
*/
public void setContextClassLoader(ClassLoader cl) {
+ // Android-removed: SecurityManager stubbed out on Android
+ // SecurityManager sm = System.getSecurityManager();
+ // if (sm != null) {
+ // sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+ // }
contextClassLoader = cl;
}
@@ -1489,11 +1658,7 @@
* the specified object.
* @since 1.4
*/
- public static boolean holdsLock(Object obj) {
- return currentThread().nativeHoldsLock(obj);
- }
-
- private native boolean nativeHoldsLock(Object object);
+ public static native boolean holdsLock(Object obj);
private static final StackTraceElement[] EMPTY_STACK_TRACE
= new StackTraceElement[0];
@@ -1535,6 +1700,7 @@
* @since 1.5
*/
public StackTraceElement[] getStackTrace() {
+ // Android-changed: Use native VMStack to get stack trace.
StackTraceElement ste[] = VMStack.getThreadStackTrace(this);
return ste != null ? ste : EmptyArray.STACK_TRACE_ELEMENT;
}
@@ -1575,20 +1741,47 @@
* @since 1.5
*/
public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
- Map<Thread, StackTraceElement[]> map = new HashMap<Thread, StackTraceElement[]>();
+ // Android-removed: SecurityManager stubbed out on Android
+ /*
+ // check for getStackTrace permission
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkPermission(
+ SecurityConstants.GET_STACK_TRACE_PERMISSION);
+ security.checkPermission(
+ SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
+ }
+ */
- // Find out how many live threads we have. Allocate a bit more
- // space than needed, in case new ones are just being created.
+ // Get a snapshot of the list of all threads
+ // BEGIN Android-changed: Use ThreadGroup and getStackTrace() instead of native methods.
+ // Allocate a bit more space than needed, in case new ones are just being created.
+ /*
+ Thread[] threads = getThreads();
+ StackTraceElement[][] traces = dumpThreads(threads);
+ Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
+ for (int i = 0; i < threads.length; i++) {
+ StackTraceElement[] stackTrace = traces[i];
+ if (stackTrace != null) {
+ m.put(threads[i], stackTrace);
+ }
+ // else terminated so we don't put it in the map
+ }
+ */
int count = ThreadGroup.systemThreadGroup.activeCount();
Thread[] threads = new Thread[count + count / 2];
- // Enumerate the threads and collect the stacktraces.
+ // Enumerate the threads.
count = ThreadGroup.systemThreadGroup.enumerate(threads);
- for (int i = 0; i < count; i++) {
- map.put(threads[i], threads[i].getStackTrace());
- }
- return map;
+ // Collect the stacktraces
+ Map<Thread, StackTraceElement[]> m = new HashMap<Thread, StackTraceElement[]>();
+ for (int i = 0; i < count; i++) {
+ StackTraceElement[] stackTrace = threads[i].getStackTrace();
+ m.put(threads[i], stackTrace);
+ }
+ // END Android-changed: Use ThreadGroup and getStackTrace() instead of native methods.
+ return m;
}
@@ -1661,6 +1854,10 @@
return result.booleanValue();
}
+ // Android-removed: Native methods that are unused on Android.
+ // private native static StackTraceElement[][] dumpThreads(Thread[] threads);
+ // private native static Thread[] getThreads();
+
/**
* Returns the identifier of this Thread. The thread ID is a positive
* <tt>long</tt> number generated when this thread was created.
@@ -1783,6 +1980,10 @@
*/
public State getState() {
// get current thread state
+ // Android-changed: Replace unused threadStatus field with started field.
+ // Use Android specific nativeGetStatus() method. See comment on started field for more
+ // information.
+ // return sun.misc.VM.toThreadState(threadStatus);
return State.values()[nativeGetStatus(started)];
}
@@ -1864,6 +2065,16 @@
* @since 1.5
*/
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
+ // Android-removed: SecurityManager stubbed out on Android
+ /*
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(
+ new RuntimePermission("setDefaultUncaughtExceptionHandler")
+ );
+ }
+ */
+
defaultUncaughtExceptionHandler = eh;
}
@@ -1879,7 +2090,8 @@
return defaultUncaughtExceptionHandler;
}
- // Android-changed: Added concept of an uncaughtExceptionPreHandler for use by platform.
+ // BEGIN Android-added: uncaughtExceptionPreHandler for use by platform.
+ // See http://b/29624607 for background information.
// null unless explicitly set
private static volatile UncaughtExceptionHandler uncaughtExceptionPreHandler;
@@ -1890,7 +2102,8 @@
* throwables thrown by the handler will be ignored by
* {@link #dispatchUncaughtException(Throwable)}.
*
- * @hide only for use by the Android framework (RuntimeInit) b/29624607
+ * @hide used when configuring the runtime for exception logging; see
+ * {@link dalvik.system.RuntimeHooks} b/29624607
*/
public static void setUncaughtExceptionPreHandler(UncaughtExceptionHandler eh) {
uncaughtExceptionPreHandler = eh;
@@ -1900,6 +2113,7 @@
public static UncaughtExceptionHandler getUncaughtExceptionPreHandler() {
return uncaughtExceptionPreHandler;
}
+ // END Android-added: uncaughtExceptionPreHandler for use by platform.
/**
* Returns the handler invoked when this thread abruptly terminates
@@ -1941,8 +2155,9 @@
*
* @hide
*/
- // @VisibleForTesting (would be package-private if not for tests)
+ // Android-changed: Make dispatchUncaughtException() public, for use by tests.
public final void dispatchUncaughtException(Throwable e) {
+ // BEGIN Android-added: uncaughtExceptionPreHandler for use by platform.
Thread.UncaughtExceptionHandler initialUeh =
Thread.getUncaughtExceptionPreHandler();
if (initialUeh != null) {
@@ -1952,6 +2167,7 @@
// Throwables thrown by the initial handler are ignored
}
}
+ // END Android-added: uncaughtExceptionPreHandler for use by platform.
getUncaughtExceptionHandler().uncaughtException(this, e);
}
@@ -2024,6 +2240,7 @@
// concurrent code, and we can not risk accidental false sharing.
// Hence, the fields are isolated with @Contended.
+ // BEGIN Android-changed: @sun.misc.Contended is not supported on Android.
/** The current seed for a ThreadLocalRandom */
// @sun.misc.Contended("tlr")
long threadLocalRandomSeed;
@@ -2035,17 +2252,27 @@
/** Secondary seed isolated from public ThreadLocalRandom sequence */
// @sun.misc.Contended("tlr")
int threadLocalRandomSecondarySeed;
+ // END Android-changed: @sun.misc.Contended is not supported on Android.
/* Some private helper methods */
- private native void nativeSetName(String newName);
+ private native void setPriority0(int newPriority);
- private native void nativeSetPriority(int newPriority);
-
- private native int nativeGetStatus(boolean hasBeenStarted);
+ // BEGIN Android-removed: Native methods that are unused on Android.
+ /*
+ private native void stop0(Object o);
+ private native void suspend0();
+ private native void resume0();
+ */
+ // END Android-removed: Native methods that are unused on Android.
@FastNative
- private native void nativeInterrupt();
+ private native void interrupt0();
+ private native void setNativeName(String name);
+ // Android-added: Android specific nativeGetStatus() method.
+ private native int nativeGetStatus(boolean hasBeenStarted);
+
+ // BEGIN Android-added: Support for parking threads, used by Unsafe.park()/unpark().
/** Park states */
private static class ParkState {
/** park state indicating unparked */
@@ -2209,4 +2436,5 @@
}
}
}
+ // END Android-added: Support for parking threads, used by Unsafe.park()/unpark().
}
diff --git a/ojluni/src/main/java/java/lang/ThreadGroup.java b/ojluni/src/main/java/java/lang/ThreadGroup.java
index 521c3c3..292b536 100644
--- a/ojluni/src/main/java/java/lang/ThreadGroup.java
+++ b/ojluni/src/main/java/java/lang/ThreadGroup.java
@@ -261,14 +261,13 @@
* @see java.lang.ThreadGroup#checkAccess()
* @since JDK1.0
*/
- // Android-changed: We clamp the priority to the range [MIN_PRIORITY, MAX_PRIORITY]
- // before using it.
public final void setMaxPriority(int pri) {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
checkAccess();
- // Android-changed: Clamp to MIN_PRIORITY, MAX_PRIORITY.
+ // BEGIN Android-changed: Clamp to the range [MIN_PRIORITY, MAX_PRIORITY].
+ // This preserves backward compatibility with previous versions of Android.
// if (pri < Thread.MIN_PRIORITY || pri > Thread.MAX_PRIORITY) {
// return;
// }
@@ -278,6 +277,7 @@
if (pri > Thread.MAX_PRIORITY) {
pri = Thread.MAX_PRIORITY;
}
+ // END Android-changed: Clamp to the range [MIN_PRIORITY, MAX_PRIORITY].
maxPriority = (parent != null) ? Math.min(pri, parent.maxPriority) : pri;
ngroupsSnapshot = ngroups;
@@ -325,6 +325,11 @@
* @since JDK1.0
*/
public final void checkAccess() {
+ // Android-removed: SecurityManager stubbed out on Android.
+ // SecurityManager security = System.getSecurityManager();
+ // if (security != null) {
+ // security.checkAccess(this);
+ // }
}
/**
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandle.java b/ojluni/src/main/java/java/lang/invoke/MethodHandle.java
index cd09322..13d719b 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodHandle.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandle.java
@@ -419,18 +419,8 @@
* @author John Rose, JSR 292 EG
*/
public abstract class MethodHandle {
- // Android-changed:
- //
+ // Android-removed: MethodHandleImpl.initStatics() unused on Android.
// static { MethodHandleImpl.initStatics(); }
- //
- // LambdaForm and customizationCount are currently unused in our implementation
- // and will be substituted with appropriate implementation / delegate classes.
- //
- // /*private*/ final LambdaForm form;
- // form is not private so that invokers can easily fetch it
- // /*non-public*/ byte customizationCount;
- // customizationCount should be accessible from invokers
-
/**
* Internal marker interface which distinguishes (to the Java compiler)
@@ -440,14 +430,32 @@
*/
@java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
+ // Android-changed: Made public @hide as otherwise it breaks the stubs generation.
+ // @interface PolymorphicSignature { }
public @interface PolymorphicSignature { }
+ // Android-added: Comment to differentiate between type and nominalType.
/**
* The type of this method handle, this corresponds to the exact type of the method
* being invoked.
+ *
+ * @see #nominalType
*/
private final MethodType type;
+ // Android-removed: LambdaForm and customizationCount unused on Android.
+ // They will be substituted with appropriate implementation / delegate classes.
+ /*
+ /*private* final LambdaForm form;
+ // form is not private so that invokers can easily fetch it
+ /*private* MethodHandle asTypeCache;
+ // asTypeCache is not private so that invokers can easily fetch it
+ /*non-public* byte customizationCount;
+ // customizationCount should be accessible from invokers
+ */
+ // BEGIN Android-added: Android specific implementation.
+ // The MethodHandle functionality is tightly coupled with internal details of the runtime and
+ // so Android has a completely different implementation compared to the RI.
/**
* The nominal type of this method handle, will be non-null if a method handle declares
* a different type from its "real" type, which is either the type of the method being invoked
@@ -506,6 +514,7 @@
this.handleKind = handleKind;
this.type = type;
}
+ // END Android-added: Android specific implementation.
/**
* Reports the type of this method handle.
@@ -513,6 +522,7 @@
* @return the method handle type
*/
public MethodType type() {
+ // Android-added: Added nominalType field.
if (nominalType != null) {
return nominalType;
}
@@ -520,6 +530,25 @@
return type;
}
+ // BEGIN Android-removed: LambdaForm unsupported on Android.
+ /*
+ /**
+ * Package-private constructor for the method handle implementation hierarchy.
+ * Method handle inheritance will be contained completely within
+ * the {@code java.lang.invoke} package.
+ *
+ // @param type type (permanently assigned) of the new method handle
+ /*non-public* MethodHandle(MethodType type, LambdaForm form) {
+ type.getClass(); // explicit NPE
+ form.getClass(); // explicit NPE
+ this.type = type;
+ this.form = form.uncustomize();
+
+ this.form.prepare(); // TO DO: Try to delay this step until just before invocation.
+ }
+ */
+ // END Android-removed: LambdaForm unsupported on Android.
+
/**
* Invokes the method handle, allowing any caller type descriptor, but requiring an exact type match.
* The symbolic type descriptor at the call site of {@code invokeExact} must
@@ -576,13 +605,64 @@
*/
public final native @PolymorphicSignature Object invoke(Object... args) throws Throwable;
- // Android-changed: Removed implementation details.
- //
- // /*non-public*/ final native @PolymorphicSignature Object invokeBasic(Object... args)
- // /*non-public*/ static native @PolymorphicSignature Object linkToVirtual(Object... args)
- // /*non-public*/ static native @PolymorphicSignature Object linkToStatic(Object... args)
- // /*non-public*/ static native @PolymorphicSignature Object linkToSpecial(Object... args)
- // /*non-public*/ static native @PolymorphicSignature Object linkToInterface(Object... args)
+ // BEGIN Android-removed: RI implementation unused on Android.
+ /*
+ /**
+ * Private method for trusted invocation of a method handle respecting simplified signatures.
+ * Type mismatches will not throw {@code WrongMethodTypeException}, but could crash the JVM.
+ * <p>
+ * The caller signature is restricted to the following basic types:
+ * Object, int, long, float, double, and void return.
+ * <p>
+ * The caller is responsible for maintaining type correctness by ensuring
+ * that the each outgoing argument value is a member of the range of the corresponding
+ * callee argument type.
+ * (The caller should therefore issue appropriate casts and integer narrowing
+ * operations on outgoing argument values.)
+ * The caller can assume that the incoming result value is part of the range
+ * of the callee's return type.
+ * @param args the signature-polymorphic parameter list, statically represented using varargs
+ * @return the signature-polymorphic result, statically represented using {@code Object}
+ *
+ /*non-public* final native @PolymorphicSignature Object invokeBasic(Object... args) throws Throwable;
+
+ /**
+ * Private method for trusted invocation of a MemberName of kind {@code REF_invokeVirtual}.
+ * The caller signature is restricted to basic types as with {@code invokeBasic}.
+ * The trailing (not leading) argument must be a MemberName.
+ * @param args the signature-polymorphic parameter list, statically represented using varargs
+ * @return the signature-polymorphic result, statically represented using {@code Object}
+ *
+ /*non-public* static native @PolymorphicSignature Object linkToVirtual(Object... args) throws Throwable;
+
+ /**
+ * Private method for trusted invocation of a MemberName of kind {@code REF_invokeStatic}.
+ * The caller signature is restricted to basic types as with {@code invokeBasic}.
+ * The trailing (not leading) argument must be a MemberName.
+ * @param args the signature-polymorphic parameter list, statically represented using varargs
+ * @return the signature-polymorphic result, statically represented using {@code Object}
+ *
+ /*non-public* static native @PolymorphicSignature Object linkToStatic(Object... args) throws Throwable;
+
+ /**
+ * Private method for trusted invocation of a MemberName of kind {@code REF_invokeSpecial}.
+ * The caller signature is restricted to basic types as with {@code invokeBasic}.
+ * The trailing (not leading) argument must be a MemberName.
+ * @param args the signature-polymorphic parameter list, statically represented using varargs
+ * @return the signature-polymorphic result, statically represented using {@code Object}
+ *
+ /*non-public* static native @PolymorphicSignature Object linkToSpecial(Object... args) throws Throwable;
+
+ /**
+ * Private method for trusted invocation of a MemberName of kind {@code REF_invokeInterface}.
+ * The caller signature is restricted to basic types as with {@code invokeBasic}.
+ * The trailing (not leading) argument must be a MemberName.
+ * @param args the signature-polymorphic parameter list, statically represented using varargs
+ * @return the signature-polymorphic result, statically represented using {@code Object}
+ *
+ /*non-public* static native @PolymorphicSignature Object linkToInterface(Object... args) throws Throwable;
+ */
+ // END Android-removed: RI implementation unused on Android.
/**
* Performs a variable arity invocation, passing the arguments in the given list
@@ -635,6 +715,9 @@
* @see MethodHandles#spreadInvoker
*/
public Object invokeWithArguments(Object... arguments) throws Throwable {
+ // BEGIN Android-changed: Android specific implementation.
+ // MethodType invocationType = MethodType.genericMethodType(arguments == null ? 0 : arguments.length);
+ // return invocationType.invokers().spreadInvoker(0).invokeExact(asType(invocationType), arguments);
MethodHandle invoker = null;
synchronized (this) {
if (cachedSpreadInvoker == null) {
@@ -645,6 +728,7 @@
}
return invoker.invoke(this, arguments);
+ // END Android-changed: Android specific implementation.
}
/**
@@ -773,14 +857,38 @@
if (newType == type) {
return this;
}
-
- if (!type.isConvertibleTo(newType)) {
- throw new WrongMethodTypeException("cannot convert " + this + " to " + newType);
+ // Android-removed: Type conversion memoizing is unsupported on Android.
+ /*
+ // Return 'this.asTypeCache' if the conversion is already memoized.
+ MethodHandle atc = asTypeCached(newType);
+ if (atc != null) {
+ return atc;
}
+ */
+ return asTypeUncached(newType);
+ }
+ // Android-removed: Type conversion memoizing is unsupported on Android.
+ /*
+ private MethodHandle asTypeCached(MethodType newType) {
+ MethodHandle atc = asTypeCache;
+ if (atc != null && newType == atc.type) {
+ return atc;
+ }
+ return null;
+ }
+ */
+
+ /** Override this to change asType behavior. */
+ /*non-public*/ MethodHandle asTypeUncached(MethodType newType) {
+ if (!type.isConvertibleTo(newType))
+ throw new WrongMethodTypeException("cannot convert "+this+" to "+newType);
+ // BEGIN Android-changed: Android specific implementation.
+ // return asTypeCache = MethodHandleImpl.makePairwiseConvert(this, newType, true);
MethodHandle mh = duplicate();
mh.nominalType = newType;
return mh;
+ // END Android-changed: Android specific implementation.
}
/**
@@ -874,13 +982,23 @@
*/
public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
MethodType postSpreadType = asSpreaderChecks(arrayType, arrayLength);
-
+ // BEGIN Android-changed: Android specific implementation.
+ /*
+ int arity = type().parameterCount();
+ int spreadArgPos = arity - arrayLength;
+ MethodHandle afterSpread = this.asType(postSpreadType);
+ BoundMethodHandle mh = afterSpread.rebind();
+ LambdaForm lform = mh.editor().spreadArgumentsForm(1 + spreadArgPos, arrayType, arrayLength);
+ MethodType preSpreadType = postSpreadType.replaceParameterTypes(spreadArgPos, arity, arrayType);
+ return mh.copyWith(preSpreadType, lform);
+ */
final int targetParamCount = postSpreadType.parameterCount();
MethodType dropArrayArgs = postSpreadType.dropParameterTypes(
(targetParamCount - arrayLength), targetParamCount);
MethodType adapterType = dropArrayArgs.appendParameterTypes(arrayType);
return new Transformers.Spreader(this, adapterType, arrayLength);
+ // END Android-changed: Android specific implementation.
}
/**
@@ -1000,8 +1118,21 @@
*/
public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
asCollectorChecks(arrayType, arrayLength);
-
+ // BEGIN Android-changed: Android specific implementation.
+ /*
+ int collectArgPos = type().parameterCount() - 1;
+ BoundMethodHandle mh = rebind();
+ MethodType resultType = type().asCollectorType(arrayType, arrayLength);
+ MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
+ LambdaForm lform = mh.editor().collectArgumentArrayForm(1 + collectArgPos, newArray);
+ if (lform != null) {
+ return mh.copyWith(resultType, lform);
+ }
+ lform = mh.editor().collectArgumentsForm(1 + collectArgPos, newArray.type().basicType());
+ return mh.copyWithExtendL(resultType, lform, newArray);
+ */
return new Transformers.Collector(this, arrayType, arrayLength);
+ // END Android-changed: Android specific implementation.
}
/**
@@ -1174,7 +1305,8 @@
boolean lastMatch = asCollectorChecks(arrayType, 0);
if (isVarargsCollector() && lastMatch)
return this;
-
+ // Android-changed: Android specific implementation.
+ // return MethodHandleImpl.makeVarargsCollector(this, arrayType);
return new Transformers.VarargsCollector(this);
}
@@ -1241,13 +1373,17 @@
* @see #isVarargsCollector
*/
public MethodHandle asFixedArity() {
- // Android-changed: implementation specific.
+ // BEGIN Android-changed: Android specific implementation.
+ // assert(!isVarargsCollector());
+ // return this;
+
MethodHandle mh = this;
if (mh.isVarargsCollector()) {
mh = ((Transformers.VarargsCollector) mh).asFixedArity();
}
assert(!mh.isVarargsCollector());
return mh;
+ // END Android-changed: Android specific implementation.
}
/**
@@ -1279,7 +1415,8 @@
*/
public MethodHandle bindTo(Object x) {
x = type.leadingReferenceParameter().cast(x); // throw CCE if needed
-
+ // Android-changed: Android specific implementation.
+ // return bindArgumentL(0, x);
return new Transformers.BindTo(this, x);
}
@@ -1300,10 +1437,26 @@
*/
@Override
public String toString() {
- // Android-changed: Removed debugging support.
+ // Android-removed: Debugging support unused on Android.
+ // if (DEBUG_METHOD_HANDLE_NAMES) return "MethodHandle"+debugString();
+ return standardString();
+ }
+ String standardString() {
return "MethodHandle"+type;
}
+ // BEGIN Android-removed: Debugging support unused on Android.
+ /*
+ /** Return a string with a several lines describing the method handle structure.
+ * This string would be suitable for display in an IDE debugger.
+ *
+ String debugString() {
+ return type+" : "+internalForm()+internalProperties();
+ }
+ */
+ // END Android-removed: Debugging support unused on Android.
+
+ // BEGIN Android-added: Android specific implementation.
/** @hide */
public int getHandleKind() {
return handleKind;
@@ -1327,7 +1480,6 @@
}
}
-
/**
* This is the entry point for all transform calls, and dispatches to the protected
* transform method. This layer of indirection exists purely for convenience, because
@@ -1339,41 +1491,156 @@
private void transformInternal(EmulatedStackFrame arguments) throws Throwable {
transform(arguments);
}
+ // END Android-added: Android specific implementation.
- // Android-changed: Removed implementation details :
- //
- // String standardString();
- // String debugString();
- //
+ // BEGIN Android-removed: RI implementation unused on Android.
+ /*
//// Implementation methods.
//// Sub-classes can override these default implementations.
//// All these methods assume arguments are already validated.
- //
+
// Other transforms to do: convert, explicitCast, permute, drop, filter, fold, GWT, catch
- //
- // BoundMethodHandle bindArgumentL(int pos, Object value);
- // /*non-public*/ MethodHandle setVarargs(MemberName member);
- // /*non-public*/ MethodHandle viewAsType(MethodType newType, boolean strict);
- // /*non-public*/ boolean viewAsTypeChecks(MethodType newType, boolean strict);
- //
+
+ BoundMethodHandle bindArgumentL(int pos, Object value) {
+ return rebind().bindArgumentL(pos, value);
+ }
+
+ /*non-public*
+ MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
+ if (!member.isVarargs()) return this;
+ Class<?> arrayType = type().lastParameterType();
+ if (arrayType.isArray()) {
+ return MethodHandleImpl.makeVarargsCollector(this, arrayType);
+ }
+ throw member.makeAccessException("cannot make variable arity", null);
+ }
+
+ /*non-public*
+ MethodHandle viewAsType(MethodType newType, boolean strict) {
+ // No actual conversions, just a new view of the same method.
+ // Note that this operation must not produce a DirectMethodHandle,
+ // because retyped DMHs, like any transformed MHs,
+ // cannot be cracked into MethodHandleInfo.
+ assert viewAsTypeChecks(newType, strict);
+ BoundMethodHandle mh = rebind();
+ assert(!((MethodHandle)mh instanceof DirectMethodHandle));
+ return mh.copyWith(newType, mh.form);
+ }
+
+ /*non-public*
+ boolean viewAsTypeChecks(MethodType newType, boolean strict) {
+ if (strict) {
+ assert(type().isViewableAs(newType, true))
+ : Arrays.asList(this, newType);
+ } else {
+ assert(type().basicType().isViewableAs(newType.basicType(), true))
+ : Arrays.asList(this, newType);
+ }
+ return true;
+ }
+
// Decoding
- //
- // /*non-public*/ LambdaForm internalForm();
- // /*non-public*/ MemberName internalMemberName();
- // /*non-public*/ Class<?> internalCallerClass();
- // /*non-public*/ MethodHandleImpl.Intrinsic intrinsicName();
- // /*non-public*/ MethodHandle withInternalMemberName(MemberName member, boolean isInvokeSpecial);
- // /*non-public*/ boolean isInvokeSpecial();
- // /*non-public*/ Object internalValues();
- // /*non-public*/ Object internalProperties();
- //
+
+ /*non-public*
+ LambdaForm internalForm() {
+ return form;
+ }
+
+ /*non-public*
+ MemberName internalMemberName() {
+ return null; // DMH returns DMH.member
+ }
+
+ /*non-public*
+ Class<?> internalCallerClass() {
+ return null; // caller-bound MH for @CallerSensitive method returns caller
+ }
+
+ /*non-public*
+ MethodHandleImpl.Intrinsic intrinsicName() {
+ // no special intrinsic meaning to most MHs
+ return MethodHandleImpl.Intrinsic.NONE;
+ }
+
+ /*non-public*
+ MethodHandle withInternalMemberName(MemberName member, boolean isInvokeSpecial) {
+ if (member != null) {
+ return MethodHandleImpl.makeWrappedMember(this, member, isInvokeSpecial);
+ } else if (internalMemberName() == null) {
+ // The required internaMemberName is null, and this MH (like most) doesn't have one.
+ return this;
+ } else {
+ // The following case is rare. Mask the internalMemberName by wrapping the MH in a BMH.
+ MethodHandle result = rebind();
+ assert (result.internalMemberName() == null);
+ return result;
+ }
+ }
+
+ /*non-public*
+ boolean isInvokeSpecial() {
+ return false; // DMH.Special returns true
+ }
+
+ /*non-public*
+ Object internalValues() {
+ return null;
+ }
+
+ /*non-public*
+ Object internalProperties() {
+ // Override to something to follow this.form, like "\n& FOO=bar"
+ return "";
+ }
+
//// Method handle implementation methods.
//// Sub-classes can override these default implementations.
//// All these methods assume arguments are already validated.
- //
- // /*non-public*/ abstract MethodHandle copyWith(MethodType mt, LambdaForm lf);
- // abstract BoundMethodHandle rebind();
- // /*non-public*/ void updateForm(LambdaForm newForm);
- // /*non-public*/ void customize();
- // private static final long FORM_OFFSET;
+
+ /*non-public*
+ abstract MethodHandle copyWith(MethodType mt, LambdaForm lf);
+
+ /** Require this method handle to be a BMH, or else replace it with a "wrapper" BMH.
+ * Many transforms are implemented only for BMHs.
+ * @return a behaviorally equivalent BMH
+ *
+ abstract BoundMethodHandle rebind();
+
+ /**
+ * Replace the old lambda form of this method handle with a new one.
+ * The new one must be functionally equivalent to the old one.
+ * Threads may continue running the old form indefinitely,
+ * but it is likely that the new one will be preferred for new executions.
+ * Use with discretion.
+ *
+ /*non-public*
+ void updateForm(LambdaForm newForm) {
+ assert(newForm.customized == null || newForm.customized == this);
+ if (form == newForm) return;
+ newForm.prepare(); // as in MethodHandle.<init>
+ UNSAFE.putObject(this, FORM_OFFSET, newForm);
+ UNSAFE.fullFence();
+ }
+
+ /** Craft a LambdaForm customized for this particular MethodHandle *
+ /*non-public*
+ void customize() {
+ if (form.customized == null) {
+ LambdaForm newForm = form.customize(this);
+ updateForm(newForm);
+ } else {
+ assert(form.customized == this);
+ }
+ }
+
+ private static final long FORM_OFFSET;
+ static {
+ try {
+ FORM_OFFSET = UNSAFE.objectFieldOffset(MethodHandle.class.getDeclaredField("form"));
+ } catch (ReflectiveOperationException ex) {
+ throw newInternalError(ex);
+ }
+ }
+ */
+ // END Android-removed: RI implementation unused on Android.
}
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandleImpl.java b/ojluni/src/main/java/java/lang/invoke/MethodHandleImpl.java
index b037716..6514cb6 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodHandleImpl.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandleImpl.java
@@ -1,11 +1,12 @@
/*
- * Copyright 2016 Google Inc.
+ * Copyright (C) 2016 The Android Open Source Project
*
* 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. Google designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Google in the LICENSE file that accompanied this code.
+ * published by the Free Software Foundation. The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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
@@ -25,6 +26,10 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+// Android-changed: Android specific implementation.
+// The whole class was implemented from scratch for the Android runtime based
+// on the specification of the MethodHandle class.
+// The code does not originate from upstream OpenJDK.
/**
* A method handle that's directly associated with an ArtField or an ArtMethod and
* specifies no additional transformations.
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandleInfo.java b/ojluni/src/main/java/java/lang/invoke/MethodHandleInfo.java
index e24bc68..2746d4a 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodHandleInfo.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandleInfo.java
@@ -27,6 +27,7 @@
import java.lang.reflect.*;
import java.util.*;
+import java.lang.invoke.MethodHandleNatives.Constants;
import java.lang.invoke.MethodHandles.Lookup;
import static java.lang.invoke.MethodHandleStatics.*;
@@ -127,17 +128,16 @@
* A direct method handle reference kind,
* as defined in the <a href="MethodHandleInfo.html#refkinds">table above</a>.
*/
- // Android-changed: Inlined the values of these constants from MethodHandleNatives.Constants.
public static final int
- REF_getField = 1,
- REF_getStatic = 2,
- REF_putField = 3,
- REF_putStatic = 4,
- REF_invokeVirtual = 5,
- REF_invokeStatic = 6,
- REF_invokeSpecial = 7,
- REF_newInvokeSpecial = 8,
- REF_invokeInterface = 9;
+ REF_getField = Constants.REF_getField,
+ REF_getStatic = Constants.REF_getStatic,
+ REF_putField = Constants.REF_putField,
+ REF_putStatic = Constants.REF_putStatic,
+ REF_invokeVirtual = Constants.REF_invokeVirtual,
+ REF_invokeStatic = Constants.REF_invokeStatic,
+ REF_invokeSpecial = Constants.REF_invokeSpecial,
+ REF_newInvokeSpecial = Constants.REF_newInvokeSpecial,
+ REF_invokeInterface = Constants.REF_invokeInterface;
/**
* Returns the reference kind of the cracked method handle, which in turn
@@ -224,13 +224,11 @@
// spelling derived from java.lang.reflect.Executable, not MethodHandle.isVarargsCollector
public default boolean isVarArgs() {
// fields are never varargs:
- if (refKindIsField(getReferenceKind()))
+ if (MethodHandleNatives.refKindIsField((byte) getReferenceKind()))
return false;
// not in the public API: Modifier.VARARGS
final int ACC_VARARGS = 0x00000080; // from JVMS 4.6 (Table 4.20)
-
- // Android-changed: Removed assert() due to http://b/30862573
- // assert(ACC_VARARGS == Modifier.TRANSIENT);
+ assert(ACC_VARARGS == Modifier.TRANSIENT);
return Modifier.isTransient(getModifiers());
}
@@ -244,9 +242,9 @@
* <a href="MethodHandleInfo.html#refkinds">reference kind number</a>
*/
public static String referenceKindToString(int referenceKind) {
- if (!refKindIsValid(referenceKind))
+ if (!MethodHandleNatives.refKindIsValid(referenceKind))
throw newIllegalArgumentException("invalid reference kind", referenceKind);
- return refKindName(referenceKind);
+ return MethodHandleNatives.refKindName((byte)referenceKind);
}
/**
@@ -284,31 +282,22 @@
return String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type);
}
- // Android-changed: Inlined from MethodHandleNatives and changed to avoid references to
- // REF_NONE and REF_LIMITED
+ // BEGIN Android-added: refKind...() methods needed for API compatibility with 26.
+ // These methods were accidentally added into the public API in API level 26 and so cannot be
+ // removed.
static boolean refKindIsValid(int refKind) {
- return (refKind >= REF_getField && refKind <= REF_invokeInterface);
+ return MethodHandleNatives.refKindIsValid(refKind);
}
// Android-changed: Inlined from MethodHandleNatives.
static boolean refKindIsField(int refKind) {
- return (refKind <= REF_putStatic);
+ return MethodHandleNatives.refKindIsField((byte) refKind);
}
// Android-changed: Inlined from MethodHandleNatives and replaced 'byte' argument with
// 'int'.
static String refKindName(int refKind) {
- switch (refKind) {
- case REF_getField: return "getField";
- case REF_getStatic: return "getStatic";
- case REF_putField: return "putField";
- case REF_putStatic: return "putStatic";
- case REF_invokeVirtual: return "invokeVirtual";
- case REF_invokeStatic: return "invokeStatic";
- case REF_invokeSpecial: return "invokeSpecial";
- case REF_newInvokeSpecial: return "newInvokeSpecial";
- case REF_invokeInterface: return "invokeInterface";
- default: return "REF_???";
- }
+ return MethodHandleNatives.refKindName((byte) refKind);
}
+ // END Android-added: refKind...() methods needed for API compatibility with 26.
}
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandleNatives.java b/ojluni/src/main/java/java/lang/invoke/MethodHandleNatives.java
new file mode 100644
index 0000000..87f95ff
--- /dev/null
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandleNatives.java
@@ -0,0 +1,551 @@
+/*
+ * 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
+ * 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 java.lang.invoke;
+
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
+
+/**
+ * The JVM interface for the method handles package is all here.
+ * This is an interface internal and private to an implementation of JSR 292.
+ * <em>This class is not part of the JSR 292 standard.</em>
+ * @author jrose
+ */
+class MethodHandleNatives {
+
+ // BEGIN Android-removed: Unused implementation code.
+ /*
+ private MethodHandleNatives() { } // static only
+
+ /// MemberName support
+
+ static native void init(MemberName self, Object ref);
+ static native void expand(MemberName self);
+ static native MemberName resolve(MemberName self, Class<?> caller) throws LinkageError, ClassNotFoundException;
+ static native int getMembers(Class<?> defc, String matchName, String matchSig,
+ int matchFlags, Class<?> caller, int skip, MemberName[] results);
+
+ /// Field layout queries parallel to sun.misc.Unsafe:
+ static native long objectFieldOffset(MemberName self); // e.g., returns vmindex
+ static native long staticFieldOffset(MemberName self); // e.g., returns vmindex
+ static native Object staticFieldBase(MemberName self); // e.g., returns clazz
+ static native Object getMemberVMInfo(MemberName self); // returns {vmindex,vmtarget}
+
+ /// MethodHandle support
+
+ /** Fetch MH-related JVM parameter.
+ * which=0 retrieves MethodHandlePushLimit
+ * which=1 retrieves stack slot push size (in address units)
+ *
+ static native int getConstant(int which);
+
+ static final boolean COUNT_GWT;
+
+ /// CallSite support
+
+ /** Tell the JVM that we need to change the target of a CallSite. *
+ static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
+ static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
+
+ private static native void registerNatives();
+ static {
+ registerNatives();
+ COUNT_GWT = getConstant(Constants.GC_COUNT_GWT) != 0;
+
+ // The JVM calls MethodHandleNatives.<clinit>. Cascade the <clinit> calls as needed:
+ MethodHandleImpl.initStatics();
+ }
+ */
+ // END Android-removed: Unused implementation code.
+
+ // All compile-time constants go here.
+ // There is an opportunity to check them against the JVM's idea of them.
+ static class Constants {
+ Constants() { } // static only
+ // BEGIN Android-removed: Unused implementation code.
+ /*
+ // MethodHandleImpl
+ static final int // for getConstant
+ GC_COUNT_GWT = 4,
+ GC_LAMBDA_SUPPORT = 5;
+
+ // MemberName
+ // The JVM uses values of -2 and above for vtable indexes.
+ // Field values are simple positive offsets.
+ // Ref: src/share/vm/oops/methodOop.hpp
+ // This value is negative enough to avoid such numbers,
+ // but not too negative.
+ static final int
+ MN_IS_METHOD = 0x00010000, // method (not constructor)
+ MN_IS_CONSTRUCTOR = 0x00020000, // constructor
+ MN_IS_FIELD = 0x00040000, // field
+ MN_IS_TYPE = 0x00080000, // nested type
+ MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected
+ MN_REFERENCE_KIND_SHIFT = 24, // refKind
+ MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
+ // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
+ MN_SEARCH_SUPERCLASSES = 0x00100000,
+ MN_SEARCH_INTERFACES = 0x00200000;
+
+ /**
+ * Basic types as encoded in the JVM. These code values are not
+ * intended for use outside this class. They are used as part of
+ * a private interface between the JVM and this class.
+ *
+ static final int
+ T_BOOLEAN = 4,
+ T_CHAR = 5,
+ T_FLOAT = 6,
+ T_DOUBLE = 7,
+ T_BYTE = 8,
+ T_SHORT = 9,
+ T_INT = 10,
+ T_LONG = 11,
+ T_OBJECT = 12,
+ //T_ARRAY = 13
+ T_VOID = 14,
+ //T_ADDRESS = 15
+ T_ILLEGAL = 99;
+
+ /**
+ * Constant pool entry types.
+ *
+ static final byte
+ CONSTANT_Utf8 = 1,
+ CONSTANT_Integer = 3,
+ CONSTANT_Float = 4,
+ CONSTANT_Long = 5,
+ CONSTANT_Double = 6,
+ CONSTANT_Class = 7,
+ CONSTANT_String = 8,
+ CONSTANT_Fieldref = 9,
+ CONSTANT_Methodref = 10,
+ CONSTANT_InterfaceMethodref = 11,
+ CONSTANT_NameAndType = 12,
+ CONSTANT_MethodHandle = 15, // JSR 292
+ CONSTANT_MethodType = 16, // JSR 292
+ CONSTANT_InvokeDynamic = 18,
+ CONSTANT_LIMIT = 19; // Limit to tags found in classfiles
+
+ /**
+ * Access modifier flags.
+ *
+ static final char
+ ACC_PUBLIC = 0x0001,
+ ACC_PRIVATE = 0x0002,
+ ACC_PROTECTED = 0x0004,
+ ACC_STATIC = 0x0008,
+ ACC_FINAL = 0x0010,
+ ACC_SYNCHRONIZED = 0x0020,
+ ACC_VOLATILE = 0x0040,
+ ACC_TRANSIENT = 0x0080,
+ ACC_NATIVE = 0x0100,
+ ACC_INTERFACE = 0x0200,
+ ACC_ABSTRACT = 0x0400,
+ ACC_STRICT = 0x0800,
+ ACC_SYNTHETIC = 0x1000,
+ ACC_ANNOTATION = 0x2000,
+ ACC_ENUM = 0x4000,
+ // aliases:
+ ACC_SUPER = ACC_SYNCHRONIZED,
+ ACC_BRIDGE = ACC_VOLATILE,
+ ACC_VARARGS = ACC_TRANSIENT;
+ */
+ // END Android-removed: Unused implementation code.
+
+ /**
+ * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
+ */
+ static final byte
+ REF_NONE = 0, // null value
+ REF_getField = 1,
+ REF_getStatic = 2,
+ REF_putField = 3,
+ REF_putStatic = 4,
+ REF_invokeVirtual = 5,
+ REF_invokeStatic = 6,
+ REF_invokeSpecial = 7,
+ REF_newInvokeSpecial = 8,
+ REF_invokeInterface = 9,
+ REF_LIMIT = 10;
+ }
+
+ static boolean refKindIsValid(int refKind) {
+ return (refKind > REF_NONE && refKind < REF_LIMIT);
+ }
+ static boolean refKindIsField(byte refKind) {
+ assert(refKindIsValid(refKind));
+ return (refKind <= REF_putStatic);
+ }
+ // BEGIN Android-removed: Unused implementation code.
+ /*
+ static boolean refKindIsGetter(byte refKind) {
+ assert(refKindIsValid(refKind));
+ return (refKind <= REF_getStatic);
+ }
+ static boolean refKindIsSetter(byte refKind) {
+ return refKindIsField(refKind) && !refKindIsGetter(refKind);
+ }
+ static boolean refKindIsMethod(byte refKind) {
+ return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial);
+ }
+ static boolean refKindIsConstructor(byte refKind) {
+ return (refKind == REF_newInvokeSpecial);
+ }
+ static boolean refKindHasReceiver(byte refKind) {
+ assert(refKindIsValid(refKind));
+ return (refKind & 1) != 0;
+ }
+ static boolean refKindIsStatic(byte refKind) {
+ return !refKindHasReceiver(refKind) && (refKind != REF_newInvokeSpecial);
+ }
+ static boolean refKindDoesDispatch(byte refKind) {
+ assert(refKindIsValid(refKind));
+ return (refKind == REF_invokeVirtual ||
+ refKind == REF_invokeInterface);
+ }
+ static {
+ final int HR_MASK = ((1 << REF_getField) |
+ (1 << REF_putField) |
+ (1 << REF_invokeVirtual) |
+ (1 << REF_invokeSpecial) |
+ (1 << REF_invokeInterface)
+ );
+ for (byte refKind = REF_NONE+1; refKind < REF_LIMIT; refKind++) {
+ assert(refKindHasReceiver(refKind) == (((1<<refKind) & HR_MASK) != 0)) : refKind;
+ }
+ }
+ */
+ // END Android-removed: Unused implementation code.
+ static String refKindName(byte refKind) {
+ assert(refKindIsValid(refKind));
+ switch (refKind) {
+ case REF_getField: return "getField";
+ case REF_getStatic: return "getStatic";
+ case REF_putField: return "putField";
+ case REF_putStatic: return "putStatic";
+ case REF_invokeVirtual: return "invokeVirtual";
+ case REF_invokeStatic: return "invokeStatic";
+ case REF_invokeSpecial: return "invokeSpecial";
+ case REF_newInvokeSpecial: return "newInvokeSpecial";
+ case REF_invokeInterface: return "invokeInterface";
+ default: return "REF_???";
+ }
+ }
+ // BEGIN Android-removed: Unused implementation code.
+ /*
+ private static native int getNamedCon(int which, Object[] name);
+ static boolean verifyConstants() {
+ Object[] box = { null };
+ for (int i = 0; ; i++) {
+ box[0] = null;
+ int vmval = getNamedCon(i, box);
+ if (box[0] == null) break;
+ String name = (String) box[0];
+ try {
+ Field con = Constants.class.getDeclaredField(name);
+ int jval = con.getInt(null);
+ if (jval == vmval) continue;
+ String err = (name+": JVM has "+vmval+" while Java has "+jval);
+ if (name.equals("CONV_OP_LIMIT")) {
+ System.err.println("warning: "+err);
+ continue;
+ }
+ throw new InternalError(err);
+ } catch (NoSuchFieldException | IllegalAccessException ex) {
+ String err = (name+": JVM has "+vmval+" which Java does not define");
+ // ignore exotic ops the JVM cares about; we just wont issue them
+ //System.err.println("warning: "+err);
+ continue;
+ }
+ }
+ return true;
+ }
+ static {
+ assert(verifyConstants());
+ }
+
+ // Up-calls from the JVM.
+ // These must NOT be public.
+
+ /**
+ * The JVM is linking an invokedynamic instruction. Create a reified call site for it.
+ *
+ static MemberName linkCallSite(Object callerObj,
+ Object bootstrapMethodObj,
+ Object nameObj, Object typeObj,
+ Object staticArguments,
+ Object[] appendixResult) {
+ MethodHandle bootstrapMethod = (MethodHandle)bootstrapMethodObj;
+ Class<?> caller = (Class<?>)callerObj;
+ String name = nameObj.toString().intern();
+ MethodType type = (MethodType)typeObj;
+ if (!TRACE_METHOD_LINKAGE)
+ return linkCallSiteImpl(caller, bootstrapMethod, name, type,
+ staticArguments, appendixResult);
+ return linkCallSiteTracing(caller, bootstrapMethod, name, type,
+ staticArguments, appendixResult);
+ }
+ static MemberName linkCallSiteImpl(Class<?> caller,
+ MethodHandle bootstrapMethod,
+ String name, MethodType type,
+ Object staticArguments,
+ Object[] appendixResult) {
+ CallSite callSite = CallSite.makeSite(bootstrapMethod,
+ name,
+ type,
+ staticArguments,
+ caller);
+ if (callSite instanceof ConstantCallSite) {
+ appendixResult[0] = callSite.dynamicInvoker();
+ return Invokers.linkToTargetMethod(type);
+ } else {
+ appendixResult[0] = callSite;
+ return Invokers.linkToCallSiteMethod(type);
+ }
+ }
+ // Tracing logic:
+ static MemberName linkCallSiteTracing(Class<?> caller,
+ MethodHandle bootstrapMethod,
+ String name, MethodType type,
+ Object staticArguments,
+ Object[] appendixResult) {
+ Object bsmReference = bootstrapMethod.internalMemberName();
+ if (bsmReference == null) bsmReference = bootstrapMethod;
+ Object staticArglist = (staticArguments instanceof Object[] ?
+ java.util.Arrays.asList((Object[]) staticArguments) :
+ staticArguments);
+ System.out.println("linkCallSite "+caller.getName()+" "+
+ bsmReference+" "+
+ name+type+"/"+staticArglist);
+ try {
+ MemberName res = linkCallSiteImpl(caller, bootstrapMethod, name, type,
+ staticArguments, appendixResult);
+ System.out.println("linkCallSite => "+res+" + "+appendixResult[0]);
+ return res;
+ } catch (Throwable ex) {
+ System.out.println("linkCallSite => throw "+ex);
+ throw ex;
+ }
+ }
+
+ /**
+ * The JVM wants a pointer to a MethodType. Oblige it by finding or creating one.
+ *
+ static MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes) {
+ return MethodType.makeImpl(rtype, ptypes, true);
+ }
+
+ /**
+ * The JVM wants to link a call site that requires a dynamic type check.
+ * Name is a type-checking invoker, invokeExact or invoke.
+ * Return a JVM method (MemberName) to handle the invoking.
+ * The method assumes the following arguments on the stack:
+ * 0: the method handle being invoked
+ * 1-N: the arguments to the method handle invocation
+ * N+1: an optional, implicitly added argument (typically the given MethodType)
+ * <p>
+ * The nominal method at such a call site is an instance of
+ * a signature-polymorphic method (see @PolymorphicSignature).
+ * Such method instances are user-visible entities which are
+ * "split" from the generic placeholder method in {@code MethodHandle}.
+ * (Note that the placeholder method is not identical with any of
+ * its instances. If invoked reflectively, is guaranteed to throw an
+ * {@code UnsupportedOperationException}.)
+ * If the signature-polymorphic method instance is ever reified,
+ * it appears as a "copy" of the original placeholder
+ * (a native final member of {@code MethodHandle}) except
+ * that its type descriptor has shape required by the instance,
+ * and the method instance is <em>not</em> varargs.
+ * The method instance is also marked synthetic, since the
+ * method (by definition) does not appear in Java source code.
+ * <p>
+ * The JVM is allowed to reify this method as instance metadata.
+ * For example, {@code invokeBasic} is always reified.
+ * But the JVM may instead call {@code linkMethod}.
+ * If the result is an * ordered pair of a {@code (method, appendix)},
+ * the method gets all the arguments (0..N inclusive)
+ * plus the appendix (N+1), and uses the appendix to complete the call.
+ * In this way, one reusable method (called a "linker method")
+ * can perform the function of any number of polymorphic instance
+ * methods.
+ * <p>
+ * Linker methods are allowed to be weakly typed, with any or
+ * all references rewritten to {@code Object} and any primitives
+ * (except {@code long}/{@code float}/{@code double})
+ * rewritten to {@code int}.
+ * A linker method is trusted to return a strongly typed result,
+ * according to the specific method type descriptor of the
+ * signature-polymorphic instance it is emulating.
+ * This can involve (as necessary) a dynamic check using
+ * data extracted from the appendix argument.
+ * <p>
+ * The JVM does not inspect the appendix, other than to pass
+ * it verbatim to the linker method at every call.
+ * This means that the JDK runtime has wide latitude
+ * for choosing the shape of each linker method and its
+ * corresponding appendix.
+ * Linker methods should be generated from {@code LambdaForm}s
+ * so that they do not become visible on stack traces.
+ * <p>
+ * The {@code linkMethod} call is free to omit the appendix
+ * (returning null) and instead emulate the required function
+ * completely in the linker method.
+ * As a corner case, if N==255, no appendix is possible.
+ * In this case, the method returned must be custom-generated to
+ * to perform any needed type checking.
+ * <p>
+ * If the JVM does not reify a method at a call site, but instead
+ * calls {@code linkMethod}, the corresponding call represented
+ * in the bytecodes may mention a valid method which is not
+ * representable with a {@code MemberName}.
+ * Therefore, use cases for {@code linkMethod} tend to correspond to
+ * special cases in reflective code such as {@code findVirtual}
+ * or {@code revealDirect}.
+ *
+ static MemberName linkMethod(Class<?> callerClass, int refKind,
+ Class<?> defc, String name, Object type,
+ Object[] appendixResult) {
+ if (!TRACE_METHOD_LINKAGE)
+ return linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
+ return linkMethodTracing(callerClass, refKind, defc, name, type, appendixResult);
+ }
+ static MemberName linkMethodImpl(Class<?> callerClass, int refKind,
+ Class<?> defc, String name, Object type,
+ Object[] appendixResult) {
+ try {
+ if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
+ return Invokers.methodHandleInvokeLinkerMethod(name, fixMethodType(callerClass, type), appendixResult);
+ }
+ } catch (Throwable ex) {
+ if (ex instanceof LinkageError)
+ throw (LinkageError) ex;
+ else
+ throw new LinkageError(ex.getMessage(), ex);
+ }
+ throw new LinkageError("no such method "+defc.getName()+"."+name+type);
+ }
+ private static MethodType fixMethodType(Class<?> callerClass, Object type) {
+ if (type instanceof MethodType)
+ return (MethodType) type;
+ else
+ return MethodType.fromMethodDescriptorString((String)type, callerClass.getClassLoader());
+ }
+ // Tracing logic:
+ static MemberName linkMethodTracing(Class<?> callerClass, int refKind,
+ Class<?> defc, String name, Object type,
+ Object[] appendixResult) {
+ System.out.println("linkMethod "+defc.getName()+"."+
+ name+type+"/"+Integer.toHexString(refKind));
+ try {
+ MemberName res = linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
+ System.out.println("linkMethod => "+res+" + "+appendixResult[0]);
+ return res;
+ } catch (Throwable ex) {
+ System.out.println("linkMethod => throw "+ex);
+ throw ex;
+ }
+ }
+
+
+ /**
+ * The JVM is resolving a CONSTANT_MethodHandle CP entry. And it wants our help.
+ * It will make an up-call to this method. (Do not change the name or signature.)
+ * The type argument is a Class for field requests and a MethodType for non-fields.
+ * <p>
+ * Recent versions of the JVM may also pass a resolved MemberName for the type.
+ * In that case, the name is ignored and may be null.
+ *
+ static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
+ Class<?> defc, String name, Object type) {
+ try {
+ Lookup lookup = IMPL_LOOKUP.in(callerClass);
+ assert(refKindIsValid(refKind));
+ return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type);
+ } catch (IllegalAccessException ex) {
+ Throwable cause = ex.getCause();
+ if (cause instanceof AbstractMethodError) {
+ throw (AbstractMethodError) cause;
+ } else {
+ Error err = new IllegalAccessError(ex.getMessage());
+ throw initCauseFrom(err, ex);
+ }
+ } catch (NoSuchMethodException ex) {
+ Error err = new NoSuchMethodError(ex.getMessage());
+ throw initCauseFrom(err, ex);
+ } catch (NoSuchFieldException ex) {
+ Error err = new NoSuchFieldError(ex.getMessage());
+ throw initCauseFrom(err, ex);
+ } catch (ReflectiveOperationException ex) {
+ Error err = new IncompatibleClassChangeError();
+ throw initCauseFrom(err, ex);
+ }
+ }
+
+ /**
+ * Use best possible cause for err.initCause(), substituting the
+ * cause for err itself if the cause has the same (or better) type.
+ *
+ static private Error initCauseFrom(Error err, Exception ex) {
+ Throwable th = ex.getCause();
+ if (err.getClass().isInstance(th))
+ return (Error) th;
+ err.initCause(th == null ? ex : th);
+ return err;
+ }
+
+ /**
+ * Is this method a caller-sensitive method?
+ * I.e., does it call Reflection.getCallerClass or a similer method
+ * to ask about the identity of its caller?
+ *
+ static boolean isCallerSensitive(MemberName mem) {
+ if (!mem.isInvocable()) return false; // fields are not caller sensitive
+
+ return mem.isCallerSensitive() || canBeCalledVirtual(mem);
+ }
+
+ static boolean canBeCalledVirtual(MemberName mem) {
+ assert(mem.isInvocable());
+ Class<?> defc = mem.getDeclaringClass();
+ switch (mem.getName()) {
+ case "checkMemberAccess":
+ return canBeCalledVirtual(mem, java.lang.SecurityManager.class);
+ case "getContextClassLoader":
+ return canBeCalledVirtual(mem, java.lang.Thread.class);
+ }
+ return false;
+ }
+
+ static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) {
+ Class<?> symbolicRefClass = symbolicRef.getDeclaringClass();
+ if (symbolicRefClass == definingClass) return true;
+ if (symbolicRef.isStatic() || symbolicRef.isPrivate()) return false;
+ return (definingClass.isAssignableFrom(symbolicRefClass) || // Msym overrides Mdef
+ symbolicRefClass.isInterface()); // Mdef implements Msym
+ }
+ */
+ // END Android-removed: Unused implementation code.
+}
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandles.java b/ojluni/src/main/java/java/lang/invoke/MethodHandles.java
index bc1e944..17c5f57 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodHandles.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandles.java
@@ -32,9 +32,10 @@
import java.util.ArrayList;
import java.util.NoSuchElementException;
-import dalvik.system.VMStack;
import sun.invoke.util.VerifyAccess;
import sun.invoke.util.Wrapper;
+import sun.reflect.Reflection;
+
import static java.lang.invoke.MethodHandleStatics.*;
/**
@@ -85,8 +86,7 @@
// Android-changed: Remove caller sensitive.
// @CallerSensitive
public static Lookup lookup() {
- // Android-changed: Do not use Reflection.getCallerClass().
- return new Lookup(VMStack.getStackClass1());
+ return new Lookup(Reflection.getCallerClass());
}
/**
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodType.java b/ojluni/src/main/java/java/lang/invoke/MethodType.java
index bfa7ccd..b2ff6e7 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodType.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodType.java
@@ -97,8 +97,8 @@
// The remaining fields are caches of various sorts:
private @Stable MethodTypeForm form; // erased form, plus cached data about primitives
private @Stable MethodType wrapAlt; // alternative wrapped/unwrapped version
- // Android-changed: Remove adapter cache. We're not dynamically generating any
- // adapters at this point.
+ // Android-removed: Cache of higher order adapters.
+ // We're not dynamically generating any adapters at this point.
// private @Stable Invokers invokers; // cache of handy higher-order adapters
private @Stable String methodDescriptor; // cache for toMethodDescriptorString
@@ -124,12 +124,13 @@
}
/*trusted*/ MethodTypeForm form() { return form; }
+ // Android-changed: Make rtype()/ptypes() public @hide for implementation use.
+ // /*trusted*/ Class<?> rtype() { return rtype; }
+ // /*trusted*/ Class<?>[] ptypes() { return ptypes; }
/*trusted*/ /** @hide */ public Class<?> rtype() { return rtype; }
/*trusted*/ /** @hide */ public Class<?>[] ptypes() { return ptypes; }
- // Android-changed: Removed method setForm. It's unused in the JDK and there's no
- // good reason to allow the form to be set externally.
- //
+ // Android-removed: Implementation methods unused on Android.
// void setForm(MethodTypeForm f) { form = f; }
/** This number, mandated by the JVM spec as 255,
@@ -618,22 +619,26 @@
return form.erasedType();
}
+ // BEGIN Android-removed: Implementation methods unused on Android.
+ /*
/**
* Erases all reference types to {@code Object}, and all subword types to {@code int}.
* This is the reduced type polymorphism used by private methods
* such as {@link MethodHandle#invokeBasic invokeBasic}.
* @return a version of the original type with all reference and subword types replaced
- */
- /*non-public*/ MethodType basicType() {
+ *
+ /*non-public* MethodType basicType() {
return form.basicType();
}
/**
* @return a version of the original type with MethodHandle prepended as the first argument
- */
- /*non-public*/ MethodType invokerType() {
+ *
+ /*non-public* MethodType invokerType() {
return insertParameterTypes(0, MethodHandle.class);
}
+ */
+ // END Android-removed: Implementation methods unused on Android.
/**
* Converts all types, both reference and primitive, to {@code Object}.
@@ -805,12 +810,36 @@
return sb.toString();
}
+ // BEGIN Android-removed: Implementation methods unused on Android.
+ /*
/** True if the old return type can always be viewed (w/o casting) under new return type,
* and the new parameters can be viewed (w/o casting) under the old parameter types.
- */
- // Android-changed: Removed implementation details.
- // boolean isViewableAs(MethodType newType, boolean keepInterfaces);
- // boolean parametersAreViewableAs(MethodType newType, boolean keepInterfaces);
+ *
+ /*non-public*
+ boolean isViewableAs(MethodType newType, boolean keepInterfaces) {
+ if (!VerifyType.isNullConversion(returnType(), newType.returnType(), keepInterfaces))
+ return false;
+ return parametersAreViewableAs(newType, keepInterfaces);
+ }
+ /** True if the new parameters can be viewed (w/o casting) under the old parameter types. *
+ /*non-public*
+ boolean parametersAreViewableAs(MethodType newType, boolean keepInterfaces) {
+ if (form == newType.form && form.erasedType == this)
+ return true; // my reference parameters are all Object
+ if (ptypes == newType.ptypes)
+ return true;
+ int argc = parameterCount();
+ if (argc != newType.parameterCount())
+ return false;
+ for (int i = 0; i < argc; i++) {
+ if (!VerifyType.isNullConversion(newType.parameterType(i), parameterType(i), keepInterfaces))
+ return false;
+ }
+ return true;
+ }
+ */
+ // END Android-removed: Implementation methods unused on Android.
+
/*non-public*/
boolean isConvertibleTo(MethodType newType) {
MethodTypeForm oldForm = this.form();
@@ -865,6 +894,9 @@
return true;
}
+ // Android-changed: Temporary workaround for bug in MethodHandle.asType(MethodType).
+ // See http://b/113855305 for more details
+ // Update documentation to describe new behavior.
/** Reports true if the src can be converted to the dst, by both asType and MHs.eCE,
* and with the same effect.
* MHs.eCA has the following "upgrades" to MH.asType:
@@ -881,9 +913,10 @@
* Boxing primitives to references is the same for both operators.
*/
private static boolean explicitCastEquivalentToAsType(Class<?> src, Class<?> dst) {
- if (src == dst || dst == Object.class || dst == void.class) {
- return true;
- } else if (src.isPrimitive() && src != void.class) {
+ if (src == dst || dst == Object.class || dst == void.class) return true;
+ // Android-changed: Temporary workaround for bug in MethodHandle.asType(MethodType).
+ // if (src.isPrimitive()) {
+ if (src.isPrimitive() && src != void.class) {
// Could be a prim/prim conversion, where casting is a strict superset.
// Or a boxing conversion, which is always to an exact wrapper class.
return canConvert(src, dst);
@@ -958,6 +991,8 @@
}
}
+ /// Queries which have to do with the bytecode architecture
+
/** Reports the number of JVM stack slots required to invoke a method
* of this type. Note that (for historical reasons) the JVM requires
* a second stack slot to pass long and double arguments.
@@ -972,16 +1007,63 @@
return form.parameterSlotCount();
}
- /// Queries which have to do with the bytecode architecture
+ // BEGIN Android-removed: Cache of higher order adapters.
+ /*
+ /*non-public* Invokers invokers() {
+ Invokers inv = invokers;
+ if (inv != null) return inv;
+ invokers = inv = new Invokers(this);
+ return inv;
+ }
+ */
+ // END Android-removed: Cache of higher order adapters.
- // Android-changed: These methods aren't needed on Android and are unused within the JDK.
- //
- // int parameterSlotDepth(int num);
- // int returnSlotCount();
- //
- // Android-changed: Removed cache of higher order adapters.
- //
- // Invokers invokers();
+ // BEGIN Android-removed: Implementation methods unused on Android.
+ /*
+ /** Reports the number of JVM stack slots which carry all parameters including and after
+ * the given position, which must be in the range of 0 to
+ * {@code parameterCount} inclusive. Successive parameters are
+ * more shallowly stacked, and parameters are indexed in the bytecodes
+ * according to their trailing edge. Thus, to obtain the depth
+ * in the outgoing call stack of parameter {@code N}, obtain
+ * the {@code parameterSlotDepth} of its trailing edge
+ * at position {@code N+1}.
+ * <p>
+ * Parameters of type {@code long} and {@code double} occupy
+ * two stack slots (for historical reasons) and all others occupy one.
+ * Therefore, the number returned is the number of arguments
+ * <em>including</em> and <em>after</em> the given parameter,
+ * <em>plus</em> the number of long or double arguments
+ * at or after after the argument for the given parameter.
+ * <p>
+ * This method is included for the benefit of applications that must
+ * generate bytecodes that process method handles and invokedynamic.
+ * @param num an index (zero-based, inclusive) within the parameter types
+ * @return the index of the (shallowest) JVM stack slot transmitting the
+ * given parameter
+ * @throws IllegalArgumentException if {@code num} is negative or greater than {@code parameterCount()}
+ *
+ /*non-public* int parameterSlotDepth(int num) {
+ if (num < 0 || num > ptypes.length)
+ parameterType(num); // force a range check
+ return form.parameterToArgSlot(num-1);
+ }
+
+ /** Reports the number of JVM stack slots required to receive a return value
+ * from a method of this type.
+ * If the {@link #returnType() return type} is void, it will be zero,
+ * else if the return type is long or double, it will be two, else one.
+ * <p>
+ * This method is included for the benefit of applications that must
+ * generate bytecodes that process method handles and invokedynamic.
+ * @return the number of JVM stack slots (0, 1, or 2) for this type's return value
+ * Will be removed for PFD.
+ *
+ /*non-public* int returnSlotCount() {
+ return form.returnSlotCount();
+ }
+ */
+ // END Android-removed: Implementation methods unused on Android.
/**
* Finds or creates an instance of a method type, given the spelling of its bytecode descriptor.
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java b/ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java
index d65392b..6f6c2a8 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java
@@ -49,20 +49,45 @@
final MethodType erasedType; // the canonical erasure
final MethodType basicType; // the canonical erasure, with primitives simplified
+ // BEGIN Android-removed: Cached adaptors / lambda forms.
+ // The upstream caching mechanism will not work on Android because of fundamental differences
+ // in the Android runtime/implementation of MethodHandle. LambdaForm is not supported on
+ // Android for similar reasons.
+ /*
// Cached adapter information:
- //
- // @Stable final SoftReference<MethodHandle>[] methodHandles;
- // static final int MH_BASIC_INV, MH_NF_INV, MH_UNINIT_CS, MH_LIMIT;
- //
+ @Stable final SoftReference<MethodHandle>[] methodHandles;
+ // Indexes into methodHandles:
+ static final int
+ MH_BASIC_INV = 0, // cached instance of MH.invokeBasic
+ MH_NF_INV = 1, // cached helper for LF.NamedFunction
+ MH_UNINIT_CS = 2, // uninitialized call site
+ MH_LIMIT = 3;
+
// Cached lambda form information, for basic types only:
- // final @Stable SoftReference<LambdaForm>[] lambdaForms;
- //
+ final @Stable SoftReference<LambdaForm>[] lambdaForms;
// Indexes into lambdaForms:
- //
- // static final int LF_INVVIRTUAL, LF_INVSTATIC, LF_INVSPECIAL, LF_NEWINVSPECIAL,
- // LF_INVINTERFACE, LF_INVSTATIC_INIT, LF_INTERPRET, LF_REBIND, LF_DELEGATE,
- // LF_DELEGATE_BLOCK_INLINING, LF_EX_LINKER, LF_EX_INVOKER, LF_GEN_LINKER, LF_GEN_INVOKER,
- // LF_CS_LINKER, LF_MH_LINKER, LF_GWC, LF_GWT, LF_LIMIT;
+ static final int
+ LF_INVVIRTUAL = 0, // DMH invokeVirtual
+ LF_INVSTATIC = 1,
+ LF_INVSPECIAL = 2,
+ LF_NEWINVSPECIAL = 3,
+ LF_INVINTERFACE = 4,
+ LF_INVSTATIC_INIT = 5, // DMH invokeStatic with <clinit> barrier
+ LF_INTERPRET = 6, // LF interpreter
+ LF_REBIND = 7, // BoundMethodHandle
+ LF_DELEGATE = 8, // DelegatingMethodHandle
+ LF_DELEGATE_BLOCK_INLINING = 9, // Counting DelegatingMethodHandle w/ @DontInline
+ LF_EX_LINKER = 10, // invokeExact_MT (for invokehandle)
+ LF_EX_INVOKER = 11, // MHs.invokeExact
+ LF_GEN_LINKER = 12, // generic invoke_MT (for invokehandle)
+ LF_GEN_INVOKER = 13, // generic MHs.invoke
+ LF_CS_LINKER = 14, // linkToCallSite_CS
+ LF_MH_LINKER = 15, // linkToCallSite_MH
+ LF_GWC = 16, // guardWithCatch (catchException)
+ LF_GWT = 17, // guardWithTest
+ LF_LIMIT = 18;
+ */
+ // END Android-removed: Cached adaptors / lambda forms.
/** Return the type corresponding uniquely (1-1) to this MT-form.
* It might have any primitive returns or arguments, but will have no references except Object.
@@ -87,12 +112,47 @@
return true;
}
- // Android-changed: Removed caches for MethodHandle adaptors / LambdaForms.
- //
- // public MethodHandle cachedMethodHandle(int which);
- // synchronized public MethodHandle setCachedMethodHandle(int which, MethodHandle mh);
- // public LambdaForm cachedLambdaForm(int which);
- // synchronized public LambdaForm setCachedLambdaForm(int which, LambdaForm form);
+ // BEGIN Android-removed: Cached adaptors / lambda forms.
+ /*
+ public MethodHandle cachedMethodHandle(int which) {
+ assert(assertIsBasicType());
+ SoftReference<MethodHandle> entry = methodHandles[which];
+ return (entry != null) ? entry.get() : null;
+ }
+
+ synchronized public MethodHandle setCachedMethodHandle(int which, MethodHandle mh) {
+ // Simulate a CAS, to avoid racy duplication of results.
+ SoftReference<MethodHandle> entry = methodHandles[which];
+ if (entry != null) {
+ MethodHandle prev = entry.get();
+ if (prev != null) {
+ return prev;
+ }
+ }
+ methodHandles[which] = new SoftReference<>(mh);
+ return mh;
+ }
+
+ public LambdaForm cachedLambdaForm(int which) {
+ assert(assertIsBasicType());
+ SoftReference<LambdaForm> entry = lambdaForms[which];
+ return (entry != null) ? entry.get() : null;
+ }
+
+ synchronized public LambdaForm setCachedLambdaForm(int which, LambdaForm form) {
+ // Simulate a CAS, to avoid racy duplication of results.
+ SoftReference<LambdaForm> entry = lambdaForms[which];
+ if (entry != null) {
+ LambdaForm prev = entry.get();
+ if (prev != null) {
+ return prev;
+ }
+ }
+ lambdaForms[which] = new SoftReference<>(form);
+ return form;
+ }
+ */
+ // END Android-removed: Cached adaptors / lambda forms.
/**
* Build an MTF for a given type, which must have all references erased to Object.
@@ -154,8 +214,7 @@
this.argCounts = that.argCounts;
this.argToSlotTable = that.argToSlotTable;
this.slotToArgTable = that.slotToArgTable;
- // Android-changed: Removed cached adaptors / lambda forms.
- //
+ // Android-removed: Cached adaptors / lambda forms.
// this.methodHandles = null;
// this.lambdaForms = null;
return;
@@ -201,8 +260,7 @@
// Initialize caches, but only for basic types
assert(basicType == erasedType);
- // Android-changed: Removed cached adaptors / lambda forms.
- //
+ // Android-removed: Cached adaptors / lambda forms.
// this.lambdaForms = new SoftReference[LF_LIMIT];
// this.methodHandles = new SoftReference[MH_LIMIT];
}
diff --git a/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java b/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java
index bb01d4c..6ca8aa0 100644
--- a/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java
+++ b/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java
@@ -25,9 +25,6 @@
package java.lang.invoke;
-// Android-changed: not used.
-// import java.util.concurrent.atomic.AtomicInteger;
-
// Android-changed: removed references to MutableCallSite.syncAll().
/**
* A {@code MutableCallSite} is a {@link CallSite} whose target variable
@@ -161,123 +158,125 @@
return makeDynamicInvoker();
}
- // Android-changed: not exposing incomplete implementation.
- // /**
- // * Performs a synchronization operation on each call site in the given array,
- // * forcing all other threads to throw away any cached values previously
- // * loaded from the target of any of the call sites.
- // * <p>
- // * This operation does not reverse any calls that have already started
- // * on an old target value.
- // * (Java supports {@linkplain java.lang.Object#wait() forward time travel} only.)
- // * <p>
- // * The overall effect is to force all future readers of each call site's target
- // * to accept the most recently stored value.
- // * ("Most recently" is reckoned relative to the {@code syncAll} itself.)
- // * Conversely, the {@code syncAll} call may block until all readers have
- // * (somehow) decached all previous versions of each call site's target.
- // * <p>
- // * To avoid race conditions, calls to {@code setTarget} and {@code syncAll}
- // * should generally be performed under some sort of mutual exclusion.
- // * Note that reader threads may observe an updated target as early
- // * as the {@code setTarget} call that install the value
- // * (and before the {@code syncAll} that confirms the value).
- // * On the other hand, reader threads may observe previous versions of
- // * the target until the {@code syncAll} call returns
- // * (and after the {@code setTarget} that attempts to convey the updated version).
- // * <p>
- // * This operation is likely to be expensive and should be used sparingly.
- // * If possible, it should be buffered for batch processing on sets of call sites.
- // * <p>
- // * If {@code sites} contains a null element,
- // * a {@code NullPointerException} will be raised.
- // * In this case, some non-null elements in the array may be
- // * processed before the method returns abnormally.
- // * Which elements these are (if any) is implementation-dependent.
- // *
- // * <h3>Java Memory Model details</h3>
- // * In terms of the Java Memory Model, this operation performs a synchronization
- // * action which is comparable in effect to the writing of a volatile variable
- // * by the current thread, and an eventual volatile read by every other thread
- // * that may access one of the affected call sites.
- // * <p>
- // * The following effects are apparent, for each individual call site {@code S}:
- // * <ul>
- // * <li>A new volatile variable {@code V} is created, and written by the current thread.
- // * As defined by the JMM, this write is a global synchronization event.
- // * <li>As is normal with thread-local ordering of write events,
- // * every action already performed by the current thread is
- // * taken to happen before the volatile write to {@code V}.
- // * (In some implementations, this means that the current thread
- // * performs a global release operation.)
- // * <li>Specifically, the write to the current target of {@code S} is
- // * taken to happen before the volatile write to {@code V}.
- // * <li>The volatile write to {@code V} is placed
- // * (in an implementation specific manner)
- // * in the global synchronization order.
- // * <li>Consider an arbitrary thread {@code T} (other than the current thread).
- // * If {@code T} executes a synchronization action {@code A}
- // * after the volatile write to {@code V} (in the global synchronization order),
- // * it is therefore required to see either the current target
- // * of {@code S}, or a later write to that target,
- // * if it executes a read on the target of {@code S}.
- // * (This constraint is called "synchronization-order consistency".)
- // * <li>The JMM specifically allows optimizing compilers to elide
- // * reads or writes of variables that are known to be useless.
- // * Such elided reads and writes have no effect on the happens-before
- // * relation. Regardless of this fact, the volatile {@code V}
- // * will not be elided, even though its written value is
- // * indeterminate and its read value is not used.
- // * </ul>
- // * Because of the last point, the implementation behaves as if a
- // * volatile read of {@code V} were performed by {@code T}
- // * immediately after its action {@code A}. In the local ordering
- // * of actions in {@code T}, this read happens before any future
- // * read of the target of {@code S}. It is as if the
- // * implementation arbitrarily picked a read of {@code S}'s target
- // * by {@code T}, and forced a read of {@code V} to precede it,
- // * thereby ensuring communication of the new target value.
- // * <p>
- // * As long as the constraints of the Java Memory Model are obeyed,
- // * implementations may delay the completion of a {@code syncAll}
- // * operation while other threads ({@code T} above) continue to
- // * use previous values of {@code S}'s target.
- // * However, implementations are (as always) encouraged to avoid
- // * livelock, and to eventually require all threads to take account
- // * of the updated target.
- // *
- // * <p style="font-size:smaller;">
- // * <em>Discussion:</em>
- // * For performance reasons, {@code syncAll} is not a virtual method
- // * on a single call site, but rather applies to a set of call sites.
- // * Some implementations may incur a large fixed overhead cost
- // * for processing one or more synchronization operations,
- // * but a small incremental cost for each additional call site.
- // * In any case, this operation is likely to be costly, since
- // * other threads may have to be somehow interrupted
- // * in order to make them notice the updated target value.
- // * However, it may be observed that a single call to synchronize
- // * several sites has the same formal effect as many calls,
- // * each on just one of the sites.
- // *
- // * <p style="font-size:smaller;">
- // * <em>Implementation Note:</em>
- // * Simple implementations of {@code MutableCallSite} may use
- // * a volatile variable for the target of a mutable call site.
- // * In such an implementation, the {@code syncAll} method can be a no-op,
- // * and yet it will conform to the JMM behavior documented above.
- // *
- // * @param sites an array of call sites to be synchronized
- // * @throws NullPointerException if the {@code sites} array reference is null
- // * or the array contains a null
- // */
- // public static void syncAll(MutableCallSite[] sites) {
- // if (sites.length == 0) return;
- // STORE_BARRIER.lazySet(0);
- // for (int i = 0; i < sites.length; i++) {
- // sites[i].getClass(); // trigger NPE on first null
- // }
- // // FIXME: NYI
- // }
- // private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
+ // BEGIN Android-removed: syncAll() implementation is incomplete.
+ /**
+ * Performs a synchronization operation on each call site in the given array,
+ * forcing all other threads to throw away any cached values previously
+ * loaded from the target of any of the call sites.
+ * <p>
+ * This operation does not reverse any calls that have already started
+ * on an old target value.
+ * (Java supports {@linkplain java.lang.Object#wait() forward time travel} only.)
+ * <p>
+ * The overall effect is to force all future readers of each call site's target
+ * to accept the most recently stored value.
+ * ("Most recently" is reckoned relative to the {@code syncAll} itself.)
+ * Conversely, the {@code syncAll} call may block until all readers have
+ * (somehow) decached all previous versions of each call site's target.
+ * <p>
+ * To avoid race conditions, calls to {@code setTarget} and {@code syncAll}
+ * should generally be performed under some sort of mutual exclusion.
+ * Note that reader threads may observe an updated target as early
+ * as the {@code setTarget} call that install the value
+ * (and before the {@code syncAll} that confirms the value).
+ * On the other hand, reader threads may observe previous versions of
+ * the target until the {@code syncAll} call returns
+ * (and after the {@code setTarget} that attempts to convey the updated version).
+ * <p>
+ * This operation is likely to be expensive and should be used sparingly.
+ * If possible, it should be buffered for batch processing on sets of call sites.
+ * <p>
+ * If {@code sites} contains a null element,
+ * a {@code NullPointerException} will be raised.
+ * In this case, some non-null elements in the array may be
+ * processed before the method returns abnormally.
+ * Which elements these are (if any) is implementation-dependent.
+ *
+ * <h1>Java Memory Model details</h1>
+ * In terms of the Java Memory Model, this operation performs a synchronization
+ * action which is comparable in effect to the writing of a volatile variable
+ * by the current thread, and an eventual volatile read by every other thread
+ * that may access one of the affected call sites.
+ * <p>
+ * The following effects are apparent, for each individual call site {@code S}:
+ * <ul>
+ * <li>A new volatile variable {@code V} is created, and written by the current thread.
+ * As defined by the JMM, this write is a global synchronization event.
+ * <li>As is normal with thread-local ordering of write events,
+ * every action already performed by the current thread is
+ * taken to happen before the volatile write to {@code V}.
+ * (In some implementations, this means that the current thread
+ * performs a global release operation.)
+ * <li>Specifically, the write to the current target of {@code S} is
+ * taken to happen before the volatile write to {@code V}.
+ * <li>The volatile write to {@code V} is placed
+ * (in an implementation specific manner)
+ * in the global synchronization order.
+ * <li>Consider an arbitrary thread {@code T} (other than the current thread).
+ * If {@code T} executes a synchronization action {@code A}
+ * after the volatile write to {@code V} (in the global synchronization order),
+ * it is therefore required to see either the current target
+ * of {@code S}, or a later write to that target,
+ * if it executes a read on the target of {@code S}.
+ * (This constraint is called "synchronization-order consistency".)
+ * <li>The JMM specifically allows optimizing compilers to elide
+ * reads or writes of variables that are known to be useless.
+ * Such elided reads and writes have no effect on the happens-before
+ * relation. Regardless of this fact, the volatile {@code V}
+ * will not be elided, even though its written value is
+ * indeterminate and its read value is not used.
+ * </ul>
+ * Because of the last point, the implementation behaves as if a
+ * volatile read of {@code V} were performed by {@code T}
+ * immediately after its action {@code A}. In the local ordering
+ * of actions in {@code T}, this read happens before any future
+ * read of the target of {@code S}. It is as if the
+ * implementation arbitrarily picked a read of {@code S}'s target
+ * by {@code T}, and forced a read of {@code V} to precede it,
+ * thereby ensuring communication of the new target value.
+ * <p>
+ * As long as the constraints of the Java Memory Model are obeyed,
+ * implementations may delay the completion of a {@code syncAll}
+ * operation while other threads ({@code T} above) continue to
+ * use previous values of {@code S}'s target.
+ * However, implementations are (as always) encouraged to avoid
+ * livelock, and to eventually require all threads to take account
+ * of the updated target.
+ *
+ * <p style="font-size:smaller;">
+ * <em>Discussion:</em>
+ * For performance reasons, {@code syncAll} is not a virtual method
+ * on a single call site, but rather applies to a set of call sites.
+ * Some implementations may incur a large fixed overhead cost
+ * for processing one or more synchronization operations,
+ * but a small incremental cost for each additional call site.
+ * In any case, this operation is likely to be costly, since
+ * other threads may have to be somehow interrupted
+ * in order to make them notice the updated target value.
+ * However, it may be observed that a single call to synchronize
+ * several sites has the same formal effect as many calls,
+ * each on just one of the sites.
+ *
+ * <p style="font-size:smaller;">
+ * <em>Implementation Note:</em>
+ * Simple implementations of {@code MutableCallSite} may use
+ * a volatile variable for the target of a mutable call site.
+ * In such an implementation, the {@code syncAll} method can be a no-op,
+ * and yet it will conform to the JMM behavior documented above.
+ *
+ * @param sites an array of call sites to be synchronized
+ * @throws NullPointerException if the {@code sites} array reference is null
+ * or the array contains a null
+ *
+ public static void syncAll(MutableCallSite[] sites) {
+ if (sites.length == 0) return;
+ STORE_BARRIER.lazySet(0);
+ for (int i = 0; i < sites.length; i++) {
+ sites[i].getClass(); // trigger NPE on first null
+ }
+ // FIXME: NYI
+ }
+ private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
+ */
+ // END Android-removed: syncAll() implementation is incomplete.
}
diff --git a/ojluni/src/main/java/java/lang/invoke/Transformers.java b/ojluni/src/main/java/java/lang/invoke/Transformers.java
index 75ee192..fc8727a 100644
--- a/ojluni/src/main/java/java/lang/invoke/Transformers.java
+++ b/ojluni/src/main/java/java/lang/invoke/Transformers.java
@@ -1,11 +1,12 @@
/*
- * Copyright 2016 Google Inc.
+ * Copyright (C) 2016 The Android Open Source Project
*
* 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. Google designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Google in the LICENSE file that accompanied this code.
+ * published by the Free Software Foundation. The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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
diff --git a/ojluni/src/main/java/java/lang/invoke/VolatileCallSite.java b/ojluni/src/main/java/java/lang/invoke/VolatileCallSite.java
index 6444335..47d2689 100644
--- a/ojluni/src/main/java/java/lang/invoke/VolatileCallSite.java
+++ b/ojluni/src/main/java/java/lang/invoke/VolatileCallSite.java
@@ -25,7 +25,7 @@
package java.lang.invoke;
-// Android-changed: removed references to MutableCallSite.syncAll().
+// Android-changed: Removed references to MutableCallSite.syncAll().
/**
* A {@code VolatileCallSite} is a {@link CallSite} whose target acts like a volatile variable.
* An {@code invokedynamic} instruction linked to a {@code VolatileCallSite} sees updates
diff --git a/ojluni/src/main/java/java/lang/ref/Reference.java b/ojluni/src/main/java/java/lang/ref/Reference.java
index 4d51b18..551d672 100644
--- a/ojluni/src/main/java/java/lang/ref/Reference.java
+++ b/ojluni/src/main/java/java/lang/ref/Reference.java
@@ -38,8 +38,8 @@
* @author Mark Reinhold
* @since 1.2
*/
-// Android-changed: Major parts of the code below were changed to accomodate a
-// different GC and compiler. ClassLinker knows about the fields of this class.
+// BEGIN Android-changed: Reimplemented to accommodate a different GC and compiler.
+// ClassLinker knows about the fields of this class.
public abstract class Reference<T> {
/**
@@ -156,7 +156,6 @@
return queue != null && queue.enqueue(this);
}
-
/* -- Constructors -- */
Reference(T referent) {
@@ -167,8 +166,10 @@
this.referent = referent;
this.queue = queue;
}
+ // END Android-changed: Reimplemented to accommodate a different GC and compiler.
- // BEGIN Android-added: reachabilityFence() documentation from upstream OpenJDK9+181
+ // BEGIN Android-added: reachabilityFence() from upstream OpenJDK9+181.
+ // The actual implementation differs from OpenJDK9.
/**
* Ensures that the object referenced by the given reference remains
* <a href="package-summary.html#reachability"><em>strongly reachable</em></a>,
@@ -278,9 +279,7 @@
* @param ref the reference. If {@code null}, this method has no effect.
* @since 9
*/
- // END Android-added: reachabilityFence() documentation from upstream OpenJDK9+181
-
- // Android-changed: reachabilityFence implementation differs from OpenJDK9.
+ // @DontInline
public static void reachabilityFence(Object ref) {
// This code is usually replaced by much faster intrinsic implementations.
// It will be executed for tests run with the access checks interpreter in
@@ -312,4 +311,5 @@
}
};
}
+ // END Android-added: Add reachabilityFence() from upstream OpenJDK9+181.
}
diff --git a/ojluni/src/main/java/java/lang/ref/ReferenceQueue.java b/ojluni/src/main/java/java/lang/ref/ReferenceQueue.java
index 80c65d9..72e55c1b 100644
--- a/ojluni/src/main/java/java/lang/ref/ReferenceQueue.java
+++ b/ojluni/src/main/java/java/lang/ref/ReferenceQueue.java
@@ -35,6 +35,8 @@
* @author Mark Reinhold
* @since 1.2
*/
+// BEGIN Android-changed: Reimplemented to accomodate a different GC and compiler.
+
public class ReferenceQueue<T> {
// Reference.queueNext will be set to sQueueNextUnenqueued to indicate
@@ -278,3 +280,4 @@
}
}
}
+// END Android-changed: Reimplemented to accomodate a different GC and compiler.
diff --git a/ojluni/src/main/java/java/lang/ref/SoftReference.java b/ojluni/src/main/java/java/lang/ref/SoftReference.java
index 814baa4..272d1bd 100644
--- a/ojluni/src/main/java/java/lang/ref/SoftReference.java
+++ b/ojluni/src/main/java/java/lang/ref/SoftReference.java
@@ -25,7 +25,7 @@
package java.lang.ref;
-
+// Android-changed: Javadoc change to recommend against using SoftReferences for caches.
/**
* Soft reference objects, which are cleared at the discretion of the garbage
* collector in response to memory demand.
diff --git a/ojluni/src/main/java/java/lang/reflect/AnnotatedElement.java b/ojluni/src/main/java/java/lang/reflect/AnnotatedElement.java
index cf6af47..7bb2a60 100644
--- a/ojluni/src/main/java/java/lang/reflect/AnnotatedElement.java
+++ b/ojluni/src/main/java/java/lang/reflect/AnnotatedElement.java
@@ -27,6 +27,7 @@
package java.lang.reflect;
import java.lang.annotation.Annotation;
+import java.lang.annotation.AnnotationFormatError;
import java.util.Objects;
import libcore.reflect.AnnotatedElements;
diff --git a/ojluni/src/main/java/java/lang/reflect/Type.java b/ojluni/src/main/java/java/lang/reflect/Type.java
index 02e97b0..eee7443 100644
--- a/ojluni/src/main/java/java/lang/reflect/Type.java
+++ b/ojluni/src/main/java/java/lang/reflect/Type.java
@@ -32,7 +32,6 @@
*
* @since 1.5
*/
-
public interface Type {
/**
* Returns a string describing this type, including information
diff --git a/ojluni/src/main/java/java/lang/reflect/TypeVariable.java b/ojluni/src/main/java/java/lang/reflect/TypeVariable.java
index 07b375c..4e29a94 100644
--- a/ojluni/src/main/java/java/lang/reflect/TypeVariable.java
+++ b/ojluni/src/main/java/java/lang/reflect/TypeVariable.java
@@ -89,6 +89,8 @@
*/
String getName();
+ // Android-removed: getAnnotatedBounds(), no support for runtime type annotations on Android.
+ /*
/**
* Returns an array of AnnotatedType objects that represent the use of
* types to denote the upper bounds of the type parameter represented by
@@ -99,7 +101,7 @@
*
* @return an array of objects representing the upper bounds of the type variable
* @since 1.8
- */
- // Android-removed: getAnnotatedBounds(), no support for runtime type annotations on Android.
- // AnnotatedType[] getAnnotatedBounds();
+ *
+ AnnotatedType[] getAnnotatedBounds();
+ */
}
diff --git a/ojluni/src/main/java/java/net/AbstractPlainDatagramSocketImpl.java b/ojluni/src/main/java/java/net/AbstractPlainDatagramSocketImpl.java
index ad0a618..a3c738a 100644
--- a/ojluni/src/main/java/java/net/AbstractPlainDatagramSocketImpl.java
+++ b/ojluni/src/main/java/java/net/AbstractPlainDatagramSocketImpl.java
@@ -25,6 +25,7 @@
package java.net;
import libcore.io.IoBridge;
+import libcore.io.IoUtils;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -96,9 +97,10 @@
throw ioe;
}
- // Android-added: CloseGuard
+ // Android-added: CloseGuard/fdsan
if (fd != null && fd.valid()) {
guard.open("close");
+ IoUtils.setFdOwner(fd, this);
}
}
diff --git a/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java b/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java
index a36dae4..0500811 100644
--- a/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java
+++ b/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java
@@ -488,9 +488,12 @@
return socketOutputStream;
}
+ // Android-removed: this.fd is maintained by the concrete implementation.
+ /*
void setFileDescriptor(FileDescriptor fd) {
this.fd = fd;
}
+ */
void setAddress(InetAddress address) {
this.address = address;
diff --git a/ojluni/src/main/java/java/net/InMemoryCookieStore.java b/ojluni/src/main/java/java/net/InMemoryCookieStore.java
index 974eeaa..5df66c0 100644
--- a/ojluni/src/main/java/java/net/InMemoryCookieStore.java
+++ b/ojluni/src/main/java/java/net/InMemoryCookieStore.java
@@ -169,17 +169,38 @@
* of this cookie store.
*/
public List<URI> getURIs() {
+ // BEGIN Android-changed: App compat. Return URI with no cookies. http://b/65538736
+ /*
List<URI> uris = new ArrayList<URI>();
lock.lock();
try {
+ Iterator<URI> it = uriIndex.keySet().iterator();
+ while (it.hasNext()) {
+ URI uri = it.next();
+ List<HttpCookie> cookies = uriIndex.get(uri);
+ if (cookies == null || cookies.size() == 0) {
+ // no cookies list or an empty list associated with
+ // this uri entry, delete it
+ it.remove();
+ }
+ }
+ } finally {
+ uris.addAll(uriIndex.keySet());
+ lock.unlock();
+ }
+
+ return uris;
+ */
+ lock.lock();
+ try {
List<URI> result = new ArrayList<URI>(uriIndex.keySet());
result.remove(null);
return Collections.unmodifiableList(result);
} finally {
- uris.addAll(uriIndex.keySet());
lock.unlock();
}
+ // END Android-changed: App compat. Return URI with no cookies. http://b/65538736
}
diff --git a/ojluni/src/main/java/java/net/InetAddress.java b/ojluni/src/main/java/java/net/InetAddress.java
index 94d32d3..2e6b534 100644
--- a/ojluni/src/main/java/java/net/InetAddress.java
+++ b/ojluni/src/main/java/java/net/InetAddress.java
@@ -1606,7 +1606,7 @@
static final int NETID_UNSET = 0;
// BEGIN Android-added: Add methods required by frameworks/base.
- // Particularly those required to deal with net-ids and scope ids.
+ // Particularly those required to deal with scope ids.
/**
* Returns true if the string is a valid numeric IPv4 or IPv6 address (such as "192.168.0.1").
* This copes with all forms of address that Java supports, detailed in the {@link InetAddress}
@@ -1673,7 +1673,8 @@
public static void clearDnsCache() {
impl.clearAddressCache();
}
-
+ // END Android-added: Add methods required by frameworks/base.
+ // BEGIN Android-added: Support for network (netId)-specific DNS resolution.
/**
* Operates identically to {@code getByName} except host resolution is
* performed on the network designated by {@code netId}.
@@ -1702,17 +1703,7 @@
public static InetAddress[] getAllByNameOnNet(String host, int netId) throws UnknownHostException {
return impl.lookupAllHostAddr(host, netId).clone();
}
- // END Android-added: Add methods required by frameworks/base.
-
- // Only called by java.net.SocketPermission.
- static InetAddress[] getAllByName0(String authHost, boolean check) throws UnknownHostException {
- throw new UnsupportedOperationException();
- }
-
- // Only called by java.net.SocketPermission.
- String getHostName(boolean check) {
- throw new UnsupportedOperationException();
- }
+ // END Android-added: Support for network (netId)-specific DNS resolution.
}
// BEGIN Android-removed: Android doesn't load user-provided implementation.
/*
diff --git a/ojluni/src/main/java/java/net/PlainSocketImpl.java b/ojluni/src/main/java/java/net/PlainSocketImpl.java
index f592398..89ee53e 100644
--- a/ojluni/src/main/java/java/net/PlainSocketImpl.java
+++ b/ojluni/src/main/java/java/net/PlainSocketImpl.java
@@ -72,15 +72,19 @@
* Constructs an empty instance.
*/
PlainSocketImpl() {
- this(new FileDescriptor());
+ // Android-changed: Let PlainSocketImpl construct its own FileDescriptor.
+ this.fd = new FileDescriptor();
}
/**
* Constructs an instance with the given file descriptor.
*/
+ // Android-removed: Let PlainSocketImpl construct its own FileDescriptor.
+ /*
PlainSocketImpl(FileDescriptor fd) {
this.fd = fd;
}
+ */
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
@@ -122,6 +126,7 @@
// 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$());
+ IoUtils.setFdOwner(fd, this);
if (serverSocket != null) {
IoUtils.setBlocking(fd, false);
@@ -196,11 +201,14 @@
FileDescriptor newfd = Libcore.os.accept(fd, peerAddress);
s.fd.setInt$(newfd.getInt$());
+ IoUtils.setFdOwner(s.fd, s);
s.address = peerAddress.getAddress();
s.port = peerAddress.getPort();
} catch (ErrnoException errnoException) {
if (errnoException.errno == EAGAIN) {
- throw new SocketTimeoutException(errnoException);
+ SocketTimeoutException e = new SocketTimeoutException();
+ e.initCause(errnoException);
+ throw e;
} else if (errnoException.errno == EINVAL || errnoException.errno == EBADF) {
throw new SocketException("Socket closed");
}
diff --git a/ojluni/src/main/java/java/net/ProtocolException.java b/ojluni/src/main/java/java/net/ProtocolException.java
index 0368350..5944282 100644
--- a/ojluni/src/main/java/java/net/ProtocolException.java
+++ b/ojluni/src/main/java/java/net/ProtocolException.java
@@ -54,10 +54,4 @@
*/
public ProtocolException() {
}
-
- // Android-added: ProtocolException ctor used by frameworks.
- /** @hide */
- public ProtocolException(String msg, Throwable cause) {
- super(msg, cause);
- }
}
diff --git a/ojluni/src/main/java/java/net/SocketTimeoutException.java b/ojluni/src/main/java/java/net/SocketTimeoutException.java
index 2c61415..5daf600 100644
--- a/ojluni/src/main/java/java/net/SocketTimeoutException.java
+++ b/ojluni/src/main/java/java/net/SocketTimeoutException.java
@@ -48,16 +48,4 @@
* Construct a new SocketTimeoutException with no detailed message.
*/
public SocketTimeoutException() {}
-
- /** @hide */
- // Android-added: Additional constructor for internal use.
- public SocketTimeoutException(Throwable cause) {
- super(cause);
- }
-
- /** @hide */
- // Android-added: Additional constructor for internal use.
- public SocketTimeoutException(String msg, Throwable cause) {
- super(msg, cause);
- }
}
diff --git a/ojluni/src/main/java/java/net/URLStreamHandler.java b/ojluni/src/main/java/java/net/URLStreamHandler.java
index d5380c1..12b842c 100644
--- a/ojluni/src/main/java/java/net/URLStreamHandler.java
+++ b/ojluni/src/main/java/java/net/URLStreamHandler.java
@@ -528,6 +528,8 @@
return result.toString();
}
+ // Android-changed: Removed @see tag (target is package-private):
+ // @see java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)
/**
* Sets the fields of the {@code URL} argument to the indicated values.
* Only classes derived from URLStreamHandler are able
@@ -544,7 +546,6 @@
* @param ref the reference.
* @exception SecurityException if the protocol handler of the URL is
* different from this one
- * @see java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)
* @since 1.3
*/
protected void setURL(URL u, String protocol, String host, int port,
diff --git a/ojluni/src/main/java/java/nio/Bits.java b/ojluni/src/main/java/java/nio/Bits.java
index 8f8767d..dda5b09 100644
--- a/ojluni/src/main/java/java/nio/Bits.java
+++ b/ojluni/src/main/java/java/nio/Bits.java
@@ -564,37 +564,20 @@
// -- Processor and memory-system properties --
- // Android-changed: Android is always little-endian.
- // private static final ByteOrder byteOrder;
- private static final ByteOrder byteOrder = ByteOrder.LITTLE_ENDIAN;
+ private static final ByteOrder byteOrder;
static ByteOrder byteOrder() {
- // BEGIN Android-removed: Android is always little-endian.
+ // Android-removed: Android is always little-endian.
/*
if (byteOrder == null)
throw new Error("Unknown byte order");
- if (byteOrder == null) {
- long a = unsafe.allocateMemory(8);
- try {
- unsafe.putLong(a, 0x0102030405060708L);
- byte b = unsafe.getByte(a);
- switch (b) {
- case 0x01: byteOrder = ByteOrder.BIG_ENDIAN; break;
- case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN; break;
- default: throw new Error("Unknown byte order");
- }
- } finally {
- unsafe.freeMemory(a);
- }
- }
*/
- // END Android-removed: Android is always little-endian.
return byteOrder;
}
- // BEGIN Android-removed: Android is always little-endian.
- /*
static {
+ // BEGIN Android-changed: Android is always little-endian.
+ /*
long a = unsafe.allocateMemory(8);
try {
unsafe.putLong(a, 0x0102030405060708L);
@@ -609,9 +592,10 @@
} finally {
unsafe.freeMemory(a);
}
+ */
+ byteOrder = ByteOrder.LITTLE_ENDIAN;
+ // END Android-changed: Android is always little-endian.
}
- */
- // END Android-removed: Android is always little-endian.
private static int pageSize = -1;
@@ -643,65 +627,115 @@
// -- Direct memory management --
+ // BEGIN Android-removed: Direct memory management unused on Android.
+ /*
// A user-settable upper limit on the maximum amount of allocatable
// direct buffer memory. This value may be changed during VM
// initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
private static volatile long maxMemory = VM.maxDirectMemory();
- private static volatile long reservedMemory;
- private static volatile long totalCapacity;
- private static volatile long count;
- private static boolean memoryLimitSet = false;
+ private static final AtomicLong reservedMemory = new AtomicLong();
+ private static final AtomicLong totalCapacity = new AtomicLong();
+ private static final AtomicLong count = new AtomicLong();
+ private static volatile boolean memoryLimitSet = false;
+ // max. number of sleeps during try-reserving with exponentially
+ // increasing delay before throwing OutOfMemoryError:
+ // 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s)
+ // which means that OOME will be thrown after 0.5 s of trying
+ private static final int MAX_SLEEPS = 9;
// These methods should be called whenever direct memory is allocated or
// freed. They allow the user to control the amount of direct memory
// which a process may access. All sizes are specified in bytes.
static void reserveMemory(long size, int cap) {
- synchronized (Bits.class) {
- if (!memoryLimitSet && VM.isBooted()) {
- maxMemory = VM.maxDirectMemory();
- memoryLimitSet = true;
- }
- // -XX:MaxDirectMemorySize limits the total capacity rather than the
- // actual memory usage, which will differ when buffers are page
- // aligned.
- if (cap <= maxMemory - totalCapacity) {
- reservedMemory += size;
- totalCapacity += cap;
- count++;
+
+ if (!memoryLimitSet && VM.isBooted()) {
+ maxMemory = VM.maxDirectMemory();
+ memoryLimitSet = true;
+ }
+
+ // optimist!
+ if (tryReserveMemory(size, cap)) {
+ return;
+ }
+
+ final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();
+
+ // retry while helping enqueue pending Reference objects
+ // which includes executing pending Cleaner(s) which includes
+ // Cleaner(s) that free direct buffer memory
+ while (jlra.tryHandlePendingReference()) {
+ if (tryReserveMemory(size, cap)) {
return;
}
}
// trigger VM's Reference processing
System.gc();
+
+ // a retry loop with exponential back-off delays
+ // (this gives VM some time to do it's job)
+ boolean interrupted = false;
try {
- Thread.sleep(100);
- } catch (InterruptedException x) {
- // Restore interrupt status
- Thread.currentThread().interrupt();
- }
- synchronized (Bits.class) {
- if (totalCapacity + cap > maxMemory)
- throw new OutOfMemoryError("Direct buffer memory");
- reservedMemory += size;
- totalCapacity += cap;
- count++;
- }
+ long sleepTime = 1;
+ int sleeps = 0;
+ while (true) {
+ if (tryReserveMemory(size, cap)) {
+ return;
+ }
+ if (sleeps >= MAX_SLEEPS) {
+ break;
+ }
+ if (!jlra.tryHandlePendingReference()) {
+ try {
+ Thread.sleep(sleepTime);
+ sleepTime <<= 1;
+ sleeps++;
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ }
+ }
+ // no luck
+ throw new OutOfMemoryError("Direct buffer memory");
+
+ } finally {
+ if (interrupted) {
+ // don't swallow interrupts
+ Thread.currentThread().interrupt();
+ }
+ }
}
- static synchronized void unreserveMemory(long size, int cap) {
- if (reservedMemory > 0) {
- reservedMemory -= size;
- totalCapacity -= cap;
- count--;
- assert (reservedMemory > -1);
+ private static boolean tryReserveMemory(long size, int cap) {
+
+ // -XX:MaxDirectMemorySize limits the total capacity rather than the
+ // actual memory usage, which will differ when buffers are page
+ // aligned.
+ long totalCap;
+ while (cap <= maxMemory - (totalCap = totalCapacity.get())) {
+ if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) {
+ reservedMemory.addAndGet(size);
+ count.incrementAndGet();
+ return true;
+ }
}
+
+ return false;
}
+
+ static void unreserveMemory(long size, int cap) {
+ long cnt = count.decrementAndGet();
+ long reservedMem = reservedMemory.addAndGet(-size);
+ long totalCap = totalCapacity.addAndGet(-cap);
+ assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0;
+ }
+ */
+
// -- Monitoring of direct buffer usage --
- // BEGIN Android-changed
+ // BEGIN Android-removed: Remove support for java.lang.management.
/*
static {
// setup access to this package in SharedSecrets
@@ -739,7 +773,10 @@
});
}
*/
- // END Android-changed
+ // END Android-removed: Remove support for java.lang.management.
+
+ // BEGIN Android-removed: Bulk get/put methods are unused on Android.
+ /*
// -- Bulk get/put acceleration --
@@ -771,14 +808,14 @@
* destination address
* @param length
* number of bytes to copy
- */
+ *
static void copyFromArray(Object src, long srcBaseOffset, long srcPos,
long dstAddr, long length)
{
long offset = srcBaseOffset + srcPos;
while (length > 0) {
long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
- unsafe.copyMemoryFromPrimitiveArray(src, offset, dstAddr, size);
+ unsafe.copyMemory(src, offset, null, dstAddr, size);
length -= size;
offset += size;
dstAddr += size;
@@ -798,14 +835,14 @@
* offset within destination array of the first element to write
* @param length
* number of bytes to copy
- */
+ *
static void copyToArray(long srcAddr, Object dst, long dstBaseOffset, long dstPos,
long length)
{
long offset = dstBaseOffset + dstPos;
while (length > 0) {
long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
- unsafe.copyMemoryToPrimitiveArray(srcAddr, dst, offset, size);
+ unsafe.copyMemory(null, srcAddr, dst, offset, size);
length -= size;
srcAddr += size;
offset += size;
@@ -838,5 +875,5 @@
long length);
static native void copyToLongArray(long srcAddr, Object dst, long dstPos,
long length);
-
+ */
}
diff --git a/ojluni/src/main/java/java/nio/ByteBuffer.java b/ojluni/src/main/java/java/nio/ByteBuffer.java
index e4a8d0f..f29cb5d 100644
--- a/ojluni/src/main/java/java/nio/ByteBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBuffer.java
@@ -221,7 +221,8 @@
ByteBuffer(int mark, int pos, int lim, int cap, // package-private
byte[] hb, int offset)
{
- super(mark, pos, lim, cap, 0);
+ // Android-added: elementSizeShift parameter (log2 of element size).
+ super(mark, pos, lim, cap, 0 /* elementSizeShift */);
this.hb = hb;
this.offset = offset;
}
@@ -250,10 +251,8 @@
* If the <tt>capacity</tt> is a negative integer
*/
public static ByteBuffer allocateDirect(int capacity) {
- if (capacity < 0) {
- throw new IllegalArgumentException("capacity < 0: " + capacity);
- }
-
+ // Android-changed: Android's DirectByteBuffers carry a MemoryRef.
+ // return new DirectByteBuffer(capacity);
DirectByteBuffer.MemoryRef memoryRef = new DirectByteBuffer.MemoryRef(capacity);
return new DirectByteBuffer(capacity, memoryRef);
}
@@ -601,25 +600,24 @@
* If this buffer is read-only
*/
public ByteBuffer put(ByteBuffer src) {
- if (!isAccessible()) {
- throw new IllegalStateException("buffer is inaccessible");
- }
- if (src == this) {
+ if (src == this)
throw new IllegalArgumentException();
- }
- if (isReadOnly) {
+ if (isReadOnly())
throw new ReadOnlyBufferException();
- }
int n = src.remaining();
- if (n > remaining()) {
+ if (n > remaining())
throw new BufferOverflowException();
- }
+ // Android-changed: improve ByteBuffer.put(ByteBuffer) performance through bulk copy.
+ /*
+ for (int i = 0; i < n; i++)
+ put(src.get());
+ */
// Note that we use offset instead of arrayOffset because arrayOffset is specified to
// throw for read only buffers. Our use of arrayOffset here is provably safe, we only
// use it to read *from* readOnly buffers.
if (this.hb != null && src.hb != null) {
- // System.arraycopy is intrinsified by art and therefore tiny bit faster than memmove
+ // System.arraycopy is intrinsified by ART and therefore tiny bit faster than memmove
System.arraycopy(src.hb, src.position() + src.offset, hb, position() + offset, n);
} else {
// Use the buffer object (and the raw memory address) if it's a direct buffer. Note that
@@ -1086,13 +1084,10 @@
*/
public abstract char getChar(int index);
- char getCharUnchecked(int index) {
- throw new UnsupportedOperationException();
- }
-
- void getUnchecked(int pos, char[] dst, int dstOffset, int length) {
- throw new UnsupportedOperationException();
- }
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract char getCharUnchecked(int index);
+ abstract void getUnchecked(int pos, char[] dst, int dstOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
/**
* Absolute <i>put</i> method for writing a char
@@ -1119,13 +1114,10 @@
*/
public abstract ByteBuffer putChar(int index, char value);
- void putCharUnchecked(int index, char value) {
- throw new UnsupportedOperationException();
- }
-
- void putUnchecked(int pos, char[] dst, int srcOffset, int length) {
- throw new UnsupportedOperationException();
- }
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract void putCharUnchecked(int index, char value);
+ abstract void putUnchecked(int pos, char[] dst, int srcOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
/**
* Creates a view of this byte buffer as a char buffer.
@@ -1201,13 +1193,10 @@
*/
public abstract short getShort(int index);
- short getShortUnchecked(int index) {
- throw new UnsupportedOperationException();
- }
-
- void getUnchecked(int pos, short[] dst, int dstOffset, int length) {
- throw new UnsupportedOperationException();
- }
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract short getShortUnchecked(int index);
+ abstract void getUnchecked(int pos, short[] dst, int dstOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
/**
* Absolute <i>put</i> method for writing a short
@@ -1234,13 +1223,10 @@
*/
public abstract ByteBuffer putShort(int index, short value);
- void putShortUnchecked(int index, short value) {
- throw new UnsupportedOperationException();
- }
-
- void putUnchecked(int pos, short[] dst, int srcOffset, int length) {
- throw new UnsupportedOperationException();
- }
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract void putShortUnchecked(int index, short value);
+ abstract void putUnchecked(int pos, short[] dst, int srcOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
/**
* Creates a view of this byte buffer as a short buffer.
@@ -1316,13 +1302,10 @@
*/
public abstract int getInt(int index);
- int getIntUnchecked(int index) {
- throw new UnsupportedOperationException();
- }
-
- void getUnchecked(int pos, int[] dst, int dstOffset, int length) {
- throw new UnsupportedOperationException();
- }
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract int getIntUnchecked(int index);
+ abstract void getUnchecked(int pos, int[] dst, int dstOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
/**
* Absolute <i>put</i> method for writing an int
@@ -1349,13 +1332,10 @@
*/
public abstract ByteBuffer putInt(int index, int value);
- void putIntUnchecked(int index, int value) {
- throw new UnsupportedOperationException();
- }
-
- void putUnchecked(int pos, int[] dst, int srcOffset, int length) {
- throw new UnsupportedOperationException();
- }
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract void putIntUnchecked(int index, int value);
+ abstract void putUnchecked(int pos, int[] dst, int srcOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
/**
* Creates a view of this byte buffer as an int buffer.
@@ -1431,13 +1411,10 @@
*/
public abstract long getLong(int index);
- long getLongUnchecked(int index) {
- throw new UnsupportedOperationException();
- }
-
- void getUnchecked(int pos, long[] dst, int dstOffset, int length) {
- throw new UnsupportedOperationException();
- }
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract long getLongUnchecked(int index);
+ abstract void getUnchecked(int pos, long[] dst, int dstOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
/**
* Absolute <i>put</i> method for writing a long
@@ -1464,13 +1441,10 @@
*/
public abstract ByteBuffer putLong(int index, long value);
- void putLongUnchecked(int index, long value) {
- throw new UnsupportedOperationException();
- }
-
- void putUnchecked(int pos, long[] dst, int srcOffset, int length) {
- throw new UnsupportedOperationException();
- }
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract void putLongUnchecked(int index, long value);
+ abstract void putUnchecked(int pos, long[] dst, int srcOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
/**
* Creates a view of this byte buffer as a long buffer.
@@ -1546,13 +1520,10 @@
*/
public abstract float getFloat(int index);
- float getFloatUnchecked(int index) {
- throw new UnsupportedOperationException();
- }
-
- void getUnchecked(int pos, float[] dst, int dstOffset, int length) {
- throw new UnsupportedOperationException();
- }
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract float getFloatUnchecked(int index);
+ abstract void getUnchecked(int pos, float[] dst, int dstOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
/**
* Absolute <i>put</i> method for writing a float
@@ -1579,13 +1550,10 @@
*/
public abstract ByteBuffer putFloat(int index, float value);
- void putFloatUnchecked(int index, float value) {
- throw new UnsupportedOperationException();
- }
-
- void putUnchecked(int pos, float[] dst, int srcOffset, int length) {
- throw new UnsupportedOperationException();
- }
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract void putFloatUnchecked(int index, float value);
+ abstract void putUnchecked(int pos, float[] dst, int srcOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
/**
* Creates a view of this byte buffer as a float buffer.
@@ -1661,13 +1629,10 @@
*/
public abstract double getDouble(int index);
- double getDoubleUnchecked(int index) {
- throw new UnsupportedOperationException();
- }
-
- void getUnchecked(int pos, double[] dst, int dstOffset, int length) {
- throw new UnsupportedOperationException();
- }
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract double getDoubleUnchecked(int index);
+ abstract void getUnchecked(int pos, double[] dst, int dstOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
/**
* Absolute <i>put</i> method for writing a double
@@ -1694,13 +1659,10 @@
*/
public abstract ByteBuffer putDouble(int index, double value);
- void putDoubleUnchecked(int index, double value) {
- throw new UnsupportedOperationException();
- }
-
- void putUnchecked(int pos, double[] dst, int srcOffset, int length) {
- throw new UnsupportedOperationException();
- }
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract void putDoubleUnchecked(int index, double value);
+ abstract void putUnchecked(int pos, double[] dst, int srcOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
/**
* Creates a view of this byte buffer as a double buffer.
@@ -1720,6 +1682,7 @@
*/
public abstract DoubleBuffer asDoubleBuffer();
+ // BEGIN Android-added: isAccessible(), setAccessible(), for use by frameworks (MediaCodec).
/**
* @hide
*/
@@ -1733,4 +1696,5 @@
public void setAccessible(boolean value) {
throw new UnsupportedOperationException();
}
+ // END Android-added: isAccessible(), setAccessible(), for use by frameworks (MediaCodec).
}
diff --git a/ojluni/src/main/java/java/nio/CharBuffer.java b/ojluni/src/main/java/java/nio/CharBuffer.java
index 61265d7..fa7423e 100644
--- a/ojluni/src/main/java/java/nio/CharBuffer.java
+++ b/ojluni/src/main/java/java/nio/CharBuffer.java
@@ -135,7 +135,8 @@
CharBuffer(int mark, int pos, int lim, int cap, // package-private
char[] hb, int offset)
{
- super(mark, pos, lim, cap, 1);
+ // Android-added: elementSizeShift parameter (log2 of element size).
+ super(mark, pos, lim, cap, 1 /* elementSizeShift */);
this.hb = hb;
this.offset = offset;
}
@@ -532,9 +533,14 @@
* <pre>
* src.get(a, 0, a.length) </pre>
*
- * @return This buffer
- * @throws BufferUnderflowException If there are fewer than <tt>length</tt> chars
- * remaining in this buffer
+ * @param dst
+ * The destination array
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> chars
+ * remaining in this buffer
*/
public CharBuffer get(char[] dst) {
return get(dst, 0, dst.length);
@@ -587,6 +593,8 @@
public CharBuffer put(CharBuffer src) {
if (src == this)
throw new IllegalArgumentException();
+ if (isReadOnly())
+ throw new ReadOnlyBufferException();
int n = src.remaining();
if (n > remaining())
throw new BufferOverflowException();
@@ -739,22 +747,17 @@
public CharBuffer put(String src, int start, int end) {
checkBounds(start, end - start, src.length());
- // Android-changed: Don't bother making changes to the buffer if there's nothing
- // to write. This is questionable behaviour but code expects it.
+ // BEGIN Android-added: Don't check readonly/overflow if there's nothing to write.
+ // This is questionable behaviour but code expects it.
if (start == end) {
return this;
}
+ // END Android-added: Don't check readonly/overflow if there's nothing to write.
- // Android-changed: Throw ReadOnlyBufferException as soon as possible.
- if (isReadOnly()) {
+ if (isReadOnly())
throw new ReadOnlyBufferException();
- }
-
- // Android-changed: Throw as early as we can if there isn't enough space.
- if ((end - start) > remaining()) {
+ if (end - start > remaining())
throw new BufferOverflowException();
- }
-
for (int i = start; i < end; i++)
this.put(src.charAt(i));
return this;
@@ -1219,8 +1222,7 @@
@Override
public IntStream chars() {
- CharBuffer self = this;
- return StreamSupport.intStream(() -> new CharBufferSpliterator(self),
+ return StreamSupport.intStream(() -> new CharBufferSpliterator(this),
Buffer.SPLITERATOR_CHARACTERISTICS, false);
}
}
diff --git a/ojluni/src/main/java/java/nio/DirectByteBuffer.java b/ojluni/src/main/java/java/nio/DirectByteBuffer.java
index badde5a..f12fd7b 100644
--- a/ojluni/src/main/java/java/nio/DirectByteBuffer.java
+++ b/ojluni/src/main/java/java/nio/DirectByteBuffer.java
@@ -34,8 +34,8 @@
import sun.misc.Cleaner;
import sun.nio.ch.DirectBuffer;
-/** @hide */
// Not final because it is extended in tests.
+/** @hide */
public class DirectByteBuffer extends MappedByteBuffer implements DirectBuffer {
/**
@@ -250,6 +250,14 @@
}
@Override
+ public ByteBuffer put(ByteBuffer src) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return super.put(src);
+ }
+
+ @Override
public final ByteBuffer put(byte x) {
if (!memoryRef.isAccessible) {
throw new IllegalStateException("buffer is inaccessible");
diff --git a/ojluni/src/main/java/java/nio/DoubleBuffer.java b/ojluni/src/main/java/java/nio/DoubleBuffer.java
index d0a0c15..9c3ff87 100644
--- a/ojluni/src/main/java/java/nio/DoubleBuffer.java
+++ b/ojluni/src/main/java/java/nio/DoubleBuffer.java
@@ -108,7 +108,8 @@
DoubleBuffer(int mark, int pos, int lim, int cap, // package-private
double[] hb, int offset)
{
- super(mark, pos, lim, cap, 3);
+ // Android-added: elementSizeShift parameter (log2 of element size).
+ super(mark, pos, lim, cap, 3 /* elementSizeShift */);
this.hb = hb;
this.offset = offset;
}
@@ -464,6 +465,8 @@
public DoubleBuffer put(DoubleBuffer src) {
if (src == this)
throw new IllegalArgumentException();
+ if (isReadOnly())
+ throw new ReadOnlyBufferException();
int n = src.remaining();
if (n > remaining())
throw new BufferOverflowException();
@@ -784,9 +787,7 @@
public int compareTo(DoubleBuffer that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
for (int i = this.position(), j = that.position(); i < n; i++, j++) {
- // Android-changed: Call through to Double.compare() instead of
- // duplicating code pointlessly.
- int cmp = Double.compare(this.get(i), that.get(j));
+ int cmp = compare(this.get(i), that.get(j));
if (cmp != 0)
return cmp;
}
diff --git a/ojluni/src/main/java/java/nio/FloatBuffer.java b/ojluni/src/main/java/java/nio/FloatBuffer.java
index 90e65ff..04eac35 100644
--- a/ojluni/src/main/java/java/nio/FloatBuffer.java
+++ b/ojluni/src/main/java/java/nio/FloatBuffer.java
@@ -108,7 +108,8 @@
FloatBuffer(int mark, int pos, int lim, int cap, // package-private
float[] hb, int offset)
{
- super(mark, pos, lim, cap, 2);
+ // Android-added: elementSizeShift parameter (log2 of element size).
+ super(mark, pos, lim, cap, 2 /* elementSizeShift */);
this.hb = hb;
this.offset = offset;
}
@@ -464,6 +465,8 @@
public FloatBuffer put(FloatBuffer src) {
if (src == this)
throw new IllegalArgumentException();
+ if (isReadOnly())
+ throw new ReadOnlyBufferException();
int n = src.remaining();
if (n > remaining())
throw new BufferOverflowException();
diff --git a/ojluni/src/main/java/java/nio/IntBuffer.java b/ojluni/src/main/java/java/nio/IntBuffer.java
index a0004ba..a8cfff8 100644
--- a/ojluni/src/main/java/java/nio/IntBuffer.java
+++ b/ojluni/src/main/java/java/nio/IntBuffer.java
@@ -109,7 +109,8 @@
IntBuffer(int mark, int pos, int lim, int cap, // package-private
int[] hb, int offset)
{
- super(mark, pos, lim, cap, 2);
+ // Android-added: elementSizeShift parameter (log2 of element size).
+ super(mark, pos, lim, cap, 2 /* elementSizeShift */);
this.hb = hb;
this.offset = offset;
}
@@ -465,6 +466,8 @@
public IntBuffer put(IntBuffer src) {
if (src == this)
throw new IllegalArgumentException();
+ if (isReadOnly())
+ throw new ReadOnlyBufferException();
int n = src.remaining();
if (n > remaining())
throw new BufferOverflowException();
diff --git a/ojluni/src/main/java/java/nio/LongBuffer.java b/ojluni/src/main/java/java/nio/LongBuffer.java
index 80e506c..c64b8f5 100644
--- a/ojluni/src/main/java/java/nio/LongBuffer.java
+++ b/ojluni/src/main/java/java/nio/LongBuffer.java
@@ -108,7 +108,8 @@
LongBuffer(int mark, int pos, int lim, int cap, // package-private
long[] hb, int offset)
{
- super(mark, pos, lim, cap, 3);
+ // Android-added: elementSizeShift parameter (log2 of element size).
+ super(mark, pos, lim, cap, 3 /* elementSizeShift */);
this.hb = hb;
this.offset = offset;
}
@@ -464,6 +465,8 @@
public LongBuffer put(LongBuffer src) {
if (src == this)
throw new IllegalArgumentException();
+ if (isReadOnly())
+ throw new ReadOnlyBufferException();
int n = src.remaining();
if (n > remaining())
throw new BufferOverflowException();
diff --git a/ojluni/src/main/java/java/nio/ShortBuffer.java b/ojluni/src/main/java/java/nio/ShortBuffer.java
index 6903b54..13a689f 100644
--- a/ojluni/src/main/java/java/nio/ShortBuffer.java
+++ b/ojluni/src/main/java/java/nio/ShortBuffer.java
@@ -108,7 +108,8 @@
ShortBuffer(int mark, int pos, int lim, int cap, // package-private
short[] hb, int offset)
{
- super(mark, pos, lim, cap, 1);
+ // Android-added: elementSizeShift parameter (log2 of element size).
+ super(mark, pos, lim, cap, 1 /* elementSizeShift */);
this.hb = hb;
this.offset = offset;
}
@@ -464,6 +465,8 @@
public ShortBuffer put(ShortBuffer src) {
if (src == this)
throw new IllegalArgumentException();
+ if (isReadOnly())
+ throw new ReadOnlyBufferException();
int n = src.remaining();
if (n > remaining())
throw new BufferOverflowException();
diff --git a/ojluni/src/main/java/java/nio/charset/CharsetDecoder.java b/ojluni/src/main/java/java/nio/charset/CharsetDecoder.java
index 8e265d6..34065ee 100644
--- a/ojluni/src/main/java/java/nio/charset/CharsetDecoder.java
+++ b/ojluni/src/main/java/java/nio/charset/CharsetDecoder.java
@@ -87,9 +87,9 @@
* <a name="cae"></a>
*
* <p> How a decoding error is handled depends upon the action requested for
- * that type of error, which is described by an instance of the {@linkplain
+ * that type of error, which is described by an instance of the {@link
* CodingErrorAction} class. The possible error actions are to {@linkplain
- * CodingErrorAction#IGNORE ignore} the erroneous input, {@link
+ * CodingErrorAction#IGNORE ignore} the erroneous input, {@linkplain
* CodingErrorAction#REPORT report} the error to the invoker via
* the returned {@link CoderResult} object, or {@linkplain CodingErrorAction#REPLACE
* replace} the erroneous input with the current value of the
@@ -164,7 +164,7 @@
* Initializes a new decoder. The new decoder will have the given
* chars-per-byte and replacement values.
*
- * * @param cs
+ * @param cs
* The charset that created this decoder
*
* @param averageCharsPerByte
@@ -253,7 +253,12 @@
* which is never <tt>null</tt> and is never empty
*/
public final String replacement() {
+
return replacement;
+
+
+
+
}
/**
@@ -296,6 +301,7 @@
+
implReplaceWith(this.replacement);
return this;
}
@@ -452,7 +458,7 @@
/**
* Returns the maximum number of characters that will be produced for each
* byte of input. This value may be used to compute the worst-case size
- * of the output buffer required for a given input sequence. </p>
+ * of the output buffer required for a given input sequence.
*
* @return The maximum number of characters that will be produced per
* byte of input
@@ -978,6 +984,12 @@
+
+
+
+
+
+
private void throwIllegalStateException(int from, int to) {
throw new IllegalStateException("Current state = " + stateNames[from]
+ ", new state = " + stateNames[to]);
diff --git a/ojluni/src/main/java/java/nio/charset/IllegalCharsetNameException.java b/ojluni/src/main/java/java/nio/charset/IllegalCharsetNameException.java
index 38962af..9124282 100644
--- a/ojluni/src/main/java/java/nio/charset/IllegalCharsetNameException.java
+++ b/ojluni/src/main/java/java/nio/charset/IllegalCharsetNameException.java
@@ -46,7 +46,7 @@
private String charsetName;
/**
- * Constructs an instance of this class. </p>
+ * Constructs an instance of this class.
*
* @param charsetName
* The illegal charset name
@@ -57,7 +57,7 @@
}
/**
- * Retrieves the illegal charset name. </p>
+ * Retrieves the illegal charset name.
*
* @return The illegal charset name
*/
diff --git a/ojluni/src/main/java/java/nio/charset/UnsupportedCharsetException.java b/ojluni/src/main/java/java/nio/charset/UnsupportedCharsetException.java
index 6c04cb1..1774fc0 100644
--- a/ojluni/src/main/java/java/nio/charset/UnsupportedCharsetException.java
+++ b/ojluni/src/main/java/java/nio/charset/UnsupportedCharsetException.java
@@ -46,7 +46,7 @@
private String charsetName;
/**
- * Constructs an instance of this class. </p>
+ * Constructs an instance of this class.
*
* @param charsetName
* The name of the unsupported charset
@@ -57,7 +57,7 @@
}
/**
- * Retrieves the name of the unsupported charset. </p>
+ * Retrieves the name of the unsupported charset.
*
* @return The name of the unsupported charset
*/
diff --git a/ojluni/src/main/java/java/security/cert/X509CRL.java b/ojluni/src/main/java/java/security/cert/X509CRL.java
index a233b44..927852b 100644
--- a/ojluni/src/main/java/java/security/cert/X509CRL.java
+++ b/ojluni/src/main/java/java/security/cert/X509CRL.java
@@ -241,16 +241,17 @@
public void verify(PublicKey key, Provider sigProvider)
throws CRLException, NoSuchAlgorithmException,
InvalidKeyException, SignatureException {
- // BEGIN Android-changed
- // TODO(31294527): was X509CRLImpl.verify(this, key, sigProvider);
+ // Android-changed: Eliminate infinite recursion in default implementation.
// As the javadoc says, this "default implementation" was introduced as to avoid breaking
// providers that generate concrete subclasses of this class.
// The method X509Impl in the original definition calls this method, thus entering an
- // infinite loop. This strange behaviour was checked to be not specific to libcore by
- // running a test with vogar --mode=jvm .
+ // infinite recursive loop. This strange behaviour was checked to be not specific to
+ // libcore by running a test with vogar --mode=jvm . See b/31294527.
+ // This is fixed upstream in OpenJDK 10.
+ //
+ // X509CRLImpl.verify(this, key, sigProvider);
throw new UnsupportedOperationException(
"X509CRL instance doesn't not support X509CRL#verify(PublicKey, Provider)");
- // END Android-changed
}
/**
diff --git a/ojluni/src/main/java/java/security/cert/X509Certificate.java b/ojluni/src/main/java/java/security/cert/X509Certificate.java
index 042eefd..f7cb9ef 100644
--- a/ojluni/src/main/java/java/security/cert/X509Certificate.java
+++ b/ojluni/src/main/java/java/security/cert/X509Certificate.java
@@ -673,11 +673,11 @@
public void verify(PublicKey key, Provider sigProvider)
throws CertificateException, NoSuchAlgorithmException,
InvalidKeyException, SignatureException {
- // Android-changed: Use Certificate default implementation that
- // throws UnsupportedOperationException.
+ // Android-changed: Eliminate infinite recursion in default implementation.
// The method X509CertImpl calls this method, thus entering an
- // infinite loop. This strange behaviour was checked to be not
- // specific to libcore by running a test with vogar --mode=jvm
+ // infinite recursive loop. This strange behaviour was checked to be not
+ // specific to libcore by running a test with vogar --mode=jvm.
+ // This is fixed upstream in OpenJDK 10.
//
// X509CertImpl.verify(this, key, sigProvider);
super.verify(key, sigProvider);
diff --git a/ojluni/src/main/java/java/sql/CallableStatement.java b/ojluni/src/main/java/java/sql/CallableStatement.java
index b4769e3..d58c88b 100644
--- a/ojluni/src/main/java/java/sql/CallableStatement.java
+++ b/ojluni/src/main/java/java/sql/CallableStatement.java
@@ -296,6 +296,7 @@
* or <code>getBigDecimal(String parameterName)</code>
* @see #setBigDecimal
*/
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
@Deprecated
BigDecimal getBigDecimal(int parameterIndex, int scale)
throws SQLException;
@@ -2438,4 +2439,6 @@
*/
void setNClob(String parameterName, Reader reader)
throws SQLException;
+
+ // Android-removed: JDBC 4.1 methods were removed immediately after the initial import.
}
diff --git a/ojluni/src/main/java/java/sql/Connection.java b/ojluni/src/main/java/java/sql/Connection.java
index 3acfd12..b742388 100644
--- a/ojluni/src/main/java/java/sql/Connection.java
+++ b/ojluni/src/main/java/java/sql/Connection.java
@@ -1303,4 +1303,5 @@
Struct createStruct(String typeName, Object[] attributes)
throws SQLException;
+ // Android-removed: JDBC 4.1 methods were removed immediately after the initial import.
}
diff --git a/ojluni/src/main/java/java/sql/DatabaseMetaData.java b/ojluni/src/main/java/java/sql/DatabaseMetaData.java
index 98101ce..8e7441c 100644
--- a/ojluni/src/main/java/java/sql/DatabaseMetaData.java
+++ b/ojluni/src/main/java/java/sql/DatabaseMetaData.java
@@ -3574,4 +3574,5 @@
*/
int functionReturnsTable = 2;
+ // Android-removed: JDBC 4.1 methods were removed immediately after the initial import.
}
diff --git a/ojluni/src/main/java/java/sql/Date.java b/ojluni/src/main/java/java/sql/Date.java
index a64a42f..b96828a 100644
--- a/ojluni/src/main/java/java/sql/Date.java
+++ b/ojluni/src/main/java/java/sql/Date.java
@@ -52,7 +52,8 @@
* @param day 1 to 31
* @deprecated instead use the constructor <code>Date(long date)</code>
*/
- @Deprecated // Android-added
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+ @Deprecated
public Date(int year, int month, int day) {
super(year, month, day);
}
@@ -172,6 +173,7 @@
// Override all the time operations inherited from java.util.Date;
+ // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
/**
* @deprecated This method is deprecated and should not be used because SQL Date
* values do not have a time component.
@@ -179,11 +181,13 @@
* @exception java.lang.IllegalArgumentException if this method is invoked
* @see #setHours
*/
- @Deprecated // Android-added: changed javadoc to include deprecation note.
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+ @Deprecated
public int getHours() {
throw new java.lang.IllegalArgumentException();
}
+ // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
/**
* @deprecated This method is deprecated and should not be used because SQL Date
* values do not have a time component.
@@ -191,11 +195,13 @@
* @exception java.lang.IllegalArgumentException if this method is invoked
* @see #setMinutes
*/
- @Deprecated // Android-added: changed javadoc to include deprecation note.
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+ @Deprecated
public int getMinutes() {
throw new java.lang.IllegalArgumentException();
}
+ // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
/**
* @deprecated This method is deprecated and should not be used because SQL Date
* values do not have a time component.
@@ -203,11 +209,13 @@
* @exception java.lang.IllegalArgumentException if this method is invoked
* @see #setSeconds
*/
- @Deprecated // Android-added: changed javadoc to include deprecation note.
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+ @Deprecated
public int getSeconds() {
throw new java.lang.IllegalArgumentException();
}
+ // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
/**
* @deprecated This method is deprecated and should not be used because SQL Date
* values do not have a time component.
@@ -215,11 +223,13 @@
* @exception java.lang.IllegalArgumentException if this method is invoked
* @see #getHours
*/
- @Deprecated // Android-added: changed javadoc to include deprecation note.
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+ @Deprecated
public void setHours(int i) {
throw new java.lang.IllegalArgumentException();
}
+ // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
/**
* @deprecated This method is deprecated and should not be used because SQL Date
* values do not have a time component.
@@ -227,11 +237,13 @@
* @exception java.lang.IllegalArgumentException if this method is invoked
* @see #getMinutes
*/
- @Deprecated // Android-added: changed javadoc to include deprecation note.
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+ @Deprecated
public void setMinutes(int i) {
throw new java.lang.IllegalArgumentException();
}
+ // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
/**
* @deprecated This method is deprecated and should not be used because SQL Date
* values do not have a time component.
@@ -239,7 +251,8 @@
* @exception java.lang.IllegalArgumentException if this method is invoked
* @see #getSeconds
*/
- @Deprecated // Android-added: changed javadoc to include deprecation note.
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+ @Deprecated
public void setSeconds(int i) {
throw new java.lang.IllegalArgumentException();
}
diff --git a/ojluni/src/main/java/java/sql/Driver.java b/ojluni/src/main/java/java/sql/Driver.java
index a9bdc7d..3970b1c 100644
--- a/ojluni/src/main/java/java/sql/Driver.java
+++ b/ojluni/src/main/java/java/sql/Driver.java
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2014 The Android Open Source Project
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -153,4 +154,5 @@
*/
boolean jdbcCompliant();
+ // Android-removed: JDBC 4.1 methods were removed immediately after the initial import.
}
diff --git a/ojluni/src/main/java/java/sql/DriverManager.java b/ojluni/src/main/java/java/sql/DriverManager.java
index e7d9c94..a1c378a 100644
--- a/ojluni/src/main/java/java/sql/DriverManager.java
+++ b/ojluni/src/main/java/java/sql/DriverManager.java
@@ -26,8 +26,6 @@
package java.sql;
-import dalvik.system.VMStack;
-
import java.util.Iterator;
import java.util.ServiceLoader;
import java.security.AccessController;
@@ -35,7 +33,9 @@
import java.util.concurrent.CopyOnWriteArrayList;
import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
+// Android-changed line 2 of the javadoc to "{@code DataSource}".
/**
* <P>The basic service for managing a set of JDBC drivers.<br>
* <B>NOTE:</B> The {@code DataSource} interface, new in the
@@ -80,7 +80,6 @@
* @see Driver
* @see Connection
*/
-// Android-changed line 2 of the javadoc to "{@code DataSource}"
public class DriverManager {
@@ -188,7 +187,7 @@
@CallerSensitive
public static Connection getConnection(String url,
java.util.Properties info) throws SQLException {
- return (getConnection(url, info, VMStack.getCallingClassLoader()));
+ return (getConnection(url, info, Reflection.getCallerClass()));
}
/**
@@ -216,7 +215,7 @@
info.put("password", password);
}
- return (getConnection(url, info, VMStack.getCallingClassLoader()));
+ return (getConnection(url, info, Reflection.getCallerClass()));
}
/**
@@ -234,7 +233,7 @@
throws SQLException {
java.util.Properties info = new java.util.Properties();
- return (getConnection(url, info, VMStack.getCallingClassLoader()));
+ return (getConnection(url, info, Reflection.getCallerClass()));
}
/**
@@ -254,14 +253,14 @@
println("DriverManager.getDriver(\"" + url + "\")");
- ClassLoader callerClassLoader = VMStack.getCallingClassLoader();
+ Class<?> callerClass = Reflection.getCallerClass();
// Walk through the loaded registeredDrivers attempting to locate someone
// who understands the given URL.
for (DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
- if(isDriverAllowed(aDriver.driver, callerClassLoader)) {
+ if(isDriverAllowed(aDriver.driver, callerClass)) {
try {
if(aDriver.driver.acceptsURL(url)) {
// Success!
@@ -326,7 +325,7 @@
DriverInfo aDriver = new DriverInfo(driver);
if(registeredDrivers.contains(aDriver)) {
- if (isDriverAllowed(driver, VMStack.getCallingClassLoader())) {
+ if (isDriverAllowed(driver, Reflection.getCallerClass())) {
registeredDrivers.remove(aDriver);
} else {
// If the caller does not have permission to load the driver then
@@ -351,13 +350,13 @@
public static java.util.Enumeration<Driver> getDrivers() {
java.util.Vector<Driver> result = new java.util.Vector<Driver>();
- ClassLoader callerClassLoader = VMStack.getCallingClassLoader();
+ Class<?> callerClass = Reflection.getCallerClass();
// Walk through the loaded registeredDrivers.
for(DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
- if(isDriverAllowed(aDriver.driver, callerClassLoader)) {
+ if(isDriverAllowed(aDriver.driver, callerClass)) {
result.addElement(aDriver.driver);
} else {
println(" skipping: " + aDriver.getClass().getName());
@@ -389,6 +388,7 @@
return (loginTimeout);
}
+ // Android-changed: Added reason to @deprecated to improve the documentation.
/**
* Sets the logging/tracing PrintStream that is used
* by the <code>DriverManager</code>
@@ -408,7 +408,8 @@
* @see SecurityManager#checkPermission
* @see #getLogStream
*/
- @Deprecated // Android-added, also changed deprecation comment to include a reason.
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+ @Deprecated
public static void setLogStream(java.io.PrintStream out) {
SecurityManager sec = System.getSecurityManager();
@@ -423,6 +424,7 @@
logWriter = null;
}
+ // Android-changed: Added reason to @deprecated to improve the documentation.
/**
* Retrieves the logging/tracing PrintStream that is used by the <code>DriverManager</code>
* and all drivers.
@@ -431,7 +433,8 @@
* @deprecated Use {@code getLogWriter} instead.
* @see #setLogStream
*/
- @Deprecated // Android-added, also changed deprecation comment to include a reason.
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+ @Deprecated
public static java.io.PrintStream getLogStream() {
return logStream;
}
@@ -454,6 +457,13 @@
//------------------------------------------------------------------------
+ // Indicates whether the class object that would be created if the code calling
+ // DriverManager is accessible.
+ private static boolean isDriverAllowed(Driver driver, Class<?> caller) {
+ ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
+ return isDriverAllowed(driver, callerCL);
+ }
+
private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) {
boolean result = false;
if(driver != null) {
@@ -536,13 +546,14 @@
// Worker method called by the public getConnection() methods.
private static Connection getConnection(
- String url, java.util.Properties info, ClassLoader callerCL) throws SQLException {
+ String url, java.util.Properties info, Class<?> caller) throws SQLException {
/*
* When callerCl is null, we should check the application's
* (which is invoking this class indirectly)
* classloader, so that the JDBC driver class outside rt.jar
* can be loaded from here.
*/
+ ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
synchronized (DriverManager.class) {
// synchronize loading of the correct classloader.
if (callerCL == null) {
diff --git a/ojluni/src/main/java/java/sql/PreparedStatement.java b/ojluni/src/main/java/java/sql/PreparedStatement.java
index 0763390..ef57f69 100644
--- a/ojluni/src/main/java/java/sql/PreparedStatement.java
+++ b/ojluni/src/main/java/java/sql/PreparedStatement.java
@@ -317,6 +317,7 @@
void setAsciiStream(int parameterIndex, java.io.InputStream x, int length)
throws SQLException;
+ // Android-changed: Added reason to @deprecated to improve the documentation.
/**
* Sets the designated parameter to the given input stream, which
* will have the specified number of bytes.
@@ -343,8 +344,9 @@
* this method is called on a closed <code>PreparedStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @deprecated Deprecated.
+ * @deprecated Use setCharacterStream
*/
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
@Deprecated
void setUnicodeStream(int parameterIndex, java.io.InputStream x,
int length) throws SQLException;
diff --git a/ojluni/src/main/java/java/sql/ResultSet.java b/ojluni/src/main/java/java/sql/ResultSet.java
index 0b1f6a0..f9ca407 100644
--- a/ojluni/src/main/java/java/sql/ResultSet.java
+++ b/ojluni/src/main/java/java/sql/ResultSet.java
@@ -343,6 +343,7 @@
*/
double getDouble(int columnIndex) throws SQLException;
+ // Android-changed: Added reason to @deprecated to improve the documentation.
/**
* Retrieves the value of the designated column in the current row
* of this <code>ResultSet</code> object as
@@ -360,6 +361,7 @@
* @deprecated Use {@code getBigDecimal(int columnIndex)}
* or {@code getBigDecimal(String columnLabel)}
*/
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
@Deprecated
BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException;
@@ -480,6 +482,7 @@
* @deprecated use <code>getCharacterStream</code> in place of
* <code>getUnicodeStream</code>
*/
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
@Deprecated
java.io.InputStream getUnicodeStream(int columnIndex) throws SQLException;
@@ -631,6 +634,7 @@
*/
double getDouble(String columnLabel) throws SQLException;
+ // Android-changed: Added reason to @deprecated to improve the documentation.
/**
* Retrieves the value of the designated column in the current row
* of this <code>ResultSet</code> object as
@@ -648,6 +652,7 @@
* @deprecated Use {@code getBigDecimal(int columnIndex)}
* or {@code getBigDecimal(String columnLabel)}
*/
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
@Deprecated
BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException;
@@ -766,6 +771,7 @@
* this method
* @deprecated use <code>getCharacterStream</code> instead
*/
+ // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
@Deprecated
java.io.InputStream getUnicodeStream(String columnLabel) throws SQLException;
@@ -4083,4 +4089,5 @@
*/
void updateNClob(String columnLabel, Reader reader) throws SQLException;
+ // Android-removed: JDBC 4.1 methods were removed immediately after the initial import.
}
diff --git a/ojluni/src/main/java/java/sql/SQLPermission.java b/ojluni/src/main/java/java/sql/SQLPermission.java
index 505202c..d90cf64 100644
--- a/ojluni/src/main/java/java/sql/SQLPermission.java
+++ b/ojluni/src/main/java/java/sql/SQLPermission.java
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2014 The Android Open Source Project
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -23,6 +24,7 @@
* questions.
*/
+
package java.sql;
import java.security.*;
diff --git a/ojluni/src/main/java/java/sql/SQLXML.java b/ojluni/src/main/java/java/sql/SQLXML.java
index 88e3baa..e27edf5 100644
--- a/ojluni/src/main/java/java/sql/SQLXML.java
+++ b/ojluni/src/main/java/java/sql/SQLXML.java
@@ -33,6 +33,8 @@
import javax.xml.transform.Result;
import javax.xml.transform.Source;
+// Android-changed: Removed @see tag (target does not exist on Android):
+// @see javax.xml.stream
/**
* The mapping in the JavaTM programming language for the SQL XML type.
* XML is a built-in type that stores an XML value
@@ -183,7 +185,6 @@
* JDBC driver supports the data type.
*
* @see javax.xml.parsers
- * @see javax.xml.stream
* @see javax.xml.transform
* @see javax.xml.xpath
* @since 1.6
diff --git a/ojluni/src/main/java/java/sql/Statement.java b/ojluni/src/main/java/java/sql/Statement.java
index 40cd97c..5915114 100644
--- a/ojluni/src/main/java/java/sql/Statement.java
+++ b/ojluni/src/main/java/java/sql/Statement.java
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2014 The Android Open Source Project
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -1030,4 +1031,5 @@
boolean isPoolable()
throws SQLException;
+ // Android-removed: JDBC 4.1 methods were removed immediately after the initial import.
}
diff --git a/ojluni/src/main/java/java/sql/Time.java b/ojluni/src/main/java/java/sql/Time.java
index 4960ce5..1300003 100644
--- a/ojluni/src/main/java/java/sql/Time.java
+++ b/ojluni/src/main/java/java/sql/Time.java
@@ -144,6 +144,7 @@
// Override all the date operations inherited from java.util.Date;
+ // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
/**
* @deprecated This method is deprecated and should not be used because SQL <code>TIME</code>
* values do not have a year component.
@@ -152,12 +153,12 @@
* method is invoked
* @see #setYear
*/
- // Android-changed javadoc, @deprecated tag now has a reason.
@Deprecated
public int getYear() {
throw new java.lang.IllegalArgumentException();
}
+ // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
/**
* @deprecated This method is deprecated and should not be used because SQL <code>TIME</code>
* values do not have a month component.
@@ -166,12 +167,12 @@
* method is invoked
* @see #setMonth
*/
- // Android-changed javadoc, @deprecated tag now has a reason.
@Deprecated
public int getMonth() {
throw new java.lang.IllegalArgumentException();
}
+ // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
/**
* @deprecated This method is deprecated and should not be used because SQL <code>TIME</code>
* values do not have a day component.
@@ -179,12 +180,12 @@
* @exception java.lang.IllegalArgumentException if this
* method is invoked
*/
- // Android-changed javadoc, @deprecated tag now has a reason.
@Deprecated
public int getDay() {
throw new java.lang.IllegalArgumentException();
}
+ // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
/**
* @deprecated This method is deprecated and should not be used because SQL <code>TIME</code>
* values do not have a date component.
@@ -193,12 +194,12 @@
* method is invoked
* @see #setDate
*/
- // Android-changed javadoc, @deprecated tag now has a reason.
@Deprecated
public int getDate() {
throw new java.lang.IllegalArgumentException();
}
+ // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
/**
* @deprecated This method is deprecated and should not be used because SQL <code>TIME</code>
* values do not have a year component.
@@ -207,12 +208,12 @@
* method is invoked
* @see #getYear
*/
- // Android-changed javadoc, @deprecated tag now has a reason.
@Deprecated
public void setYear(int i) {
throw new java.lang.IllegalArgumentException();
}
+ // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
/**
* @deprecated This method is deprecated and should not be used because SQL <code>TIME</code>
* values do not have a month component.
@@ -221,12 +222,12 @@
* method is invoked
* @see #getMonth
*/
- // Android-changed javadoc, @deprecated tag now has a reason.
@Deprecated
public void setMonth(int i) {
throw new java.lang.IllegalArgumentException();
}
+ // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
/**
* @deprecated This method is deprecated and should not be used because SQL <code>TIME</code>
* values do not have a date component.
diff --git a/ojluni/src/main/java/java/text/DecimalFormat.java b/ojluni/src/main/java/java/text/DecimalFormat.java
index 2cb1473..93ed4a3 100644
--- a/ojluni/src/main/java/java/text/DecimalFormat.java
+++ b/ojluni/src/main/java/java/text/DecimalFormat.java
@@ -49,8 +49,6 @@
import java.util.Currency;
import java.util.Locale;
import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import libcore.icu.LocaleData;
diff --git a/ojluni/src/main/java/java/text/DecimalFormatSymbols.java b/ojluni/src/main/java/java/text/DecimalFormatSymbols.java
index 070fd1c..6686d8b 100644
--- a/ojluni/src/main/java/java/text/DecimalFormatSymbols.java
+++ b/ojluni/src/main/java/java/text/DecimalFormatSymbols.java
@@ -46,7 +46,6 @@
import java.io.Serializable;
import java.util.Currency;
import java.util.Locale;
-import java.util.concurrent.ConcurrentHashMap;
import libcore.icu.ICU;
import libcore.icu.LocaleData;
diff --git a/ojluni/src/main/java/java/text/MessageFormat.java b/ojluni/src/main/java/java/text/MessageFormat.java
index b900824..4a48e9c 100644
--- a/ojluni/src/main/java/java/text/MessageFormat.java
+++ b/ojluni/src/main/java/java/text/MessageFormat.java
@@ -692,7 +692,9 @@
public void setFormat(int formatElementIndex, Format newFormat) {
// Android-added: prevent setting unused formatters.
if (formatElementIndex > maxOffset) {
- throw new ArrayIndexOutOfBoundsException(maxOffset, formatElementIndex);
+ // Note: maxOffset is maximum index, not the length.
+ throw new ArrayIndexOutOfBoundsException(
+ "maxOffset=" + maxOffset + "; formatElementIndex=" + formatElementIndex);
}
formats[formatElementIndex] = newFormat;
}
diff --git a/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java b/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java
index 69e35d6..736a8fc 100644
--- a/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java
+++ b/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java
@@ -102,7 +102,6 @@
import java.time.temporal.ValueRange;
import java.time.temporal.WeekFields;
import java.time.zone.ZoneRulesProvider;
-import java.util.AbstractMap;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
import java.util.Collections;
@@ -212,6 +211,10 @@
}
// Android-changed: get format string from ICU.
+ // LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased()
+ // .getLocaleResources(locale);
+ // String pattern = lr.getJavaTimeDateTimePattern(
+ // convertStyle(timeStyle), convertStyle(dateStyle), chrono.getCalendarType());
String pattern = Calendar.getDateTimeFormatString(
ULocale.forLocale(locale), chrono.getCalendarType(),
convertStyle(dateStyle), convertStyle(timeStyle));
@@ -3675,8 +3678,22 @@
SoftReference<Map<Locale, String[]>> ref = cache.get(id);
Map<Locale, String[]> perLocale = null;
if (ref == null || (perLocale = ref.get()) == null ||
- (names = perLocale.get(locale)) == null) {
+ (names = perLocale.get(locale)) == null) {
// BEGIN Android-changed: use ICU TimeZoneNames instead of TimeZoneNameUtility.
+ /*
+ names = TimeZoneNameUtility.retrieveDisplayNames(id, locale);
+ if (names == null) {
+ return null;
+ }
+ names = Arrays.copyOfRange(names, 0, 7);
+ names[5] =
+ TimeZoneNameUtility.retrieveGenericDisplayName(id, TimeZone.LONG, locale);
+ if (names[5] == null) {
+ names[5] = names[0]; // use the id
+ }
+ names[6] =
+ TimeZoneNameUtility.retrieveGenericDisplayName(id, TimeZone.SHORT, locale);
+ */
TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);
names = new String[TYPES.length + 1];
// Zeroth index used for id, other indexes based on NameType constant + 1.
@@ -3764,13 +3781,43 @@
Map<Locale, Entry<Integer, SoftReference<PrefixTree>>> cached =
isCaseSensitive ? cachedTree : cachedTreeCI;
- Entry<Integer, SoftReference<PrefixTree>> entry;
- // BEGIN Android-changed: use ICU TimeZoneNames to get Zone names.
- PrefixTree tree;
+ Entry<Integer, SoftReference<PrefixTree>> entry = null;
+ PrefixTree tree = null;
+ String[][] zoneStrings = null;
if ((entry = cached.get(locale)) == null ||
(entry.getKey() != regionIdsSize ||
(tree = entry.getValue().get()) == null)) {
tree = PrefixTree.newTree(context);
+ // BEGIN Android-changed: use ICU TimeZoneNames to get Zone names.
+ /*
+ zoneStrings = TimeZoneNameUtility.getZoneStrings(locale);
+ for (String[] names : zoneStrings) {
+ String zid = names[0];
+ if (!regionIds.contains(zid)) {
+ continue;
+ }
+ tree.add(zid, zid); // don't convert zid -> metazone
+ zid = ZoneName.toZid(zid, locale);
+ int i = textStyle == TextStyle.FULL ? 1 : 2;
+ for (; i < names.length; i += 2) {
+ tree.add(names[i], zid);
+ }
+ }
+ // if we have a set of preferred zones, need a copy and
+ // add the preferred zones again to overwrite
+ if (preferredZones != null) {
+ for (String[] names : zoneStrings) {
+ String zid = names[0];
+ if (!preferredZones.contains(zid) || !regionIds.contains(zid)) {
+ continue;
+ }
+ int i = textStyle == TextStyle.FULL ? 1 : 2;
+ for (; i < names.length; i += 2) {
+ tree.add(names[i], zid);
+ }
+ }
+ }
+ */
TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);
long now = System.currentTimeMillis();
TimeZoneNames.NameType[] types =
@@ -3800,9 +3847,9 @@
tree.add(names[i], zid);
}
}
- // END Android-changed: use ICU TimeZoneNames to get Zone names.
}
}
+ // END Android-changed: use ICU TimeZoneNames to get Zone names.
cached.put(locale, new SimpleImmutableEntry<>(regionIdsSize, new SoftReference<>(tree)));
}
return tree;
@@ -4369,7 +4416,9 @@
* @throws NullPointerException if chrono or locale is null
*/
private String getChronologyName(Chronology chrono, Locale locale) {
- // Android-changed: Use ICU LocaleDisplayNames.
+ // Android-changed: Use ICU LocaleDisplayNames. http://b/28832222
+ // String key = "calendarname." + chrono.getCalendarType();
+ // String name = DateTimeTextProvider.getLocalizedResource(key, locale);
LocaleDisplayNames displayNames = LocaleDisplayNames.getInstance(ULocale.forLocale(locale));
String name = displayNames.keyValueDisplayName("calendar", chrono.getCalendarType());
return name != null ? name : chrono.getId();
diff --git a/ojluni/src/main/java/java/time/format/DateTimeTextProvider.java b/ojluni/src/main/java/java/time/format/DateTimeTextProvider.java
index 2ef9df8..260196a 100644
--- a/ojluni/src/main/java/java/time/format/DateTimeTextProvider.java
+++ b/ojluni/src/main/java/java/time/format/DateTimeTextProvider.java
@@ -430,7 +430,28 @@
}
if (field == IsoFields.QUARTER_OF_YEAR) {
- // Android-changed: Use ICU resources.
+ // BEGIN Android-changed: Use ICU resources.
+ /*
+ // The order of keys must correspond to the TextStyle.values() order.
+ final String[] keys = {
+ "QuarterNames",
+ "standalone.QuarterNames",
+ "QuarterAbbreviations",
+ "standalone.QuarterAbbreviations",
+ "QuarterNarrows",
+ "standalone.QuarterNarrows",
+ };
+ for (int i = 0; i < keys.length; i++) {
+ String[] names = getLocalizedResource(keys[i], locale);
+ if (names != null) {
+ Map<Long, String> map = new HashMap<>();
+ for (int q = 0; q < names.length; q++) {
+ map.put((long) (q + 1), names[q]);
+ }
+ styleMap.put(TextStyle.values()[i], map);
+ }
+ }
+ */
ICUResourceBundle rb = (ICUResourceBundle) UResourceBundle
.getBundleInstance(ICUData.ICU_BASE_NAME, locale);
ICUResourceBundle quartersRb = rb.getWithFallback("calendar/gregorian/quarters");
@@ -442,13 +463,14 @@
styleMap.put(TextStyle.SHORT_STANDALONE, extractQuarters(standaloneRb, "abbreviated"));
styleMap.put(TextStyle.NARROW, extractQuarters(formatRb, "narrow"));
styleMap.put(TextStyle.NARROW_STANDALONE, extractQuarters(standaloneRb, "narrow"));
+ // END Android-changed: Use ICU resources.
return new LocaleStore(styleMap);
}
return ""; // null marker for map
}
- // Android-added: extractQuarters to extract Map of quarter names from ICU resource bundle.
+ // BEGIN Android-added: Extracts a Map of quarter names from ICU resource bundle.
private static Map<Long, String> extractQuarters(ICUResourceBundle rb, String key) {
String[] names = rb.getWithFallback(key).getStringArray();
Map<Long, String> map = new HashMap<>();
@@ -457,6 +479,7 @@
}
return map;
}
+ // END Android-added: Extracts a Map of quarter names from ICU resource bundle.
/**
* Helper method to create an immutable entry.
@@ -469,7 +492,24 @@
return new SimpleImmutableEntry<>(text, field);
}
- // Android-removed: unused helper method getLocalizedResource.
+ // BEGIN Android-removed: Android uses ICU resources and has no LocaleProviderAdapter.
+ /**
+ * Returns the localized resource of the given key and locale, or null
+ * if no localized resource is available.
+ *
+ * @param key the key of the localized resource, not null
+ * @param locale the locale, not null
+ * @return the localized resource, or null if not available
+ * @throws NullPointerException if key or locale is null
+ */
+ // @SuppressWarnings("unchecked")
+ // static <T> T getLocalizedResource(String key, Locale locale) {
+ // LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased()
+ // .getLocaleResources(locale);
+ // ResourceBundle rb = lr.getJavaTimeFormatData();
+ // return rb.containsKey(key) ? (T) rb.getObject(key) : null;
+ // }
+ // END Android-removed: Android uses ICU resources and has no LocaleProviderAdapter.
/**
* Stores the text for a single locale.
diff --git a/ojluni/src/main/java/java/util/Arrays.java b/ojluni/src/main/java/java/util/Arrays.java
index 72c5f93..3ffead0 100644
--- a/ojluni/src/main/java/java/util/Arrays.java
+++ b/ojluni/src/main/java/java/util/Arrays.java
@@ -78,7 +78,7 @@
* tasks that makes parallel speedups unlikely.
* @hide
*/
- // Android-changed: make public (used by harmony ArraysTest)
+ // Android-changed: Make MIN_ARRAY_SORT_GRAN public and @hide (used by harmony ArraysTest)
public static final int MIN_ARRAY_SORT_GRAN = 1 << 13;
// Suppresses default constructor, ensuring non-instantiability.
@@ -124,20 +124,6 @@
}
}
- // BEGIN Android-added: checkOffsetAndCount() helper method for AIOOBE enforcement.
- /**
- * Checks that the range described by {@code offset} and {@code count} doesn't exceed
- * {@code arrayLength}.
- * @hide
- */
- public static void checkOffsetAndCount(int arrayLength, int offset, int count) {
- if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) {
- throw new ArrayIndexOutOfBoundsException(arrayLength, offset,
- count);
- }
- }
- // END Android-added: checkOffsetAndCount() helper method for AIOOBE enforcement.
-
/*
* Sorting methods. Note that all public "sort" methods take the
* same form: Performing argument checks if necessary, and then
@@ -1201,6 +1187,8 @@
* Sorting of complex type arrays.
*/
+ // Android-removed: LegacyMergeSort class (unused on Android).
+
/**
* Sorts the specified array of objects into ascending order, according
* to the {@linkplain Comparable natural ordering} of its elements.
@@ -1244,13 +1232,15 @@
* {@link Comparable} contract
*/
public static void sort(Object[] a) {
- // Android-changed: LegacyMergeSort is no longer supported
+ // Android-removed: LegacyMergeSort support
// if (LegacyMergeSort.userRequested)
// legacyMergeSort(a);
// else
ComparableTimSort.sort(a, 0, a.length, null, 0, 0);
}
+ // Android-removed: legacyMergeSort() (unused on Android)
+
/**
* Sorts the specified range of the specified array of objects into
* ascending order, according to the
@@ -1305,13 +1295,15 @@
*/
public static void sort(Object[] a, int fromIndex, int toIndex) {
rangeCheck(a.length, fromIndex, toIndex);
- // Android-changed: LegacyMergeSort is no longer supported
+ // Android-removed: LegacyMergeSort support
// if (LegacyMergeSort.userRequested)
// legacyMergeSort(a, fromIndex, toIndex);
// else
ComparableTimSort.sort(a, fromIndex, toIndex, null, 0, 0);
}
+ // Android-removed: legacyMergeSort() (unused on Android)
+
/**
* Tuning parameter: list size at or below which insertion sort will be
* used in preference to mergesort.
@@ -1425,7 +1417,7 @@
if (c == null) {
sort(a);
} else {
- // Android-changed: LegacyMergeSort is no longer supported
+ // Android-removed: LegacyMergeSort support
// if (LegacyMergeSort.userRequested)
// legacyMergeSort(a, c);
// else
@@ -1433,6 +1425,8 @@
}
}
+ // Android-removed: legacyMergeSort() (unused on Android)
+
/**
* Sorts the specified range of the specified array of objects according
* to the order induced by the specified comparator. The range to be
@@ -1491,7 +1485,7 @@
sort(a, fromIndex, toIndex);
} else {
rangeCheck(a.length, fromIndex, toIndex);
- // Android-changed: LegacyMergeSort is no longer supported
+ // Android-removed: LegacyMergeSort support
// if (LegacyMergeSort.userRequested)
// legacyMergeSort(a, fromIndex, toIndex, c);
// else
@@ -1499,6 +1493,9 @@
}
}
+ // Android-removed: legacyMergeSort() (unused on Android)
+ // Android-removed: mergeSort() (unused on Android)
+
// Parallel prefix
/**
@@ -4113,7 +4110,7 @@
for (Object element : a) {
int elementHash = 0;
- // BEGIN Android-changed: getComponentType() is faster than instanceof()
+ // BEGIN Android-changed: getComponentType() is faster than instanceof
if (element != null) {
Class<?> cl = element.getClass().getComponentType();
if (cl == null)
@@ -4196,8 +4193,7 @@
if (e1 == e2)
continue;
- // Android-changed: Return early if e2 == null
- if (e1 == null || e2 == null)
+ if (e1 == null)
return false;
// Figure out whether the two elements are equal
@@ -4210,34 +4206,29 @@
}
static boolean deepEquals0(Object e1, Object e2) {
- // BEGIN Android-changed: getComponentType() is faster than instanceof()
- Class<?> cl1 = e1.getClass().getComponentType();
- Class<?> cl2 = e2.getClass().getComponentType();
-
- if (cl1 != cl2) {
- return false;
- }
- if (e1 instanceof Object[])
- return deepEquals ((Object[]) e1, (Object[]) e2);
- else if (cl1 == byte.class)
- return equals((byte[]) e1, (byte[]) e2);
- else if (cl1 == short.class)
- return equals((short[]) e1, (short[]) e2);
- else if (cl1 == int.class)
- return equals((int[]) e1, (int[]) e2);
- else if (cl1 == long.class)
- return equals((long[]) e1, (long[]) e2);
- else if (cl1 == char.class)
- return equals((char[]) e1, (char[]) e2);
- else if (cl1 == float.class)
- return equals((float[]) e1, (float[]) e2);
- else if (cl1 == double.class)
- return equals((double[]) e1, (double[]) e2);
- else if (cl1 == boolean.class)
- return equals((boolean[]) e1, (boolean[]) e2);
+ assert e1 != null;
+ boolean eq;
+ if (e1 instanceof Object[] && e2 instanceof Object[])
+ eq = deepEquals ((Object[]) e1, (Object[]) e2);
+ else if (e1 instanceof byte[] && e2 instanceof byte[])
+ eq = equals((byte[]) e1, (byte[]) e2);
+ else if (e1 instanceof short[] && e2 instanceof short[])
+ eq = equals((short[]) e1, (short[]) e2);
+ else if (e1 instanceof int[] && e2 instanceof int[])
+ eq = equals((int[]) e1, (int[]) e2);
+ else if (e1 instanceof long[] && e2 instanceof long[])
+ eq = equals((long[]) e1, (long[]) e2);
+ else if (e1 instanceof char[] && e2 instanceof char[])
+ eq = equals((char[]) e1, (char[]) e2);
+ else if (e1 instanceof float[] && e2 instanceof float[])
+ eq = equals((float[]) e1, (float[]) e2);
+ else if (e1 instanceof double[] && e2 instanceof double[])
+ eq = equals((double[]) e1, (double[]) e2);
+ else if (e1 instanceof boolean[] && e2 instanceof boolean[])
+ eq = equals((boolean[]) e1, (boolean[]) e2);
else
- return e1.equals(e2);
- // END Android-changed: getComponentType() is faster than instanceof()
+ eq = e1.equals(e2);
+ return eq;
}
/**
diff --git a/ojluni/src/main/java/java/util/Base64.java b/ojluni/src/main/java/java/util/Base64.java
index 61f68d3..be98fad 100644
--- a/ojluni/src/main/java/java/util/Base64.java
+++ b/ojluni/src/main/java/java/util/Base64.java
@@ -788,6 +788,9 @@
public void write(byte[] b, int off, int len) throws IOException {
if (closed)
throw new IOException("Stream is closed");
+ // Android-changed: Upstream fix to avoid overflow.
+ // This upstream fix is from beyond OpenJDK8u121-b13. http://b/62368386
+ // if (off < 0 || len < 0 || off + len > b.length)
if (off < 0 || len < 0 || len > b.length - off)
throw new ArrayIndexOutOfBoundsException();
if (len == 0)
diff --git a/ojluni/src/main/java/java/util/Collections.java b/ojluni/src/main/java/java/util/Collections.java
index af5237d..d2de25d 100644
--- a/ojluni/src/main/java/java/util/Collections.java
+++ b/ojluni/src/main/java/java/util/Collections.java
@@ -112,8 +112,10 @@
private static final int REPLACEALL_THRESHOLD = 11;
private static final int INDEXOFSUBLIST_THRESHOLD = 35;
- // Android-changed: Warn about Collections.sort() being built on top
- // of List.sort() when it used to be the other way round in Nougat.
+ // Android-added: List.sort() vs. Collections.sort() app compat.
+ // Added a warning in the documentation.
+ // Collections.sort() calls List.sort() for apps targeting API version >= 26
+ // (Android Oreo) but the other way around for app targeting <= 25 (Nougat).
/**
* Sorts the specified list into ascending order, according to the
* {@linkplain Comparable natural ordering} of its elements.
@@ -150,14 +152,17 @@
*/
@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> void sort(List<T> list) {
- // Android-changed: Call sort(list, null) here to be consistent
- // with that method's (Android changed) behavior.
+ // Android-changed: List.sort() vs. Collections.sort() app compat.
+ // Call sort(list, null) here to be consistent with that method's
+ // (changed on Android) behavior.
// list.sort(null);
sort(list, null);
}
- // Android-changed: Warn about Collections.sort() being built on top
- // of List.sort() when it used to be the other way round in Nougat.
+ // Android-added: List.sort() vs. Collections.sort() app compat.
+ // Added a warning in the documentation.
+ // Collections.sort() calls List.sort() for apps targeting API version >= 26
+ // (Android Oreo) but the other way around for app targeting <= 25 (Nougat).
/**
* Sorts the specified list according to the order induced by the
* specified comparator. All elements in the list must be <i>mutually
@@ -194,7 +199,7 @@
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public static <T> void sort(List<T> list, Comparator<? super T> c) {
- // BEGIN Android-changed: Compat behavior for apps targeting APIs <= 25.
+ // BEGIN Android-changed: List.sort() vs. Collections.sort() app compat.
// list.sort(c);
int targetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
if (targetSdkVersion > 25) {
@@ -214,7 +219,7 @@
i.set((T) a[j]);
}
}
- // END Android-changed: Compat behavior for apps targeting APIs <= 25.
+ // END Android-changed: List.sort() vs. Collections.sort() app compat.
}
@@ -1705,8 +1710,10 @@
public void remove() {
throw new UnsupportedOperationException();
}
- // Android-note: This seems pretty inconsistent. Unlike other subclasses, we aren't
- // delegating to the subclass iterator here. Seems like an oversight.
+ // Android-note: Oversight of Iterator.forEachRemaining().
+ // This seems pretty inconsistent. Unlike other subclasses,
+ // we aren't delegating to the subclass iterator here.
+ // Seems like an oversight. http://b/110351017
};
}
@@ -3119,7 +3126,8 @@
public boolean hasNext() { return it.hasNext(); }
public E next() { return it.next(); }
public void remove() { it.remove(); }};
- // Android-note: Should we delegate to it for forEachRemaining ?
+ // Android-note: Oversight of Iterator.forEachRemaining().
+ // http://b/110351017
}
public boolean add(E e) { return c.add(typeCheck(e)); }
@@ -3804,7 +3812,8 @@
public Map.Entry<K,V> next() {
return checkedEntry(i.next(), valueType);
}
- // Android-note: forEachRemaining is missing checks.
+ // Android-note: Oversight of Iterator.forEachRemaining().
+ // http://b/110351017
};
}
diff --git a/ojluni/src/main/java/java/util/Currency.java b/ojluni/src/main/java/java/util/Currency.java
index 88606aa..a154dc6 100644
--- a/ojluni/src/main/java/java/util/Currency.java
+++ b/ojluni/src/main/java/java/util/Currency.java
@@ -58,24 +58,216 @@
*/
private final String currencyCode;
+ // BEGIN Android-changed: Use ICU.
+ // We do not keep track of defaultFractionDigits and numericCode separately.
+ /*
+ /**
+ * Default fraction digits for this currency.
+ * Set from currency data tables.
+ *
+ transient private final int defaultFractionDigits;
+
+ /**
+ * ISO 4217 numeric code for this currency.
+ * Set from currency data tables.
+ *
+ transient private final int numericCode;
+ */
+ private transient final android.icu.util.Currency icuCurrency;
+ // END Android-changed: Use ICU.
+
+
// class data: instance map
private static ConcurrentMap<String, Currency> instances = new ConcurrentHashMap<>(7);
private static HashSet<Currency> available;
- // Android-changed: Implement Currency on top of ICU throughout.
- // We do not keep track of defaultFractionDigits and numericCode separately here.
- private transient final android.icu.util.Currency icuCurrency;
+ // BEGIN Android-removed: Use ICU.
+ // We don't need any of these static fields nor the static initializer.
+ /*
+ // Class data: currency data obtained from currency.data file.
+ // Purpose:
+ // - determine valid country codes
+ // - determine valid currency codes
+ // - map country codes to currency codes
+ // - obtain default fraction digits for currency codes
+ //
+ // sc = special case; dfd = default fraction digits
+ // Simple countries are those where the country code is a prefix of the
+ // currency code, and there are no known plans to change the currency.
+ //
+ // table formats:
+ // - mainTable:
+ // - maps country code to 32-bit int
+ // - 26*26 entries, corresponding to [A-Z]*[A-Z]
+ // - \u007F -> not valid country
+ // - bits 20-31: unused
+ // - bits 10-19: numeric code (0 to 1023)
+ // - bit 9: 1 - special case, bits 0-4 indicate which one
+ // 0 - simple country, bits 0-4 indicate final char of currency code
+ // - bits 5-8: fraction digits for simple countries, 0 for special cases
+ // - bits 0-4: final char for currency code for simple country, or ID of special case
+ // - special case IDs:
+ // - 0: country has no currency
+ // - other: index into sc* arrays + 1
+ // - scCutOverTimes: cut-over time in millis as returned by
+ // System.currentTimeMillis for special case countries that are changing
+ // currencies; Long.MAX_VALUE for countries that are not changing currencies
+ // - scOldCurrencies: old currencies for special case countries
+ // - scNewCurrencies: new currencies for special case countries that are
+ // changing currencies; null for others
+ // - scOldCurrenciesDFD: default fraction digits for old currencies
+ // - scNewCurrenciesDFD: default fraction digits for new currencies, 0 for
+ // countries that are not changing currencies
+ // - otherCurrencies: concatenation of all currency codes that are not the
+ // main currency of a simple country, separated by "-"
+ // - otherCurrenciesDFD: decimal format digits for currencies in otherCurrencies, same order
+
+ static int formatVersion;
+ static int dataVersion;
+ static int[] mainTable;
+ static long[] scCutOverTimes;
+ static String[] scOldCurrencies;
+ static String[] scNewCurrencies;
+ static int[] scOldCurrenciesDFD;
+ static int[] scNewCurrenciesDFD;
+ static int[] scOldCurrenciesNumericCode;
+ static int[] scNewCurrenciesNumericCode;
+ static String otherCurrencies;
+ static int[] otherCurrenciesDFD;
+ static int[] otherCurrenciesNumericCode;
+
+ // handy constants - must match definitions in GenerateCurrencyData
+ // magic number
+ private static final int MAGIC_NUMBER = 0x43757244;
+ // number of characters from A to Z
+ private static final int A_TO_Z = ('Z' - 'A') + 1;
+ // entry for invalid country codes
+ private static final int INVALID_COUNTRY_ENTRY = 0x0000007F;
+ // entry for countries without currency
+ private static final int COUNTRY_WITHOUT_CURRENCY_ENTRY = 0x00000200;
+ // mask for simple case country entries
+ private static final int SIMPLE_CASE_COUNTRY_MASK = 0x00000000;
+ // mask for simple case country entry final character
+ private static final int SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK = 0x0000001F;
+ // mask for simple case country entry default currency digits
+ private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK = 0x000001E0;
+ // shift count for simple case country entry default currency digits
+ private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT = 5;
+ // maximum number for simple case country entry default currency digits
+ private static final int SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS = 9;
+ // mask for special case country entries
+ private static final int SPECIAL_CASE_COUNTRY_MASK = 0x00000200;
+ // mask for special case country index
+ private static final int SPECIAL_CASE_COUNTRY_INDEX_MASK = 0x0000001F;
+ // delta from entry index component in main table to index into special case tables
+ private static final int SPECIAL_CASE_COUNTRY_INDEX_DELTA = 1;
+ // mask for distinguishing simple and special case countries
+ private static final int COUNTRY_TYPE_MASK = SIMPLE_CASE_COUNTRY_MASK | SPECIAL_CASE_COUNTRY_MASK;
+ // mask for the numeric code of the currency
+ private static final int NUMERIC_CODE_MASK = 0x000FFC00;
+ // shift count for the numeric code of the currency
+ private static final int NUMERIC_CODE_SHIFT = 10;
+
+ // Currency data format version
+ private static final int VALID_FORMAT_VERSION = 2;
+
+ static {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ @Override
+ public Void run() {
+ String homeDir = System.getProperty("java.home");
+ try {
+ String dataFile = homeDir + File.separator +
+ "lib" + File.separator + "currency.data";
+ try (DataInputStream dis = new DataInputStream(
+ new BufferedInputStream(
+ new FileInputStream(dataFile)))) {
+ if (dis.readInt() != MAGIC_NUMBER) {
+ throw new InternalError("Currency data is possibly corrupted");
+ }
+ formatVersion = dis.readInt();
+ if (formatVersion != VALID_FORMAT_VERSION) {
+ throw new InternalError("Currency data format is incorrect");
+ }
+ dataVersion = dis.readInt();
+ mainTable = readIntArray(dis, A_TO_Z * A_TO_Z);
+ int scCount = dis.readInt();
+ scCutOverTimes = readLongArray(dis, scCount);
+ scOldCurrencies = readStringArray(dis, scCount);
+ scNewCurrencies = readStringArray(dis, scCount);
+ scOldCurrenciesDFD = readIntArray(dis, scCount);
+ scNewCurrenciesDFD = readIntArray(dis, scCount);
+ scOldCurrenciesNumericCode = readIntArray(dis, scCount);
+ scNewCurrenciesNumericCode = readIntArray(dis, scCount);
+ int ocCount = dis.readInt();
+ otherCurrencies = dis.readUTF();
+ otherCurrenciesDFD = readIntArray(dis, ocCount);
+ otherCurrenciesNumericCode = readIntArray(dis, ocCount);
+ }
+ } catch (IOException e) {
+ throw new InternalError(e);
+ }
+
+ // look for the properties file for overrides
+ String propsFile = System.getProperty("java.util.currency.data");
+ if (propsFile == null) {
+ propsFile = homeDir + File.separator + "lib" +
+ File.separator + "currency.properties";
+ }
+ try {
+ File propFile = new File(propsFile);
+ if (propFile.exists()) {
+ Properties props = new Properties();
+ try (FileReader fr = new FileReader(propFile)) {
+ props.load(fr);
+ }
+ Set<String> keys = props.stringPropertyNames();
+ Pattern propertiesPattern =
+ Pattern.compile("([A-Z]{3})\\s*,\\s*(\\d{3})\\s*,\\s*" +
+ "(\\d+)\\s*,?\\s*(\\d{4}-\\d{2}-\\d{2}T\\d{2}:" +
+ "\\d{2}:\\d{2})?");
+ for (String key : keys) {
+ replaceCurrencyData(propertiesPattern,
+ key.toUpperCase(Locale.ROOT),
+ props.getProperty(key).toUpperCase(Locale.ROOT));
+ }
+ }
+ } catch (IOException e) {
+ info("currency.properties is ignored because of an IOException", e);
+ }
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Constants for retrieving localized names from the name providers.
+ *
+ private static final int SYMBOL = 0;
+ private static final int DISPLAYNAME = 1;
+ */
+
/**
* Constructs a <code>Currency</code> instance. The constructor is private
* so that we can insure that there's never more than one instance for a
* given currency.
*/
+ // BEGIN Android-changed: Use ICU.
+ // We do not keep track of defaultFractionDigits and numericCode separately.
+ /*
+ private Currency(String currencyCode, int defaultFractionDigits, int numericCode) {
+ this.currencyCode = currencyCode;
+ this.defaultFractionDigits = defaultFractionDigits;
+ this.numericCode = numericCode;
+ }
+ */
private Currency(android.icu.util.Currency icuCurrency) {
this.icuCurrency = icuCurrency;
this.currencyCode = icuCurrency.getCurrencyCode();
}
+ // END Android-changed: Use ICU.
/**
* Returns the <code>Currency</code> instance for the given currency code.
@@ -87,7 +279,8 @@
* a supported ISO 4217 code.
*/
public static Currency getInstance(String currencyCode) {
- // BEGIN Android-changed: use ICU
+ // BEGIN Android-changed: Use ICU.
+ // Upstream uses a private static helper method, implemented differently.
Currency instance = instances.get(currencyCode);
if (instance != null) {
return instance;
@@ -98,7 +291,7 @@
return null;
}
Currency currencyVal = new Currency(icuInstance);
- // END Android-changed
+ // END Android-changed: Use ICU.
instance = instances.putIfAbsent(currencyCode, currencyVal);
return (instance != null ? instance : currencyVal);
}
@@ -125,11 +318,50 @@
* is not a supported ISO 3166 country code.
*/
public static Currency getInstance(Locale locale) {
- // BEGIN Android-changed: use ICU
+ String country = locale.getCountry();
+ if (country == null) {
+ throw new NullPointerException();
+ }
+
+ // BEGIN Android-changed: Use ICU.
+ /*
+ if (country.length() != 2) {
+ throw new IllegalArgumentException();
+ }
+
+ char char1 = country.charAt(0);
+ char char2 = country.charAt(1);
+ int tableEntry = getMainTableEntry(char1, char2);
+ if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
+ && tableEntry != INVALID_COUNTRY_ENTRY) {
+ char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A');
+ int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
+ int numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT;
+ StringBuilder sb = new StringBuilder(country);
+ sb.append(finalChar);
+ return getInstance(sb.toString(), defaultFractionDigits, numericCode);
+ } else {
+ // special cases
+ if (tableEntry == INVALID_COUNTRY_ENTRY) {
+ throw new IllegalArgumentException();
+ }
+ if (tableEntry == COUNTRY_WITHOUT_CURRENCY_ENTRY) {
+ return null;
+ } else {
+ int index = (tableEntry & SPECIAL_CASE_COUNTRY_INDEX_MASK) - SPECIAL_CASE_COUNTRY_INDEX_DELTA;
+ if (scCutOverTimes[index] == Long.MAX_VALUE || System.currentTimeMillis() < scCutOverTimes[index]) {
+ return getInstance(scOldCurrencies[index], scOldCurrenciesDFD[index],
+ scOldCurrenciesNumericCode[index]);
+ } else {
+ return getInstance(scNewCurrencies[index], scNewCurrenciesDFD[index],
+ scNewCurrenciesNumericCode[index]);
+ }
+ }
+ }
+ */
android.icu.util.Currency icuInstance =
android.icu.util.Currency.getInstance(locale);
String variant = locale.getVariant();
- String country = locale.getCountry();
if (!variant.isEmpty() && (variant.equals("EURO") || variant.equals("HK") ||
variant.equals("PREEURO"))) {
country = country + "_" + variant;
@@ -142,7 +374,7 @@
return null;
}
return getInstance(currencyCode);
- // END Android-changed
+ // END Android-changed: Use ICU.
}
/**
@@ -158,10 +390,37 @@
public static Set<Currency> getAvailableCurrencies() {
synchronized(Currency.class) {
if (available == null) {
- // BEGIN Android-changed: use ICU
+ // BEGIN Android-changed: Use ICU.
+ /*
+ available = new HashSet<>(256);
+
+ // Add simple currencies first
+ for (char c1 = 'A'; c1 <= 'Z'; c1 ++) {
+ for (char c2 = 'A'; c2 <= 'Z'; c2 ++) {
+ int tableEntry = getMainTableEntry(c1, c2);
+ if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
+ && tableEntry != INVALID_COUNTRY_ENTRY) {
+ char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A');
+ int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
+ int numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT;
+ StringBuilder sb = new StringBuilder();
+ sb.append(c1);
+ sb.append(c2);
+ sb.append(finalChar);
+ available.add(getInstance(sb.toString(), defaultFractionDigits, numericCode));
+ }
+ }
+ }
+
+ // Now add other currencies
+ StringTokenizer st = new StringTokenizer(otherCurrencies, "-");
+ while (st.hasMoreElements()) {
+ available.add(getInstance((String)st.nextElement()));
+ }
+ */
+ available = new HashSet<>();
Set<android.icu.util.Currency> icuAvailableCurrencies
= android.icu.util.Currency.getAvailableCurrencies();
- available = new HashSet<>();
for (android.icu.util.Currency icuCurrency : icuAvailableCurrencies) {
Currency currency = getInstance(icuCurrency.getCurrencyCode());
if (currency == null) {
@@ -170,7 +429,7 @@
}
available.add(currency);
}
- // END Android-changed
+ // END Android-changed: Use ICU.
}
}
@@ -218,12 +477,25 @@
* @exception NullPointerException if <code>locale</code> is null
*/
public String getSymbol(Locale locale) {
- // BEGIN Android-changed: use ICU
+ // BEGIN Android-changed: Use ICU.
+ /*
+ LocaleServiceProviderPool pool =
+ LocaleServiceProviderPool.getPool(CurrencyNameProvider.class);
+ String symbol = pool.getLocalizedObject(
+ CurrencyNameGetter.INSTANCE,
+ locale, currencyCode, SYMBOL);
+ if (symbol != null) {
+ return symbol;
+ }
+
+ // use currency code as symbol of last resort
+ return currencyCode;
+ */
if (locale == null) {
throw new NullPointerException("locale == null");
}
return icuCurrency.getSymbol(locale);
- // END Android-changed
+ // END Android-changed: Use ICU.
}
/**
@@ -236,12 +508,13 @@
* @return the default number of fraction digits used with this currency
*/
public int getDefaultFractionDigits() {
- // BEGIN Android-changed: use ICU
+ // BEGIN Android-changed: Use ICU.
+ // return defaultFractionDigits;
if (icuCurrency.getCurrencyCode().equals("XXX")) {
return -1;
}
return icuCurrency.getDefaultFractionDigits();
- // END Android-changed
+ // END Android-changed: Use ICU.
}
/**
@@ -251,8 +524,8 @@
* @since 1.7
*/
public int getNumericCode() {
- // Android-changed: use ICU
- // was: return numericCode;
+ // Android-changed: Use ICU.
+ // return numericCode;
return icuCurrency.getNumericCode();
}
@@ -286,7 +559,20 @@
* @since 1.7
*/
public String getDisplayName(Locale locale) {
- // Android-changed: use ICU
+ // Android-changed: Use ICU.
+ /*
+ LocaleServiceProviderPool pool =
+ LocaleServiceProviderPool.getPool(CurrencyNameProvider.class);
+ String result = pool.getLocalizedObject(
+ CurrencyNameGetter.INSTANCE,
+ locale, currencyCode, DISPLAYNAME);
+ if (result != null) {
+ return result;
+ }
+
+ // use currency code as symbol of last resort
+ return currencyCode;
+ */
return icuCurrency.getDisplayName(Objects.requireNonNull(locale));
}
@@ -297,7 +583,8 @@
*/
@Override
public String toString() {
- // Android-changed: use ICU
+ // Android-changed: Use ICU.
+ // return currencyCode;
return icuCurrency.toString();
}
@@ -307,4 +594,7 @@
private Object readResolve() {
return getInstance(currencyCode);
}
+
+ // Android-removed: Use ICU.
+ // Removed a bunch of private helper methods that are unused on Android.
}
diff --git a/ojluni/src/main/java/java/util/DoubleSummaryStatistics.java b/ojluni/src/main/java/java/util/DoubleSummaryStatistics.java
index 599bd18..222d967 100644
--- a/ojluni/src/main/java/java/util/DoubleSummaryStatistics.java
+++ b/ojluni/src/main/java/java/util/DoubleSummaryStatistics.java
@@ -25,6 +25,7 @@
package java.util;
import java.util.function.DoubleConsumer;
+import java.util.stream.Collector;
/**
* A state object for collecting statistics such as count, min, max, sum, and
diff --git a/ojluni/src/main/java/java/util/Formatter.java b/ojluni/src/main/java/java/util/Formatter.java
index 5e9c028..b5c7997 100644
--- a/ojluni/src/main/java/java/util/Formatter.java
+++ b/ojluni/src/main/java/java/util/Formatter.java
@@ -61,6 +61,7 @@
import sun.misc.DoubleConsts;
import sun.misc.FormattedFloatingDecimal;
+// Android-changed: Use localized exponent separator for %e.
/**
* An interpreter for printf-style format strings. This class provides support
* for layout justification and alignment, common formats for numeric, string,
diff --git a/ojluni/src/main/java/java/util/IntSummaryStatistics.java b/ojluni/src/main/java/java/util/IntSummaryStatistics.java
index d16f224..f93436e 100644
--- a/ojluni/src/main/java/java/util/IntSummaryStatistics.java
+++ b/ojluni/src/main/java/java/util/IntSummaryStatistics.java
@@ -25,6 +25,7 @@
package java.util;
import java.util.function.IntConsumer;
+import java.util.stream.Collector;
/**
* A state object for collecting statistics such as count, min, max, sum, and
diff --git a/ojluni/src/main/java/java/util/List.java b/ojluni/src/main/java/java/util/List.java
index 9cadac1..09970c9 100644
--- a/ojluni/src/main/java/java/util/List.java
+++ b/ojluni/src/main/java/java/util/List.java
@@ -414,9 +414,10 @@
}
}
- // Android-changed: Warn about Collections.sort() being built on top
- // of List.sort() rather than the other way round when targeting an
- // API version > 25.
+ // Android-added: List.sort() vs. Collections.sort() app compat.
+ // Added a warning in the documentation.
+ // Collections.sort() calls List.sort() for apps targeting API version >= 26
+ // (Android Oreo) but the other way around for app targeting <= 25 (Nougat).
/**
* Sorts this list according to the order induced by the specified
* {@link Comparator}.
diff --git a/ojluni/src/main/java/java/util/Locale.java b/ojluni/src/main/java/java/util/Locale.java
index c96bb13..49d7bea 100644
--- a/ojluni/src/main/java/java/util/Locale.java
+++ b/ojluni/src/main/java/java/util/Locale.java
@@ -945,21 +945,23 @@
return getDefault();
}
- // BEGIN Android-changed: initDefault changes
- // 1.) In initDefault(), user.locale gets priority
- // 2.) In both initDefault methods, use System.getProperty() instead
- // of legacy AccessController / GetPropertyAction security code.
/**
* @hide visible for testing.
*/
+ // Android-changed: Make initDefault() @hide public for testing.
+ // private static Locale initDefault() {
public static Locale initDefault() {
+ // BEGIN Android-added: In initDefault(), prioritize user.locale.
// user.locale gets priority
final String languageTag = System.getProperty("user.locale", "");
if (!languageTag.isEmpty()) {
return Locale.forLanguageTag(languageTag);
}
+ // END Android-added: In initDefault(), prioritize user.locale.
- // user.locale is empty
+ // BEGIN Android-changed: Short-circuit legacy security code.
+ // Use System.getProperty(name, default) instead of
+ // AccessController.doPrivileged(new GetPropertyAction(name, default)).
String language, region, script, country, variant;
language = System.getProperty("user.language", "en");
// for compatibility, check for old user.region property
@@ -980,21 +982,35 @@
country = System.getProperty("user.country", "");
variant = System.getProperty("user.variant", "");
}
+ // END Android-changed: Short-circuit legacy security code.
return getInstance(language, script, country, variant, null);
}
private static Locale initDefault(Locale.Category category) {
- // Android-changed: Add NoImagePreloadHolder to allow compile-time initialization.
+ // Android-added: Add NoImagePreloadHolder to allow compile-time initialization.
final Locale defaultLocale = NoImagePreloadHolder.defaultLocale;
+ // BEGIN Android-changed: Short-circuit legacy security code.
+ /*
+ return getInstance(
+ AccessController.doPrivileged(
+ new GetPropertyAction(category.languageKey, defaultLocale.getLanguage())),
+ AccessController.doPrivileged(
+ new GetPropertyAction(category.scriptKey, defaultLocale.getScript())),
+ AccessController.doPrivileged(
+ new GetPropertyAction(category.countryKey, defaultLocale.getCountry())),
+ AccessController.doPrivileged(
+ new GetPropertyAction(category.variantKey, defaultLocale.getVariant())),
+ null);
+ */
return getInstance(
System.getProperty(category.languageKey, defaultLocale.getLanguage()),
System.getProperty(category.scriptKey, defaultLocale.getScript()),
System.getProperty(category.countryKey, defaultLocale.getCountry()),
System.getProperty(category.variantKey, defaultLocale.getVariant()),
null);
+ // END Android-changed: Short-circuit legacy security code.
}
- // END Android-changed: initDefault changes
/**
* Sets the default locale for this instance of the Java Virtual Machine.
@@ -1091,7 +1107,7 @@
* @return An array of installed locales.
*/
public static Locale[] getAvailableLocales() {
- // Android-changed: Switched to use ICU.
+ // Android-changed: Use ICU.
// return LocaleServiceProviderPool.getAllAvailableLocales();
return ICU.getAvailableLocales();
}
@@ -1108,7 +1124,15 @@
* @return An array of ISO 3166 two-letter country codes.
*/
public static String[] getISOCountries() {
- // Android-changed: Switched to use ICU.
+ // Android-changed: Use ICU.
+ /*
+ if (isoCountries == null) {
+ isoCountries = getISO2Table(LocaleISOData.isoCountryTable);
+ }
+ String[] result = new String[isoCountries.length];
+ System.arraycopy(isoCountries, 0, result, 0, isoCountries.length);
+ return result;
+ */
return ICU.getISOCountries();
}
@@ -1129,10 +1153,31 @@
* @return Am array of ISO 639 two-letter language codes.
*/
public static String[] getISOLanguages() {
- // Android-changed: Switched to use ICU.
+ // Android-changed: Use ICU.
+ /*
+ if (isoLanguages == null) {
+ isoLanguages = getISO2Table(LocaleISOData.isoLanguageTable);
+ }
+ String[] result = new String[isoLanguages.length];
+ System.arraycopy(isoLanguages, 0, result, 0, isoLanguages.length);
+ return result;
+ */
return ICU.getISOLanguages();
}
+ // Android-removed: Use ICU.
+ // Private helper method getISO2Table(), unused on Android.
+ /*
+ private static String[] getISO2Table(String table) {
+ int len = table.length() / 5;
+ String[] isoTable = new String[len];
+ for (int i = 0, j = 0; i < len; i++, j += 5) {
+ isoTable[i] = table.substring(j, j + 2);
+ }
+ return isoTable;
+ }
+ */
+
/**
* Returns the language code of this Locale.
*
@@ -1676,19 +1721,18 @@
if (lang.length() == 3) {
return lang;
}
- // BEGIN Android-added
- // return "" for empty languages for the sake of backwards compatibility.
+ // BEGIN Android-added: app compat: Use "" as ISO3 for empty languages.
else if (lang.isEmpty()) {
return "";
}
- // END Android-added
+ // END Android-added: app compat: Use "" as ISO3 for empty languages.
// BEGIN Android-changed: Use ICU.
// String language3 = getISO3Code(lang, LocaleISOData.isoLanguageTable);
// if (language3 == null) {
String language3 = ICU.getISO3Language(lang);
if (!lang.isEmpty() && language3.isEmpty()) {
- // END Android-changed
+ // END Android-changed: Use ICU.
throw new MissingResourceException("Couldn't find 3-letter language code for "
+ lang, "FormatData_" + toString(), "ShortLanguage");
}
@@ -1709,7 +1753,9 @@
* three-letter country abbreviation is not available for this locale.
*/
public String getISO3Country() throws MissingResourceException {
- // BEGIN Android-changed: Use ICU. Also return "" for missing regions.
+ // BEGIN Android-changed: Use ICU. Also, use "" as ISO3 for missing regions.
+ // String country3 = getISO3Code(baseLocale.getRegion(), LocaleISOData.isoCountryTable);
+ // if (country3 == null) {
final String region = baseLocale.getRegion();
// Note that this will return an UN.M49 region code
if (region.length() == 3) {
@@ -1721,13 +1767,38 @@
// Prefix "en-" because ICU doesn't really care about what the language is.
String country3 = ICU.getISO3Country("en-" + region);
if (!region.isEmpty() && country3.isEmpty()) {
+ // END Android-changed: Use ICU. Also, use "" as ISO3 for missing regions.
throw new MissingResourceException("Couldn't find 3-letter country code for "
+ baseLocale.getRegion(), "FormatData_" + toString(), "ShortCountry");
}
- // END Android-changed
return country3;
}
+ // Android-removed: Use ICU.
+ // getISO3Code() is unused on Android.
+ /*
+ private static String getISO3Code(String iso2Code, String table) {
+ int codeLength = iso2Code.length();
+ if (codeLength == 0) {
+ return "";
+ }
+
+ int tableLength = table.length();
+ int index = tableLength;
+ if (codeLength == 2) {
+ char c1 = iso2Code.charAt(0);
+ char c2 = iso2Code.charAt(1);
+ for (index = 0; index < tableLength; index += 5) {
+ if (table.charAt(index) == c1
+ && table.charAt(index + 1) == c2) {
+ break;
+ }
+ }
+ }
+ return index < tableLength ? table.substring(index + 2, index + 5) : null;
+ }
+ */
+
/**
* Returns a name for the locale's language that is appropriate for display to the
* user.
@@ -1750,8 +1821,30 @@
return getDisplayLanguage(getDefault(Category.DISPLAY));
}
- // BEGIN Android-changed: Use ICU; documentation; backwards compatibility hacks;
- // added private helper methods.
+ // BEGIN Android-changed: Documentation and behavior of getDisplay*().
+ // Use ICU; documentation; backwards compatibility hacks; added private helper methods.
+ /*
+ /**
+ * Returns a name for the locale's language that is appropriate for display to the
+ * user.
+ * If possible, the name returned will be localized according to inLocale.
+ * For example, if the locale is fr_FR and inLocale
+ * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
+ * inLocale is fr_FR, getDisplayLanguage() will return "anglais".
+ * If the name returned cannot be localized according to inLocale,
+ * (say, we don't have a Japanese name for Croatian),
+ * this function falls back on the English name, and finally
+ * on the ISO code as a last-resort value. If the locale doesn't specify a language,
+ * this function returns the empty string.
+ *
+ * @param inLocale The locale for which to retrieve the display language.
+ * @return The name of the display language appropriate to the given locale.
+ * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
+ *
+ public String getDisplayLanguage(Locale inLocale) {
+ return getDisplayString(baseLocale.getLanguage(), inLocale, DISPLAY_LANGUAGE);
+ }
+ */
/**
* Returns the name of this locale's language, localized to {@code locale}.
* If the language name is unknown, the language code is returned.
@@ -1816,7 +1909,7 @@
return true;
}
- // END Android-changed
+ // END Android-changed: Documentation and behavior of getDisplay*().
/**
* Returns a name for the the locale's script that is appropriate for display to
@@ -1846,6 +1939,7 @@
*/
public String getDisplayScript(Locale inLocale) {
// BEGIN Android-changed: Use ICU.
+ // return getDisplayString(baseLocale.getScript(), inLocale, DISPLAY_SCRIPT);
String scriptCode = baseLocale.getScript();
if (scriptCode.isEmpty()) {
return "";
@@ -1857,7 +1951,7 @@
}
return result;
- // END Android-changed
+ // END Android-changed: Use ICU.
}
/**
@@ -1882,7 +1976,52 @@
return getDisplayCountry(getDefault(Category.DISPLAY));
}
- // BEGIN Android-changed: Use ICU; documentation; added private helper methods.
+ // BEGIN Android-changed: Documentation and behavior of getDisplay*().
+ // Use ICU; documentation; added private helper methods.
+ /*
+ /**
+ * Returns a name for the locale's country that is appropriate for display to the
+ * user.
+ * If possible, the name returned will be localized according to inLocale.
+ * For example, if the locale is fr_FR and inLocale
+ * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
+ * inLocale is fr_FR, getDisplayCountry() will return "Etats-Unis".
+ * If the name returned cannot be localized according to inLocale.
+ * (say, we don't have a Japanese name for Croatia),
+ * this function falls back on the English name, and finally
+ * on the ISO code as a last-resort value. If the locale doesn't specify a country,
+ * this function returns the empty string.
+ *
+ * @param inLocale The locale for which to retrieve the display country.
+ * @return The name of the country appropriate to the given locale.
+ * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
+ *
+ public String getDisplayCountry(Locale inLocale) {
+ return getDisplayString(baseLocale.getRegion(), inLocale, DISPLAY_COUNTRY);
+ }
+
+ private String getDisplayString(String code, Locale inLocale, int type) {
+ if (code.length() == 0) {
+ return "";
+ }
+
+ if (inLocale == null) {
+ throw new NullPointerException();
+ }
+
+ LocaleServiceProviderPool pool =
+ LocaleServiceProviderPool.getPool(LocaleNameProvider.class);
+ String key = (type == DISPLAY_VARIANT ? "%%"+code : code);
+ String result = pool.getLocalizedObject(
+ LocaleNameGetter.INSTANCE,
+ inLocale, key, type, code);
+ if (result != null) {
+ return result;
+ }
+
+ return code;
+ }
+ */
/**
* Returns the name of this locale's country, localized to {@code locale}.
* Returns the empty string if this locale does not correspond to a specific
@@ -1959,7 +2098,7 @@
return true;
}
- // END Android-changed: Use ICU; documentation; added private helper methods.
+ // END Android-changed: Documentation and behavior of getDisplay*().
/**
* Returns a name for the locale's variant code that is appropriate for display to the
@@ -1982,8 +2121,24 @@
* @return The name of the display variant code appropriate to the given locale.
* @exception NullPointerException if <code>inLocale</code> is <code>null</code>
*/
- // BEGIN Android-changed: Use ICU; added private helper methods.
public String getDisplayVariant(Locale inLocale) {
+// BEGIN Android-changed: Documentation and behavior of getDisplay*().
+// Use ICU; added private helper methods.
+/*
+ if (baseLocale.getVariant().length() == 0)
+ return "";
+
+ LocaleResources lr = LocaleProviderAdapter.forJRE().getLocaleResources(inLocale);
+
+ String names[] = getDisplayVariantArray(inLocale);
+
+ // Get the localized patterns for formatting a list, and use
+ // them to format the list.
+ return formatList(names,
+ lr.getLocaleName("ListPattern"),
+ lr.getLocaleName("ListCompositionPattern"));
+ }
+*/
String variantCode = baseLocale.getVariant();
if (variantCode.isEmpty()) {
return "";
@@ -2046,7 +2201,7 @@
return false;
}
- // END Android-changed
+// END Android-changed: Documentation and behavior of getDisplay*().
/**
* Returns a name for the locale that is appropriate for display to the
@@ -2071,7 +2226,115 @@
return getDisplayName(getDefault(Category.DISPLAY));
}
- // BEGIN Android-changed: Use ICU.
+ // BEGIN Android-changed: Documentation and behavior of getDisplay*().
+ /*
+ /**
+ * Returns a name for the locale that is appropriate for display
+ * to the user. This will be the values returned by
+ * getDisplayLanguage(), getDisplayScript(),getDisplayCountry(),
+ * and getDisplayVariant() assembled into a single string.
+ * The non-empty values are used in order,
+ * with the second and subsequent names in parentheses. For example:
+ * <blockquote>
+ * language (script, country, variant)<br>
+ * language (country)<br>
+ * language (variant)<br>
+ * script (country)<br>
+ * country<br>
+ * </blockquote>
+ * depending on which fields are specified in the locale. If the
+ * language, script, country, and variant fields are all empty,
+ * this function returns the empty string.
+ *
+ * @param inLocale The locale for which to retrieve the display name.
+ * @return The name of the locale appropriate to display.
+ * @throws NullPointerException if <code>inLocale</code> is <code>null</code>
+ *
+ public String getDisplayName(Locale inLocale) {
+ LocaleResources lr = LocaleProviderAdapter.forJRE().getLocaleResources(inLocale);
+
+ String languageName = getDisplayLanguage(inLocale);
+ String scriptName = getDisplayScript(inLocale);
+ String countryName = getDisplayCountry(inLocale);
+ String[] variantNames = getDisplayVariantArray(inLocale);
+
+ // Get the localized patterns for formatting a display name.
+ String displayNamePattern = lr.getLocaleName("DisplayNamePattern");
+ String listPattern = lr.getLocaleName("ListPattern");
+ String listCompositionPattern = lr.getLocaleName("ListCompositionPattern");
+
+ // The display name consists of a main name, followed by qualifiers.
+ // Typically, the format is "MainName (Qualifier, Qualifier)" but this
+ // depends on what pattern is stored in the display locale.
+ String mainName = null;
+ String[] qualifierNames = null;
+
+ // The main name is the language, or if there is no language, the script,
+ // then if no script, the country. If there is no language/script/country
+ // (an anomalous situation) then the display name is simply the variant's
+ // display name.
+ if (languageName.length() == 0 && scriptName.length() == 0 && countryName.length() == 0) {
+ if (variantNames.length == 0) {
+ return "";
+ } else {
+ return formatList(variantNames, listPattern, listCompositionPattern);
+ }
+ }
+ ArrayList<String> names = new ArrayList<>(4);
+ if (languageName.length() != 0) {
+ names.add(languageName);
+ }
+ if (scriptName.length() != 0) {
+ names.add(scriptName);
+ }
+ if (countryName.length() != 0) {
+ names.add(countryName);
+ }
+ if (variantNames.length != 0) {
+ names.addAll(Arrays.asList(variantNames));
+ }
+
+ // The first one in the main name
+ mainName = names.get(0);
+
+ // Others are qualifiers
+ int numNames = names.size();
+ qualifierNames = (numNames > 1) ?
+ names.subList(1, numNames).toArray(new String[numNames - 1]) : new String[0];
+
+ // Create an array whose first element is the number of remaining
+ // elements. This serves as a selector into a ChoiceFormat pattern from
+ // the resource. The second and third elements are the main name and
+ // the qualifier; if there are no qualifiers, the third element is
+ // unused by the format pattern.
+ Object[] displayNames = {
+ new Integer(qualifierNames.length != 0 ? 2 : 1),
+ mainName,
+ // We could also just call formatList() and have it handle the empty
+ // list case, but this is more efficient, and we want it to be
+ // efficient since all the language-only locales will not have any
+ // qualifiers.
+ qualifierNames.length != 0 ? formatList(qualifierNames, listPattern, listCompositionPattern) : null
+ };
+
+ if (displayNamePattern != null) {
+ return new MessageFormat(displayNamePattern).format(displayNames);
+ }
+ else {
+ // If we cannot get the message format pattern, then we use a simple
+ // hard-coded pattern. This should not occur in practice unless the
+ // installation is missing some core files (FormatData etc.).
+ StringBuilder result = new StringBuilder();
+ result.append((String)displayNames[1]);
+ if (displayNames.length > 2) {
+ result.append(" (");
+ result.append((String)displayNames[2]);
+ result.append(')');
+ }
+ return result.toString();
+ }
+ }
+ */
/**
* Returns this locale's language name, country name, and variant, localized
* to {@code locale}. The exact output form depends on whether this locale
@@ -2133,7 +2396,7 @@
}
return buffer.toString();
}
- // END Android-changed: Use ICU.
+ // END Android-changed: Documentation and behavior of getDisplay*().
/**
* Overrides Cloneable.
@@ -2203,6 +2466,7 @@
private transient volatile int hashCodeValue = 0;
// Android-changed: Add NoImagePreloadHolder to allow compile-time initialization.
+ // private volatile static Locale defaultLocale = initDefault();
private static class NoImagePreloadHolder {
public volatile static Locale defaultLocale = initDefault();
}
@@ -2211,6 +2475,30 @@
private transient volatile String languageTag;
+ // BEGIN Android-removed: Private helper getDisplayVariantArray() unused on Android.
+ /*
+ /**
+ * Return an array of the display names of the variant.
+ * @param bundle the ResourceBundle to use to get the display names
+ * @return an array of display names, possible of zero length.
+ *
+ private String[] getDisplayVariantArray(Locale inLocale) {
+ // Split the variant name into tokens separated by '_'.
+ StringTokenizer tokenizer = new StringTokenizer(baseLocale.getVariant(), "_");
+ String[] names = new String[tokenizer.countTokens()];
+
+ // For each variant token, lookup the display name. If
+ // not found, use the variant name itself.
+ for (int i=0; i<names.length; ++i) {
+ names[i] = getDisplayString(tokenizer.nextToken(),
+ inLocale, DISPLAY_VARIANT);
+ }
+
+ return names;
+ }
+ */
+ // END Android-removed: Private helper getDisplayVariantArray() unused on Android.
+
/**
* Format a list using given pattern strings.
* If either of the patterns is null, then a the list is
@@ -2421,7 +2709,43 @@
}
// Android-removed: Drop nested private class LocaleNameGetter.
- // BEGIN Android-added: Add adjustLanguageCode(); for internal use only.
+ /*
+ /**
+ * Obtains a localized locale names from a LocaleNameProvider
+ * implementation.
+ *
+ private static class LocaleNameGetter
+ implements LocaleServiceProviderPool.LocalizedObjectGetter<LocaleNameProvider, String> {
+ private static final LocaleNameGetter INSTANCE = new LocaleNameGetter();
+
+ @Override
+ public String getObject(LocaleNameProvider localeNameProvider,
+ Locale locale,
+ String key,
+ Object... params) {
+ assert params.length == 2;
+ int type = (Integer)params[0];
+ String code = (String)params[1];
+
+ switch(type) {
+ case DISPLAY_LANGUAGE:
+ return localeNameProvider.getDisplayLanguage(code, locale);
+ case DISPLAY_COUNTRY:
+ return localeNameProvider.getDisplayCountry(code, locale);
+ case DISPLAY_VARIANT:
+ return localeNameProvider.getDisplayVariant(code, locale);
+ case DISPLAY_SCRIPT:
+ return localeNameProvider.getDisplayScript(code, locale);
+ default:
+ assert false; // shouldn't happen
+ }
+
+ return null;
+ }
+ }
+ */
+
+ // BEGIN Android-added: adjustLanguageCode(), for internal use only.
/** @hide for internal use only. */
public static String adjustLanguageCode(String languageCode) {
String adjusted = languageCode.toLowerCase(Locale.US);
@@ -2437,7 +2761,7 @@
return adjusted;
}
- // END Android-added
+ // END Android-added: adjustLanguageCode(), for internal use only.
/**
* Enum for locale categories. These locale categories are used to get/set
@@ -2775,11 +3099,12 @@
* @see #setExtension(char, String)
*/
public Builder removeUnicodeLocaleAttribute(String attribute) {
- // BEGIN Android-added: removeUnicodeLocaleAttribute(null) is documented to throw NPE
+ // BEGIN Android-added: removeUnicodeLocaleAttribute(null) is documented to throw NPE.
+ // This could probably be contributed back to upstream. http://b/110752069
if (attribute == null) {
throw new NullPointerException("attribute == null");
}
- // END Android-added: removeUnicodeLocaleAttribute(null) is documented to throw NPE
+ // END Android-added: removeUnicodeLocaleAttribute(null) is documented to throw NPE.
try {
localeBuilder.removeUnicodeLocaleAttribute(attribute);
diff --git a/ojluni/src/main/java/java/util/LongSummaryStatistics.java b/ojluni/src/main/java/java/util/LongSummaryStatistics.java
index 2ba3959..085aa29 100644
--- a/ojluni/src/main/java/java/util/LongSummaryStatistics.java
+++ b/ojluni/src/main/java/java/util/LongSummaryStatistics.java
@@ -26,6 +26,7 @@
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
+import java.util.stream.Collector;
/**
* A state object for collecting statistics such as count, min, max, sum, and
diff --git a/ojluni/src/main/java/java/util/OptionalInt.java b/ojluni/src/main/java/java/util/OptionalInt.java
index 7907328..61cac03 100644
--- a/ojluni/src/main/java/java/util/OptionalInt.java
+++ b/ojluni/src/main/java/java/util/OptionalInt.java
@@ -87,7 +87,6 @@
*/
private OptionalInt(int value) {
this.isPresent = true;
-
this.value = value;
}
diff --git a/ojluni/src/main/java/java/util/Properties.java b/ojluni/src/main/java/java/util/Properties.java
index 3d6f1db..b413abb 100644
--- a/ojluni/src/main/java/java/util/Properties.java
+++ b/ojluni/src/main/java/java/util/Properties.java
@@ -36,7 +36,8 @@
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
-// Android-changed: Removed dead native2ascii links
+// Android-removed: Dead native2ascii links.
+// These links are also gone in OpenJDK 9.
/**
* The {@code Properties} class represents a persistent set of
* properties. The {@code Properties} can be saved to a stream
@@ -360,9 +361,9 @@
valueStart = keyLen + 1;
hasSep = true;
break;
- }
- // Android-changed: use of Character.isWhitespace(c) b/25998006
- else if (Character.isWhitespace(c) && !precedingBackslash) {
+ // Android-changed: Treat all whitespace the same. http://b/25998006
+ // } else if ((c == ' ' || c == '\t' || c == '\f') && !precedingBackslash) {
+ } else if (Character.isWhitespace(c) && !precedingBackslash) {
valueStart = keyLen + 1;
break;
}
@@ -375,7 +376,8 @@
}
while (valueStart < limit) {
c = lr.lineBuf[valueStart];
- // Android-changed: use of Character.isWhitespace(c) b/25998006
+ // Android-changed: Treat all whitespace the same. http://b/25998006
+ // if (c != ' ' && c != '\t' && c != '\f') {
if (!Character.isWhitespace(c)) {
if (!hasSep && (c == '=' || c == ':')) {
hasSep = true;
@@ -456,7 +458,8 @@
}
}
if (skipWhiteSpace) {
- // Android-changed: use of Character.isWhitespace(c) b/25998006
+ // Android-changed: Treat all whitespace the same. http://b/25998006
+ // if (c == ' ' || c == '\t' || c == '\f') {
if (Character.isWhitespace(c)) {
continue;
}
@@ -1141,4 +1144,89 @@
private static final char[] hexDigit = {
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
};
+
+ // Android-removed: Keep OpenJDK7u40's XmlUtils.
+ // XmlSupport's system property based XmlPropertiesProvider
+ // selection does not make sense on Android and has too many
+ // dependencies on classes that are not available on Android.
+ /*
+ /**
+ * Supporting class for loading/storing properties in XML format.
+ *
+ * <p> The {@code load} and {@code store} methods defined here delegate to a
+ * system-wide {@code XmlPropertiesProvider}. On first invocation of either
+ * method then the system-wide provider is located as follows: </p>
+ *
+ * <ol>
+ * <li> If the system property {@code sun.util.spi.XmlPropertiesProvider}
+ * is defined then it is taken to be the full-qualified name of a concrete
+ * provider class. The class is loaded with the system class loader as the
+ * initiating loader. If it cannot be loaded or instantiated using a zero
+ * argument constructor then an unspecified error is thrown. </li>
+ *
+ * <li> If the system property is not defined then the service-provider
+ * loading facility defined by the {@link ServiceLoader} class is used to
+ * locate a provider with the system class loader as the initiating
+ * loader and {@code sun.util.spi.XmlPropertiesProvider} as the service
+ * type. If this process fails then an unspecified error is thrown. If
+ * there is more than one service provider installed then it is
+ * not specified as to which provider will be used. </li>
+ *
+ * <li> If the provider is not found by the above means then a system
+ * default provider will be instantiated and used. </li>
+ * </ol>
+ *
+ private static class XmlSupport {
+
+ private static XmlPropertiesProvider loadProviderFromProperty(ClassLoader cl) {
+ String cn = System.getProperty("sun.util.spi.XmlPropertiesProvider");
+ if (cn == null)
+ return null;
+ try {
+ Class<?> c = Class.forName(cn, true, cl);
+ return (XmlPropertiesProvider)c.newInstance();
+ } catch (ClassNotFoundException |
+ IllegalAccessException |
+ InstantiationException x) {
+ throw new ServiceConfigurationError(null, x);
+ }
+ }
+
+ private static XmlPropertiesProvider loadProviderAsService(ClassLoader cl) {
+ Iterator<XmlPropertiesProvider> iterator =
+ ServiceLoader.load(XmlPropertiesProvider.class, cl).iterator();
+ return iterator.hasNext() ? iterator.next() : null;
+ }
+
+ private static XmlPropertiesProvider loadProvider() {
+ return AccessController.doPrivileged(
+ new PrivilegedAction<XmlPropertiesProvider>() {
+ public XmlPropertiesProvider run() {
+ ClassLoader cl = ClassLoader.getSystemClassLoader();
+ XmlPropertiesProvider provider = loadProviderFromProperty(cl);
+ if (provider != null)
+ return provider;
+ provider = loadProviderAsService(cl);
+ if (provider != null)
+ return provider;
+ return new jdk.internal.util.xml.BasicXmlPropertiesProvider();
+ }});
+ }
+
+ private static final XmlPropertiesProvider PROVIDER = loadProvider();
+
+ static void load(Properties props, InputStream in)
+ throws IOException, InvalidPropertiesFormatException
+ {
+ PROVIDER.load(props, in);
+ }
+
+ static void save(Properties props, OutputStream os, String comment,
+ String encoding)
+ throws IOException
+ {
+ PROVIDER.store(props, os, comment, encoding);
+ }
+ }
+ */
}
diff --git a/ojluni/src/main/java/java/util/ResourceBundle.java b/ojluni/src/main/java/java/util/ResourceBundle.java
index 6fff252..dd07452 100644
--- a/ojluni/src/main/java/java/util/ResourceBundle.java
+++ b/ojluni/src/main/java/java/util/ResourceBundle.java
@@ -59,13 +59,16 @@
import java.util.concurrent.ConcurrentMap;
import java.util.jar.JarEntry;
-import dalvik.system.VMStack;
import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
import sun.util.locale.BaseLocale;
import sun.util.locale.LocaleObjectCache;
-// Android-changed: Removed reference to ResourceBundleControlProvider.
+// Android-removed: Support for ResourceBundleControlProvider.
+// Removed references to ResourceBundleControlProvider from the documentation.
+// The service provider interface ResourceBundleControlProvider is not
+// available on Android.
/**
*
* Resource bundles contain locale-specific objects. When your program needs a
@@ -360,7 +363,7 @@
*/
private volatile Set<String> keySet;
- // Android-changed: Removed use of ResourceBundleControlProvider.
+ // Android-removed: Support for ResourceBundleControlProvider.
/*
private static final List<ResourceBundleControlProvider> providers;
@@ -464,11 +467,8 @@
* Automatic determination of the ClassLoader to be used to load
* resources on behalf of the client.
*/
- private static ClassLoader getLoader(ClassLoader cl) {
- // Android-changed: On Android, this method takes a ClassLoader argument:
- // Callers call {@code getLoader(VMStack.getCallingClassLoader())}
- // instead of {@code getLoader(Reflection.getCallerClass())}.
- // ClassLoader cl = caller == null ? null : caller.getClassLoader();
+ private static ClassLoader getLoader(Class<?> caller) {
+ ClassLoader cl = caller == null ? null : caller.getClassLoader();
if (cl == null) {
// When the caller's loader is the boot class loader, cl is null
// here. In that case, ClassLoader.getSystemClassLoader() may
@@ -769,9 +769,7 @@
public static final ResourceBundle getBundle(String baseName)
{
return getBundleImpl(baseName, Locale.getDefault(),
- // Android-changed: use of VMStack.getCallingClassLoader()
- getLoader(VMStack.getCallingClassLoader()),
- // getLoader(Reflection.getCallerClass()),
+ getLoader(Reflection.getCallerClass()),
getDefaultControl(baseName));
}
@@ -813,9 +811,7 @@
public static final ResourceBundle getBundle(String baseName,
Control control) {
return getBundleImpl(baseName, Locale.getDefault(),
- // Android-changed: use of VMStack.getCallingClassLoader()
- getLoader(VMStack.getCallingClassLoader()),
- // getLoader(Reflection.getCallerClass()),
+ getLoader(Reflection.getCallerClass()),
control);
}
@@ -845,9 +841,7 @@
Locale locale)
{
return getBundleImpl(baseName, locale,
- // Android-changed: use of VMStack.getCallingClassLoader()
- getLoader(VMStack.getCallingClassLoader()),
- // getLoader(Reflection.getCallerClass()),
+ getLoader(Reflection.getCallerClass()),
getDefaultControl(baseName));
}
@@ -892,13 +886,12 @@
public static final ResourceBundle getBundle(String baseName, Locale targetLocale,
Control control) {
return getBundleImpl(baseName, targetLocale,
- // Android-changed: use of VMStack.getCallingClassLoader()
- getLoader(VMStack.getCallingClassLoader()),
- // getLoader(Reflection.getCallerClass()),
+ getLoader(Reflection.getCallerClass()),
control);
}
- // Android-changed: Removed references to ResourceBundleControlProvider.
+ // Android-removed: Support for ResourceBundleControlProvider.
+ // Removed documentation referring to that SPI.
/**
* Gets a resource bundle using the specified base name, locale, and class
* loader.
@@ -1301,7 +1294,17 @@
}
private static Control getDefaultControl(String baseName) {
- // Android-changed: Removed used of ResourceBundleControlProvider.
+ // Android-removed: Support for ResourceBundleControlProvider.
+ /*
+ if (providers != null) {
+ for (ResourceBundleControlProvider provider : providers) {
+ Control control = provider.getControl(baseName);
+ if (control != null) {
+ return control;
+ }
+ }
+ }
+ */
return Control.INSTANCE;
}
@@ -1737,9 +1740,7 @@
*/
@CallerSensitive
public static final void clearCache() {
- // Android-changed: use of VMStack.getCallingClassLoader()
- clearCache(getLoader(VMStack.getCallingClassLoader()));
- // clearCache(getLoader(Reflection.getCallerClass()));
+ clearCache(getLoader(Reflection.getCallerClass()));
}
/**
@@ -2681,9 +2682,9 @@
if (stream != null) {
try {
// Android-changed: Use UTF-8 for property based resources. b/26879578
+ // bundle = new PropertyResourceBundle(stream);
bundle = new PropertyResourceBundle(
new InputStreamReader(stream, StandardCharsets.UTF_8));
- // bundle = new PropertyResourceBundle(stream);
} finally {
stream.close();
}
diff --git a/ojluni/src/main/java/java/util/Scanner.java b/ojluni/src/main/java/java/util/Scanner.java
index a1ce699..15ad8e8 100644
--- a/ojluni/src/main/java/java/util/Scanner.java
+++ b/ojluni/src/main/java/java/util/Scanner.java
@@ -422,17 +422,21 @@
private int SIMPLE_GROUP_INDEX = 5;
private String buildIntegerPatternString() {
String radixDigits = digits.substring(0, radix);
- // Android-changed: Support non-decimal starting digits. (i.e, a-z are valid radix digits).
- String nonZeroRadixDigits = "((?i)[" + digits.substring(1, radix) + "]|(" + non0Digit + "))";
-
// \\p{javaDigit} is not guaranteed to be appropriate
// here but what can we do? The final authority will be
// whatever parse method is invoked, so ultimately the
// Scanner will do the right thing
String digit = "((?i)["+radixDigits+"]|\\p{javaDigit})";
- // Android-changed: Support non-decimal starting digits.
- String groupedNumeral = "("+nonZeroRadixDigits+digit+"?"+digit+"?("+
+ // BEGIN Android-changed: Support non-decimal starting digits.
+ // Ie., in addition to 1-9, a-z are also valid radix digits.
+ /*
+ String groupedNumeral = "("+non0Digit+digit+"?"+digit+"?("+
groupSeparator+digit+digit+digit+")+)";
+ */
+ String non0RadixDigits = "((?i)[" + digits.substring(1, radix) + "]|(" + non0Digit + "))";
+ String groupedNumeral = "("+non0RadixDigits+digit+"?"+digit+"?("+
+ groupSeparator+digit+digit+digit+")+)";
+ // END Android-changed: Support non-decimal starting digits.
// digit++ is the possessive form which is necessary for reducing
// backtracking that would otherwise cause unacceptable performance
String numeral = "(("+ digit+"++)|"+groupedNumeral+")";
@@ -827,7 +831,8 @@
// Restore current position and limit for reading
buf.limit(buf.position());
buf.position(p);
- // Android-changed: The matcher implementation eagerly calls toString() so we'll have
+ // Android-added: reset() the matcher after reading.
+ // The matcher implementation eagerly calls toString() so we'll have
// to update its input whenever the buffer limit, position etc. changes.
matcher.reset(buf);
}
@@ -1274,10 +1279,11 @@
// The next operation should occur in the specified radix but
// the default is left untouched.
private void setRadix(int radix) {
- // Android-changed: Complain loudly if a bogus radix is being set.
+ // BEGIN Android-added: Complain loudly if a bogus radix is being set.
if (radix > Character.MAX_RADIX) {
throw new IllegalArgumentException("radix == " + radix);
}
+ // END Android-added: Complain loudly if a bogus radix is being set.
if (this.radix != radix) {
// Force rebuilding and recompilation of radix dependent patterns
@@ -2274,9 +2280,10 @@
result = "NaN";
if (result.equals(infinityString))
result = "Infinity";
- // Android-changed: Match the infinity symbol.
+ // BEGIN Android-added: Match the infinity symbol.
if (result.equals("\u221E"))
result = "Infinity";
+ // END Android-added: Match the infinity symbol.
if (isNegative)
result = "-" + result;
diff --git a/ojluni/src/main/java/java/util/TimeZone.java b/ojluni/src/main/java/java/util/TimeZone.java
index de4d4d1..9fbf348 100644
--- a/ojluni/src/main/java/java/util/TimeZone.java
+++ b/ojluni/src/main/java/java/util/TimeZone.java
@@ -39,16 +39,18 @@
package java.util;
-import org.apache.harmony.luni.internal.util.TimezoneGetter;
import android.icu.text.TimeZoneNames;
import java.io.IOException;
import java.io.Serializable;
import java.time.ZoneId;
+import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import libcore.io.IoUtils;
import libcore.util.ZoneInfoDB;
+import dalvik.system.RuntimeHooks;
+
/**
* <code>TimeZone</code> represents a time zone offset, and also figures out daylight
* savings.
@@ -704,8 +706,8 @@
*/
static synchronized TimeZone getDefaultRef() {
if (defaultTimeZone == null) {
- TimezoneGetter tzGetter = TimezoneGetter.getInstance();
- String zoneName = (tzGetter != null) ? tzGetter.getId() : null;
+ Supplier<String> tzGetter = RuntimeHooks.getTimeZoneIdSupplier();
+ String zoneName = (tzGetter != null) ? tzGetter.get() : null;
if (zoneName != null) {
zoneName = zoneName.trim();
}
diff --git a/ojluni/src/main/java/java/util/Vector.java b/ojluni/src/main/java/java/util/Vector.java
index 895430b..61eeb21 100644
--- a/ojluni/src/main/java/java/util/Vector.java
+++ b/ojluni/src/main/java/java/util/Vector.java
@@ -1122,8 +1122,8 @@
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
- // Android-changed: changes around elementCount, introduced limit.
- // b/27430229 AOSP commit 6e5b758a4438d2c154dd11a5c04d14a5d2fc907c
+ // Android-added: Change CME behavior: Use added limit field, not elementCount.
+ // http://b/27430229 AOSP commit 6e5b758a4438d2c154dd11a5c04d14a5d2fc907c
//
// The "limit" of this iterator. This is the size of the list at the time the
// iterator was created. Adding & removing elements will invalidate the iteration
@@ -1137,6 +1137,8 @@
int expectedModCount = modCount;
public boolean hasNext() {
+ // Android-changed: Change CME behavior: Use added limit field, not elementCount.
+ // return cursor != elementCount;
return cursor < limit;
}
@@ -1144,6 +1146,8 @@
synchronized (Vector.this) {
checkForComodification();
int i = cursor;
+ // Android-changed: Change CME behavior: Use added limit field, not elementCount.
+ // if (i >= elementCount)
if (i >= limit)
throw new NoSuchElementException();
cursor = i + 1;
@@ -1158,6 +1162,7 @@
checkForComodification();
Vector.this.remove(lastRet);
expectedModCount = modCount;
+ // Android-added: Change CME behavior: Use added limit field, not elementCount.
limit--;
}
cursor = lastRet;
@@ -1168,6 +1173,8 @@
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
synchronized (Vector.this) {
+ // Android-changed: Change CME behavior: Use added limit field, not elementCount.
+ // final int size = elementCount;
final int size = limit;
int i = cursor;
if (i >= size) {
@@ -1241,6 +1248,7 @@
checkForComodification();
Vector.this.add(i, e);
expectedModCount = modCount;
+ // Android-added: Change CME behavior: Use added limit field, not elementCount.
limit++;
}
cursor = i + 1;
diff --git a/ojluni/src/main/java/java/util/concurrent/CompletableFuture.java b/ojluni/src/main/java/java/util/concurrent/CompletableFuture.java
index b1de4f6..976bfe4 100644
--- a/ojluni/src/main/java/java/util/concurrent/CompletableFuture.java
+++ b/ojluni/src/main/java/java/util/concurrent/CompletableFuture.java
@@ -42,6 +42,8 @@
import java.util.function.Function;
import java.util.function.Supplier;
+// Android-note: Class javadoc changed to remove references to hidden OpenJDK 9 methods.
+
/**
* A {@link Future} that may be explicitly completed (setting its
* value and status), and may be used as a {@link CompletionStage},
@@ -2405,9 +2407,8 @@
* @param <U> the type of the value
* @return a new CompletableFuture
* @since 9
- * @hide
+ * @hide API from OpenJDK 9, not yet exposed on Android.
*/
- // Android-changed: hidden
public <U> CompletableFuture<U> newIncompleteFuture() {
return new CompletableFuture<U>();
}
@@ -2422,9 +2423,8 @@
*
* @return the executor
* @since 9
- * @hide
+ * @hide API from OpenJDK 9, not yet exposed on Android.
*/
- // Android-changed: hidden
public Executor defaultExecutor() {
return ASYNC_POOL;
}
@@ -2442,9 +2442,8 @@
*
* @return the new CompletableFuture
* @since 9
- * @hide
+ * @hide API from OpenJDK 9, not yet exposed on Android.
*/
- // Android-changed: hidden
public CompletableFuture<T> copy() {
return uniCopyStage();
}
@@ -2461,9 +2460,8 @@
*
* @return the new CompletionStage
* @since 9
- * @hide
+ * @hide API from OpenJDK 9, not yet exposed on Android.
*/
- // Android-changed: hidden
public CompletionStage<T> minimalCompletionStage() {
return uniAsMinimalStage();
}
@@ -2478,9 +2476,8 @@
* @param executor the executor to use for asynchronous execution
* @return this CompletableFuture
* @since 9
- * @hide
+ * @hide API from OpenJDK 9, not yet exposed on Android.
*/
- // Android-changed: hidden
public CompletableFuture<T> completeAsync(Supplier<? extends T> supplier,
Executor executor) {
if (supplier == null || executor == null)
@@ -2498,9 +2495,8 @@
* to complete this CompletableFuture
* @return this CompletableFuture
* @since 9
- * @hide
+ * @hide API from OpenJDK 9, not yet exposed on Android.
*/
- // Android-changed: hidden
public CompletableFuture<T> completeAsync(Supplier<? extends T> supplier) {
return completeAsync(supplier, defaultExecutor());
}
@@ -2516,9 +2512,8 @@
* {@code timeout} parameter
* @return this CompletableFuture
* @since 9
- * @hide
+ * @hide API from OpenJDK 9, not yet exposed on Android.
*/
- // Android-changed: hidden
public CompletableFuture<T> orTimeout(long timeout, TimeUnit unit) {
if (unit == null)
throw new NullPointerException();
@@ -2539,9 +2534,8 @@
* {@code timeout} parameter
* @return this CompletableFuture
* @since 9
- * @hide
+ * @hide API from OpenJDK 9, not yet exposed on Android.
*/
- // Android-changed: hidden
public CompletableFuture<T> completeOnTimeout(T value, long timeout,
TimeUnit unit) {
if (unit == null)
@@ -2565,9 +2559,8 @@
* @param executor the base executor
* @return the new delayed executor
* @since 9
- * @hide
+ * @hide API from OpenJDK 9, not yet exposed on Android.
*/
- // Android-changed: hidden
public static Executor delayedExecutor(long delay, TimeUnit unit,
Executor executor) {
if (unit == null || executor == null)
@@ -2586,9 +2579,8 @@
* {@code delay} parameter
* @return the new delayed executor
* @since 9
- * @hide
+ * @hide API from OpenJDK 9, not yet exposed on Android.
*/
- // Android-changed: hidden
public static Executor delayedExecutor(long delay, TimeUnit unit) {
if (unit == null)
throw new NullPointerException();
@@ -2604,9 +2596,8 @@
* @param <U> the type of the value
* @return the completed CompletionStage
* @since 9
- * @hide
+ * @hide API from OpenJDK 9, not yet exposed on Android.
*/
- // Android-changed: hidden
public static <U> CompletionStage<U> completedStage(U value) {
return new MinimalStage<U>((value == null) ? NIL : value);
}
@@ -2619,9 +2610,8 @@
* @param <U> the type of the value
* @return the exceptionally completed CompletableFuture
* @since 9
- * @hide
+ * @hide API from OpenJDK 9, not yet exposed on Android.
*/
- // Android-changed: hidden
public static <U> CompletableFuture<U> failedFuture(Throwable ex) {
if (ex == null) throw new NullPointerException();
return new CompletableFuture<U>(new AltResult(ex));
@@ -2636,9 +2626,8 @@
* @param <U> the type of the value
* @return the exceptionally completed CompletionStage
* @since 9
- * @hide
+ * @hide API from OpenJDK 9, not yet exposed on Android.
*/
- // Android-changed: hidden
public static <U> CompletionStage<U> failedStage(Throwable ex) {
if (ex == null) throw new NullPointerException();
return new MinimalStage<U>(new AltResult(ex));
diff --git a/ojluni/src/main/java/java/util/concurrent/ConcurrentHashMap.java b/ojluni/src/main/java/java/util/concurrent/ConcurrentHashMap.java
index 2b51d91..5407963 100644
--- a/ojluni/src/main/java/java/util/concurrent/ConcurrentHashMap.java
+++ b/ojluni/src/main/java/java/util/concurrent/ConcurrentHashMap.java
@@ -1242,6 +1242,7 @@
* @return the set view
*/
// Android-changed: Return type for backwards compat. Was KeySetView<K,V>. http://b/28099367
+ @dalvik.annotation.codegen.CovariantReturnType(returnType = KeySetView.class, presentAfter = 28)
public Set<K> keySet() {
KeySetView<K,V> ks;
return (ks = keySet) != null ? ks : (keySet = new KeySetView<K,V>(this, null));
@@ -2562,7 +2563,8 @@
* A padded cell for distributing counts. Adapted from LongAdder
* and Striped64. See their internal docs for explanation.
*/
- //@jdk.internal.vm.annotation.Contended // Android-removed
+ // Android-removed: @Contended, this hint is not used by the Android runtime.
+ //@jdk.internal.vm.annotation.Contended
static final class CounterCell {
volatile long value;
CounterCell(long x) { value = x; }
diff --git a/ojluni/src/main/java/java/util/concurrent/CountedCompleter.java b/ojluni/src/main/java/java/util/concurrent/CountedCompleter.java
index f65371aa..a29208e 100644
--- a/ojluni/src/main/java/java/util/concurrent/CountedCompleter.java
+++ b/ojluni/src/main/java/java/util/concurrent/CountedCompleter.java
@@ -42,7 +42,7 @@
* presence of subtask stalls and blockage than are other forms of
* ForkJoinTasks, but are less intuitive to program. Uses of
* CountedCompleter are similar to those of other completion based
- * components
+ * components (such as {@link java.nio.channels.CompletionHandler})
* except that multiple <em>pending</em> completions may be necessary
* to trigger the completion action {@link #onCompletion(CountedCompleter)},
* not just one.
diff --git a/ojluni/src/main/java/java/util/concurrent/Exchanger.java b/ojluni/src/main/java/java/util/concurrent/Exchanger.java
index b1e9324..f01a705 100644
--- a/ojluni/src/main/java/java/util/concurrent/Exchanger.java
+++ b/ojluni/src/main/java/java/util/concurrent/Exchanger.java
@@ -306,7 +306,8 @@
* Nodes hold partially exchanged data, plus other per-thread
* bookkeeping. Padded via @Contended to reduce memory contention.
*/
- //@jdk.internal.vm.annotation.Contended // Android-removed
+ // Android-removed: @Contended, this hint is not used by the Android runtime.
+ //@jdk.internal.vm.annotation.Contended
static final class Node {
int index; // Arena index
int bound; // Last recorded value of Exchanger.bound
diff --git a/ojluni/src/main/java/java/util/concurrent/Executors.java b/ojluni/src/main/java/java/util/concurrent/Executors.java
index 9244136..565fdeb 100644
--- a/ojluni/src/main/java/java/util/concurrent/Executors.java
+++ b/ojluni/src/main/java/java/util/concurrent/Executors.java
@@ -341,6 +341,7 @@
return new DelegatedScheduledExecutorService(executor);
}
+ // Android-changed: Removed references to SecurityManager from javadoc.
/**
* Returns a default thread factory used to create new threads.
* This factory creates all new threads used by an Executor in the
@@ -358,6 +359,7 @@
return new DefaultThreadFactory();
}
+ // Android-changed: Dropped documentation for legacy security code.
/**
* Legacy security code; do not use.
*/
@@ -424,6 +426,7 @@
public Object call() throws Exception { return action.run(); }};
}
+ // Android-changed: Dropped documentation for legacy security code.
/**
* Legacy security code; do not use.
*/
@@ -433,6 +436,7 @@
return new PrivilegedCallable<T>(callable);
}
+ // Android-changed: Dropped documentation for legacy security code.
/**
* Legacy security code; do not use.
*/
@@ -497,19 +501,20 @@
final ClassLoader ccl;
PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
- // BEGIN Android-removed
- // SecurityManager sm = System.getSecurityManager();
- // if (sm != null) {
- // // Calls to getContextClassLoader from this class
- // // never trigger a security check, but we check
- // // whether our callers have this permission anyways.
- // sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
+ // Android-removed: System.getSecurityManager always returns null.
+ /*
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ // Calls to getContextClassLoader from this class
+ // never trigger a security check, but we check
+ // whether our callers have this permission anyways.
+ sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- // // Whether setContextClassLoader turns out to be necessary
- // // or not, we fail fast if permission is not available.
- // sm.checkPermission(new RuntimePermission("setContextClassLoader"));
- // }
- // END Android-removed
+ // Whether setContextClassLoader turns out to be necessary
+ // or not, we fail fast if permission is not available.
+ sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+ }
+ */
this.task = task;
this.acc = AccessController.getContext();
this.ccl = Thread.currentThread().getContextClassLoader();
@@ -579,18 +584,19 @@
PrivilegedThreadFactory() {
super();
- // BEGIN Android-removed
- // SecurityManager sm = System.getSecurityManager();
- // if (sm != null) {
- // // Calls to getContextClassLoader from this class
- // // never trigger a security check, but we check
- // // whether our callers have this permission anyways.
- // sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
+ // Android-removed: System.getSecurityManager always returns null.
+ /*
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ // Calls to getContextClassLoader from this class
+ // never trigger a security check, but we check
+ // whether our callers have this permission anyways.
+ sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- // // Fail fast
- // sm.checkPermission(new RuntimePermission("setContextClassLoader"));
- // }
- // END Android-removed
+ // Fail fast
+ sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+ }
+ */
this.acc = AccessController.getContext();
this.ccl = Thread.currentThread().getContextClassLoader();
}
diff --git a/ojluni/src/main/java/java/util/concurrent/ForkJoinPool.java b/ojluni/src/main/java/java/util/concurrent/ForkJoinPool.java
index 9cf9b2d..04ad7d7 100644
--- a/ojluni/src/main/java/java/util/concurrent/ForkJoinPool.java
+++ b/ojluni/src/main/java/java/util/concurrent/ForkJoinPool.java
@@ -162,7 +162,8 @@
* @since 1.7
* @author Doug Lea
*/
-//@jdk.internal.vm.annotation.Contended // Android-removed
+// Android-removed: @Contended, this hint is not used by the Android runtime.
+//@jdk.internal.vm.annotation.Contended
public class ForkJoinPool extends AbstractExecutorService {
/*
@@ -781,7 +782,8 @@
* arrays sharing cache lines. The @Contended annotation alerts
* JVMs to try to keep instances apart.
*/
- //@jdk.internal.vm.annotation.Contended // Android-removed
+ // Android-removed: @Contended, this hint is not used by the Android runtime.
+ //@jdk.internal.vm.annotation.Contended
static final class WorkQueue {
/**
@@ -820,7 +822,8 @@
volatile Thread parker; // == owner during call to park; else null
volatile ForkJoinTask<?> currentJoin; // task being joined in awaitJoin
- // @jdk.internal.vm.annotation.Contended("group2") // segregate // Android-removed
+ // Android-removed: @Contended, this hint is not used by the Android runtime.
+ // @jdk.internal.vm.annotation.Contended("group2") // segregate
volatile ForkJoinTask<?> currentSteal; // nonnull when running some task
WorkQueue(ForkJoinPool pool, ForkJoinWorkerThread owner) {
diff --git a/ojluni/src/main/java/java/util/concurrent/ForkJoinTask.java b/ojluni/src/main/java/java/util/concurrent/ForkJoinTask.java
index 1f25549..efccfa5 100644
--- a/ojluni/src/main/java/java/util/concurrent/ForkJoinTask.java
+++ b/ojluni/src/main/java/java/util/concurrent/ForkJoinTask.java
@@ -1300,9 +1300,8 @@
*
* @return a task, or {@code null} if none are available
* @since 9
- * @hide
+ * @hide API from OpenJDK 9, not yet exposed on Android.
*/
- // Android-changed: hidden
protected static ForkJoinTask<?> pollSubmission() {
Thread t;
return ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
diff --git a/ojluni/src/main/java/java/util/concurrent/ThreadLocalRandom.java b/ojluni/src/main/java/java/util/concurrent/ThreadLocalRandom.java
index 03fa594..195f8ac 100644
--- a/ojluni/src/main/java/java/util/concurrent/ThreadLocalRandom.java
+++ b/ojluni/src/main/java/java/util/concurrent/ThreadLocalRandom.java
@@ -461,6 +461,7 @@
// stream methods, coded in a way intended to better isolate for
// maintenance purposes the small differences across forms.
+
/**
* Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code int} values.
diff --git a/ojluni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java b/ojluni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
index b7d2246..b0096a4 100644
--- a/ojluni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
+++ b/ojluni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
@@ -1545,6 +1545,7 @@
return handler;
}
+ // Android-changed: Tolerate maximumPoolSize >= corePoolSize during setCorePoolSize().
/**
* Sets the core number of threads. This overrides any value set
* in the constructor. If the new value is smaller than the
@@ -1556,15 +1557,15 @@
* @throws IllegalArgumentException if {@code corePoolSize < 0}
* @see #getCorePoolSize
*/
- // Android-changed: Reverted code that threw an IAE when
- // {@code corePoolSize} is greater than the {@linkplain #getMaximumPoolSize()
- // maximum pool size}. This is due to defective code in a commonly used third
- // party library that does something like :
- //
- // exec.setCorePoolSize(N);
- // exec.setMaxPoolSize(N);
public void setCorePoolSize(int corePoolSize) {
+ // BEGIN Android-changed: Tolerate maximumPoolSize >= corePoolSize during setCorePoolSize().
+ // This reverts a change that threw an IAE on that condition. This is due to defective code
+ // in a commonly used third party library that does something like exec.setCorePoolSize(N)
+ // before doing exec.setMaxPoolSize(N).
+ //
+ // if (corePoolSize < 0 || maximumPoolSize < corePoolSize)
if (corePoolSize < 0)
+ // END Android-changed: Tolerate maximumPoolSize >= corePoolSize during setCorePoolSize().
throw new IllegalArgumentException();
int delta = corePoolSize - this.corePoolSize;
this.corePoolSize = corePoolSize;
diff --git a/ojluni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/ojluni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
index 8812a8c..cdc1c5b 100644
--- a/ojluni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
+++ b/ojluni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
@@ -35,7 +35,6 @@
package java.util.concurrent.atomic;
-import dalvik.system.VMStack; // Android-added
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.AccessController;
@@ -85,7 +84,7 @@
public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass,
String fieldName) {
return new AtomicIntegerFieldUpdaterImpl<U>
- (tclass, fieldName, VMStack.getStackClass1()); // Android-changed
+ (tclass, fieldName, Reflection.getCallerClass());
}
/**
@@ -384,27 +383,33 @@
final Field field;
final int modifiers;
try {
+ // Android-changed: Skip privilege escalation which is a noop on Android.
+ /*
field = AccessController.doPrivileged(
new PrivilegedExceptionAction<Field>() {
public Field run() throws NoSuchFieldException {
return tclass.getDeclaredField(fieldName);
}
});
+ */
+ field = tclass.getDeclaredField(fieldName);
modifiers = field.getModifiers();
- // BEGIN Android-removed
- // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
- // caller, tclass, null, modifiers);
- // ClassLoader cl = tclass.getClassLoader();
- // ClassLoader ccl = caller.getClassLoader();
- // if ((ccl != null) && (ccl != cl) &&
- // ((cl == null) || !isAncestor(cl, ccl))) {
- // sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
- // }
- // END Android-removed
- // BEGIN Android-removed
- // } catch (PrivilegedActionException pae) {
- // throw new RuntimeException(pae.getException());
- // END Android-removed
+ sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+ caller, tclass, null, modifiers);
+ // BEGIN Android-removed: Skip checkPackageAccess which is a noop on Android.
+ /*
+ ClassLoader cl = tclass.getClassLoader();
+ ClassLoader ccl = caller.getClassLoader();
+ if ((ccl != null) && (ccl != cl) &&
+ ((cl == null) || !isAncestor(cl, ccl))) {
+ sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+ }
+ */
+ // BEGIN Android-removed: Skip privilege escalation which is a noop on Android.
+ /*
+ } catch (PrivilegedActionException pae) {
+ throw new RuntimeException(pae.getException());
+ */
} catch (Exception ex) {
throw new RuntimeException(ex);
}
@@ -420,23 +425,24 @@
this.offset = U.objectFieldOffset(field);
}
- // BEGIN Android-removed
- // /**
- // * Returns true if the second classloader can be found in the first
- // * classloader's delegation chain.
- // * Equivalent to the inaccessible: first.isAncestor(second).
- // */
- // private static boolean isAncestor(ClassLoader first, ClassLoader second) {
- // ClassLoader acl = first;
- // do {
- // acl = acl.getParent();
- // if (second == acl) {
- // return true;
- // }
- // } while (acl != null);
- // return false;
- // }
- // END Android-removed
+ // Android-removed: isAncestor's only usage was removed above.
+ /*
+ /**
+ * Returns true if the second classloader can be found in the first
+ * classloader's delegation chain.
+ * Equivalent to the inaccessible: first.isAncestor(second).
+ *
+ private static boolean isAncestor(ClassLoader first, ClassLoader second) {
+ ClassLoader acl = first;
+ do {
+ acl = acl.getParent();
+ if (second == acl) {
+ return true;
+ }
+ } while (acl != null);
+ return false;
+ }
+ */
/**
* Checks that target argument is instance of cclass. On
diff --git a/ojluni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/ojluni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
index 73c4e3e..447a642 100644
--- a/ojluni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
+++ b/ojluni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
@@ -35,7 +35,6 @@
package java.util.concurrent.atomic;
-import dalvik.system.VMStack; // Android-added
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.AccessController;
@@ -84,7 +83,7 @@
@CallerSensitive
public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass,
String fieldName) {
- Class<?> caller = VMStack.getStackClass1(); // Android-changed
+ Class<?> caller = Reflection.getCallerClass();
if (AtomicLong.VM_SUPPORTS_LONG_CAS)
return new CASUpdater<U>(tclass, fieldName, caller);
else
@@ -382,22 +381,33 @@
final Field field;
final int modifiers;
try {
- field = tclass.getDeclaredField(fieldName); // Android-changed
+ // Android-changed: Skip privilege escalation which is a noop on Android.
+ /*
+ field = AccessController.doPrivileged(
+ new PrivilegedExceptionAction<Field>() {
+ public Field run() throws NoSuchFieldException {
+ return tclass.getDeclaredField(fieldName);
+ }
+ });
+ */
+ field = tclass.getDeclaredField(fieldName);
modifiers = field.getModifiers();
- // BEGIN Android-removed
- // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
- // caller, tclass, null, modifiers);
- // ClassLoader cl = tclass.getClassLoader();
- // ClassLoader ccl = caller.getClassLoader();
- // if ((ccl != null) && (ccl != cl) &&
- // ((cl == null) || !isAncestor(cl, ccl))) {
- // sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
- // }
- // END Android-removed
- // BEGIN Android-removed
- // } catch (PrivilegedActionException pae) {
- // throw new RuntimeException(pae.getException());
- // END Android-removed
+ sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+ caller, tclass, null, modifiers);
+ // Android-removed: Skip checkPackageAccess which is a noop on Android.
+ /*
+ ClassLoader cl = tclass.getClassLoader();
+ ClassLoader ccl = caller.getClassLoader();
+ if ((ccl != null) && (ccl != cl) &&
+ ((cl == null) || !isAncestor(cl, ccl))) {
+ sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+ }
+ */
+ // Android-removed: Skip privilege escalation which is a noop on Android.
+ /*
+ } catch (PrivilegedActionException pae) {
+ throw new RuntimeException(pae.getException());
+ */
} catch (Exception ex) {
throw new RuntimeException(ex);
}
@@ -512,22 +522,33 @@
Field field = null;
int modifiers = 0;
try {
- field = tclass.getDeclaredField(fieldName); // Android-changed
+ // Android-changed: Skip privilege escalation which is a noop on Android.
+ /*
+ field = AccessController.doPrivileged(
+ new PrivilegedExceptionAction<Field>() {
+ public Field run() throws NoSuchFieldException {
+ return tclass.getDeclaredField(fieldName);
+ }
+ });
+ */
+ field = tclass.getDeclaredField(fieldName);
modifiers = field.getModifiers();
- // BEGIN Android-removed
- // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
- // caller, tclass, null, modifiers);
- // ClassLoader cl = tclass.getClassLoader();
- // ClassLoader ccl = caller.getClassLoader();
- // if ((ccl != null) && (ccl != cl) &&
- // ((cl == null) || !isAncestor(cl, ccl))) {
- // sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
- // }
- // END Android-removed
- // BEGIN Android-removed
- // } catch (PrivilegedActionException pae) {
- // throw new RuntimeException(pae.getException());
- // END Android-removed
+ sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+ caller, tclass, null, modifiers);
+ // Android-removed: Skip checkPackageAccess which is a noop on Android.
+ /*
+ ClassLoader cl = tclass.getClassLoader();
+ ClassLoader ccl = caller.getClassLoader();
+ if ((ccl != null) && (ccl != cl) &&
+ ((cl == null) || !isAncestor(cl, ccl))) {
+ sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+ }
+ */
+ // Android-removed: Skip privilege escalation which is a noop on Android.
+ /*
+ } catch (PrivilegedActionException pae) {
+ throw new RuntimeException(pae.getException());
+ */
} catch (Exception ex) {
throw new RuntimeException(ex);
}
@@ -604,21 +625,22 @@
}
}
- // BEGIN Android-removed
- // /**
- // * Returns true if the second classloader can be found in the first
- // * classloader's delegation chain.
- // * Equivalent to the inaccessible: first.isAncestor(second).
- // */
- // static boolean isAncestor(ClassLoader first, ClassLoader second) {
- // ClassLoader acl = first;
- // do {
- // acl = acl.getParent();
- // if (second == acl) {
- // return true;
- // }
- // } while (acl != null);
- // return false;
- // }
- // END Android-removed
+ // Android-removed: isAncestor's only usage was removed above.
+ /*
+ /**
+ * Returns true if the second classloader can be found in the first
+ * classloader's delegation chain.
+ * Equivalent to the inaccessible: first.isAncestor(second).
+ *
+ static boolean isAncestor(ClassLoader first, ClassLoader second) {
+ ClassLoader acl = first;
+ do {
+ acl = acl.getParent();
+ if (second == acl) {
+ return true;
+ }
+ } while (acl != null);
+ return false;
+ }
+ */
}
diff --git a/ojluni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/ojluni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
index 5164f36..17423ad 100644
--- a/ojluni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
+++ b/ojluni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
@@ -35,7 +35,6 @@
package java.util.concurrent.atomic;
-import dalvik.system.VMStack; // Android-added
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.AccessController;
@@ -107,7 +106,7 @@
Class<W> vclass,
String fieldName) {
return new AtomicReferenceFieldUpdaterImpl<U,W>
- (tclass, vclass, fieldName, VMStack.getStackClass1()); // Android-changed
+ (tclass, vclass, fieldName, Reflection.getCallerClass());
}
/**
@@ -317,23 +316,34 @@
final Class<?> fieldClass;
final int modifiers;
try {
- field = tclass.getDeclaredField(fieldName); // Android-changed
+ // Android-changed: Skip privilege escalation which is a noop on Android.
+ /*
+ field = AccessController.doPrivileged(
+ new PrivilegedExceptionAction<Field>() {
+ public Field run() throws NoSuchFieldException {
+ return tclass.getDeclaredField(fieldName);
+ }
+ });
+ */
+ field = tclass.getDeclaredField(fieldName);
modifiers = field.getModifiers();
- // BEGIN Android-removed
- // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
- // caller, tclass, null, modifiers);
- // ClassLoader cl = tclass.getClassLoader();
- // ClassLoader ccl = caller.getClassLoader();
- // if ((ccl != null) && (ccl != cl) &&
- // ((cl == null) || !isAncestor(cl, ccl))) {
- // sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
- // }
- // END Android-removed
+ sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+ caller, tclass, null, modifiers);
+ // Android-removed: Skip checkPackageAccess which is a noop on Android.
+ /*
+ ClassLoader cl = tclass.getClassLoader();
+ ClassLoader ccl = caller.getClassLoader();
+ if ((ccl != null) && (ccl != cl) &&
+ ((cl == null) || !isAncestor(cl, ccl))) {
+ sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+ }
+ */
fieldClass = field.getType();
- // BEGIN Android-removed
- // } catch (PrivilegedActionException pae) {
- // throw new RuntimeException(pae.getException());
- // END Android-removed
+ // Android-removed: Skip privilege escalation which is a noop on Android.
+ /*
+ } catch (PrivilegedActionException pae) {
+ throw new RuntimeException(pae.getException());
+ */
} catch (Exception ex) {
throw new RuntimeException(ex);
}
@@ -352,23 +362,24 @@
this.offset = U.objectFieldOffset(field);
}
- // BEGIN Android-removed
- // /**
- // * Returns true if the second classloader can be found in the first
- // * classloader's delegation chain.
- // * Equivalent to the inaccessible: first.isAncestor(second).
- // */
- // private static boolean isAncestor(ClassLoader first, ClassLoader second) {
- // ClassLoader acl = first;
- // do {
- // acl = acl.getParent();
- // if (second == acl) {
- // return true;
- // }
- // } while (acl != null);
- // return false;
- // }
- // END Android-removed
+ // Android-removed: isAncestor's only usage was removed above.
+ /*
+ /**
+ * Returns true if the second classloader can be found in the first
+ * classloader's delegation chain.
+ * Equivalent to the inaccessible: first.isAncestor(second).
+ *
+ private static boolean isAncestor(ClassLoader first, ClassLoader second) {
+ ClassLoader acl = first;
+ do {
+ acl = acl.getParent();
+ if (second == acl) {
+ return true;
+ }
+ } while (acl != null);
+ return false;
+ }
+ */
/**
* Checks that target argument is instance of cclass. On
diff --git a/ojluni/src/main/java/java/util/concurrent/atomic/Striped64.java b/ojluni/src/main/java/java/util/concurrent/atomic/Striped64.java
index e52729a..2a8f327 100644
--- a/ojluni/src/main/java/java/util/concurrent/atomic/Striped64.java
+++ b/ojluni/src/main/java/java/util/concurrent/atomic/Striped64.java
@@ -119,7 +119,8 @@
* JVM intrinsics note: It would be possible to use a release-only
* form of CAS here, if it were provided.
*/
- // @jdk.internal.vm.annotation.Contended // Android-removed
+ // Android-removed: @Contended, this hint is not used by the Android runtime.
+ // @jdk.internal.vm.annotation.Contended
static final class Cell {
volatile long value;
Cell(long x) { value = x; }
diff --git a/ojluni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/ojluni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
index 894de90..602b5ce 100644
--- a/ojluni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
+++ b/ojluni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
@@ -886,6 +886,8 @@
* @param arg the acquire argument
* @return {@code true} if interrupted while waiting
*/
+ // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+ // @ReservedStackAccess
final boolean acquireQueued(final Node node, int arg) {
try {
boolean interrupted = false;
@@ -1218,6 +1220,8 @@
* {@link #tryAcquire} but is otherwise uninterpreted and
* can represent anything you like.
*/
+ // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+ // @ReservedStackAccess
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
@@ -1281,6 +1285,8 @@
* can represent anything you like.
* @return the value returned from {@link #tryRelease}
*/
+ // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+ // @ReservedStackAccess
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
@@ -1361,6 +1367,8 @@
* and can represent anything you like.
* @return the value returned from {@link #tryReleaseShared}
*/
+ // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+ // @ReservedStackAccess
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
diff --git a/ojluni/src/main/java/java/util/concurrent/locks/ReentrantLock.java b/ojluni/src/main/java/java/util/concurrent/locks/ReentrantLock.java
index 9df2505..3c1c492 100644
--- a/ojluni/src/main/java/java/util/concurrent/locks/ReentrantLock.java
+++ b/ojluni/src/main/java/java/util/concurrent/locks/ReentrantLock.java
@@ -127,6 +127,8 @@
* Performs non-fair tryLock. tryAcquire is implemented in
* subclasses, but both need nonfair try for trylock method.
*/
+ // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+ // @ReservedStackAccess
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
@@ -146,6 +148,8 @@
return false;
}
+ // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+ // @ReservedStackAccess
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
@@ -203,6 +207,8 @@
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
+ // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+ // @ReservedStackAccess
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
@@ -229,6 +235,8 @@
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
*/
+ // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+ // @ReservedStackAccess
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
diff --git a/ojluni/src/main/java/java/util/jar/Attributes.java b/ojluni/src/main/java/java/util/jar/Attributes.java
index 9193542..dd279a5 100644
--- a/ojluni/src/main/java/java/util/jar/Attributes.java
+++ b/ojluni/src/main/java/java/util/jar/Attributes.java
@@ -528,7 +528,7 @@
* <code>Name</code> object for <code>Manifest-Version</code>
* manifest attribute. This attribute indicates the version number
* of the manifest standard to which a JAR file's manifest conforms.
- * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html#JAR Manifest">
+ * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html#JAR_Manifest">
* Manifest and Signature Specification</a>
*/
public static final Name MANIFEST_VERSION = new Name("Manifest-Version");
@@ -536,7 +536,7 @@
/**
* <code>Name</code> object for <code>Signature-Version</code>
* manifest attribute used when signing JAR files.
- * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html#JAR Manifest">
+ * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html#JAR_Manifest">
* Manifest and Signature Specification</a>
*/
public static final Name SIGNATURE_VERSION = new Name("Signature-Version");
@@ -669,10 +669,5 @@
* Java Product Versioning Specification</a>
*/
public static final Name SPECIFICATION_VENDOR = new Name("Specification-Vendor");
-
- /**
- * @hide
- */
- public static final Name NAME = new Name("Name");
}
}
diff --git a/ojluni/src/main/java/java/util/jar/JarFile.java b/ojluni/src/main/java/java/util/jar/JarFile.java
index cf8acd8..342e341 100644
--- a/ojluni/src/main/java/java/util/jar/JarFile.java
+++ b/ojluni/src/main/java/java/util/jar/JarFile.java
@@ -67,7 +67,8 @@
*/
public
class JarFile extends ZipFile {
- static final String META_DIR = "META-INF/";
+ // Android-changed: Hold the Manifest via a hard reference. http://b/28692091
+ // private SoftReference<Manifest> manRef;
private Manifest manifest;
private JarEntry manEntry;
private JarVerifier jv;
@@ -79,6 +80,14 @@
// true if manifest checked for special attributes
private volatile boolean hasCheckedSpecialAttributes;
+ // Android-removed: SharedSecrets.setJavaUtilJarAccess
+ /*
+ // Set up JavaUtilJarAccess in SharedSecrets
+ static {
+ SharedSecrets.setJavaUtilJarAccess(new JavaUtilJarAccessImpl());
+ }
+ */
+
/**
* The JAR manifest file name.
*/
@@ -174,8 +183,15 @@
return getManifestFromReference();
}
+ // BEGIN Android-changed: Fix JarFile to be thread safe. http://b/27826114
+ // A volatile field might also work instead of synchronized. http://b/81505612
+ // private Manifest getManifestFromReference() throws IOException {
private synchronized Manifest getManifestFromReference() throws IOException {
- if (manifest == null) {
+ // END Android-changed: Fix JarFile to be thread safe. http://b/27826114
+ // Android-changed: Hold the Manifest via a hard reference. http://b/28692091
+ // Manifest man = manRef != null ? manRef.get() : null;
+ Manifest man = manifest;
+ if (man == null) {
JarEntry manEntry = getManEntry();
@@ -183,16 +199,19 @@
if (manEntry != null) {
if (verify) {
byte[] b = getBytes(manEntry);
- manifest = new Manifest(new ByteArrayInputStream(b));
+ man = new Manifest(new ByteArrayInputStream(b));
if (!jvInitialized) {
jv = new JarVerifier(b);
}
} else {
- manifest = new Manifest(super.getInputStream(manEntry));
+ man = new Manifest(super.getInputStream(manEntry));
}
+ // Android-changed: Hold the Manifest via a hard reference. http://b/28692091
+ // manRef = new SoftReference<>(man);
+ manifest = man;
}
}
- return manifest;
+ return man;
}
private native String[] getMetaInfEntryNames();
@@ -479,7 +498,11 @@
CLASSPATH_OPTOSFT[9]=1;
}
+ // BEGIN Android-changed: Fix JarFile to be thread safe. http://b/27826114
+ // A volatile field might also work instead of synchronized. http://b/81505612
+ // private JarEntry getManEntry() {
private synchronized JarEntry getManEntry() {
+ // END Android-changed: Fix JarFile to be thread safe. http://b/27826114
if (manEntry == null) {
// First look up manifest entry using standard name
manEntry = getJarEntry(MANIFEST_NAME);
@@ -501,11 +524,14 @@
return manEntry;
}
- /**
- * Returns {@code true} iff this JAR file has a manifest with the
- * Class-Path attribute
- * @hide
- */
+ /**
+ * Returns {@code true} iff this JAR file has a manifest with the
+ * Class-Path attribute
+ * @hide
+ */
+ // Android-changed: Make hasClassPathAttribute() @hide public, for internal use.
+ // Used by URLClassPath.JarLoader.
+ // boolean hasClassPathAttribute() throws IOException {
public boolean hasClassPathAttribute() throws IOException {
checkForSpecialAttributes();
return hasClassPathAttribute;
@@ -541,8 +567,8 @@
*/
private void checkForSpecialAttributes() throws IOException {
if (hasCheckedSpecialAttributes) return;
- // Android-changed: Doesn't make sense on android:
- //if (!isKnownNotToHaveSpecialAttributes()) {
+ // Android-changed: Special handling of well-known .jar files specific to OpenJDK.
+ // if (!isKnownNotToHaveSpecialAttributes()) {
{
JarEntry manEntry = getManEntry();
if (manEntry != null) {
@@ -555,8 +581,9 @@
}
- // Android-changed: Doesn't make sense on android:
- /*private static String javaHome;
+ // Android-removed: Special handling of well-known .jar files specific to OpenJDK.
+ /*
+ private static String javaHome;
private static volatile String[] jarNames;
private boolean isKnownNotToHaveSpecialAttributes() {
// Optimize away even scanning of manifest for jar files we
@@ -596,9 +623,199 @@
}
}
return false;
- }*/
+ }
+ */
+
+ // Android-removed: Unused method ensureInitialization().
+ /*
+ private synchronized void ensureInitialization() {
+ try {
+ maybeInstantiateVerifier();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ if (jv != null && !jvInitialized) {
+ initializeVerifier();
+ jvInitialized = true;
+ }
+ }
+ */
JarEntry newEntry(ZipEntry ze) {
return new JarFileEntry(ze);
}
+
+ // Android-removed: Unused methods entryNames(), entries2().
+ /*
+ Enumeration<String> entryNames(CodeSource[] cs) {
+ ensureInitialization();
+ if (jv != null) {
+ return jv.entryNames(this, cs);
+ }
+
+ /*
+ * JAR file has no signed content. Is there a non-signing
+ * code source?
+ *
+ boolean includeUnsigned = false;
+ for (int i = 0; i < cs.length; i++) {
+ if (cs[i].getCodeSigners() == null) {
+ includeUnsigned = true;
+ break;
+ }
+ }
+ if (includeUnsigned) {
+ return unsignedEntryNames();
+ } else {
+ return new Enumeration<String>() {
+
+ public boolean hasMoreElements() {
+ return false;
+ }
+
+ public String nextElement() {
+ throw new NoSuchElementException();
+ }
+ };
+ }
+ }
+
+ /**
+ * Returns an enumeration of the zip file entries
+ * excluding internal JAR mechanism entries and including
+ * signed entries missing from the ZIP directory.
+ *
+ Enumeration<JarEntry> entries2() {
+ ensureInitialization();
+ if (jv != null) {
+ return jv.entries2(this, super.entries());
+ }
+
+ // screen out entries which are never signed
+ final Enumeration<? extends ZipEntry> enum_ = super.entries();
+ return new Enumeration<JarEntry>() {
+
+ ZipEntry entry;
+
+ public boolean hasMoreElements() {
+ if (entry != null) {
+ return true;
+ }
+ while (enum_.hasMoreElements()) {
+ ZipEntry ze = enum_.nextElement();
+ if (JarVerifier.isSigningRelated(ze.getName())) {
+ continue;
+ }
+ entry = ze;
+ return true;
+ }
+ return false;
+ }
+
+ public JarFileEntry nextElement() {
+ if (hasMoreElements()) {
+ ZipEntry ze = entry;
+ entry = null;
+ return new JarFileEntry(ze);
+ }
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
+ CodeSource[] getCodeSources(URL url) {
+ ensureInitialization();
+ if (jv != null) {
+ return jv.getCodeSources(this, url);
+ }
+
+ /*
+ * JAR file has no signed content. Is there a non-signing
+ * code source?
+ *
+ Enumeration<String> unsigned = unsignedEntryNames();
+ if (unsigned.hasMoreElements()) {
+ return new CodeSource[]{JarVerifier.getUnsignedCS(url)};
+ } else {
+ return null;
+ }
+ }
+
+ private Enumeration<String> unsignedEntryNames() {
+ final Enumeration<JarEntry> entries = entries();
+ return new Enumeration<String>() {
+
+ String name;
+
+ /*
+ * Grab entries from ZIP directory but screen out
+ * metadata.
+ *
+ public boolean hasMoreElements() {
+ if (name != null) {
+ return true;
+ }
+ while (entries.hasMoreElements()) {
+ String value;
+ ZipEntry e = entries.nextElement();
+ value = e.getName();
+ if (e.isDirectory() || JarVerifier.isSigningRelated(value)) {
+ continue;
+ }
+ name = value;
+ return true;
+ }
+ return false;
+ }
+
+ public String nextElement() {
+ if (hasMoreElements()) {
+ String value = name;
+ name = null;
+ return value;
+ }
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
+ CodeSource getCodeSource(URL url, String name) {
+ ensureInitialization();
+ if (jv != null) {
+ if (jv.eagerValidation) {
+ CodeSource cs = null;
+ JarEntry je = getJarEntry(name);
+ if (je != null) {
+ cs = jv.getCodeSource(url, this, je);
+ } else {
+ cs = jv.getCodeSource(url, name);
+ }
+ return cs;
+ } else {
+ return jv.getCodeSource(url, name);
+ }
+ }
+
+ return JarVerifier.getUnsignedCS(url);
+ }
+
+ void setEagerValidation(boolean eager) {
+ try {
+ maybeInstantiateVerifier();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ if (jv != null) {
+ jv.setEagerValidation(eager);
+ }
+ }
+
+ List<Object> getManifestDigests() {
+ ensureInitialization();
+ if (jv != null) {
+ return jv.getManifestDigests();
+ }
+ return new ArrayList<Object>();
+ }
+ */
}
diff --git a/ojluni/src/main/java/java/util/jar/JarVerifier.java b/ojluni/src/main/java/java/util/jar/JarVerifier.java
index 4b243de..e0e7d55 100644
--- a/ojluni/src/main/java/java/util/jar/JarVerifier.java
+++ b/ojluni/src/main/java/java/util/jar/JarVerifier.java
@@ -333,6 +333,7 @@
}
}
+ // Android-changed: @deprecated tag needs a description. http://b/110781661
/**
* Return an array of java.security.cert.Certificate objects for
* the given file in the jar.
@@ -447,11 +448,14 @@
InputStream is,
JarVerifier jv) throws IOException
{
- // Android-changed: Added to make sure inputs are not null. This allows to
- // use is == null to detect closed verifier streams.
+ // BEGIN Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
+ // To know that null signals that the stream has been closed, we disallow
+ // it in the constructor. There's no need for anyone to pass null into this
+ // constructor, anyway.
if (is == null) {
throw new NullPointerException("is == null");
}
+ // END Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
this.is = is;
this.jv = jv;
this.mev = new ManifestEntryVerifier(man);
@@ -463,11 +467,11 @@
public int read() throws IOException
{
- // Android-added.
+ // BEGIN Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
if (is == null) {
throw new IOException("stream closed");
}
-
+ // END Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
if (numLeft > 0) {
int b = is.read();
jv.update(b, mev);
@@ -481,11 +485,11 @@
}
public int read(byte b[], int off, int len) throws IOException {
- // Android-added.
+ // BEGIN Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
if (is == null) {
throw new IOException("stream closed");
}
-
+ // END Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
if ((numLeft > 0) && (numLeft < len)) {
len = (int)numLeft;
}
@@ -513,11 +517,11 @@
}
public int available() throws IOException {
- // Android-added.
+ // BEGIN Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
if (is == null) {
throw new IOException("stream closed");
}
-
+ // END Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
return is.available();
}
diff --git a/ojluni/src/main/java/java/util/logging/FileHandler.java b/ojluni/src/main/java/java/util/logging/FileHandler.java
index 9cae655..24a7c75 100644
--- a/ojluni/src/main/java/java/util/logging/FileHandler.java
+++ b/ojluni/src/main/java/java/util/logging/FileHandler.java
@@ -598,13 +598,14 @@
continue;
} else if (ch2 == 'h') {
file = new File(System.getProperty("user.home"));
- // Android-changed: Don't make a special exemption for setuid programs.
- //
- // if (isSetUID()) {
- // // Ok, we are in a set UID program. For safety's sake
- // // we disallow attempts to open files relative to %h.
- // throw new IOException("can't use %h in set UID program");
- // }
+ // Android-removed: Don't prohibit using user.home property in setuid programs.
+ /*
+ if (isSetUID()) {
+ // Ok, we are in a set UID program. For safety's sake
+ // we disallow attempts to open files relative to %h.
+ throw new IOException("can't use %h in set UID program");
+ }
+ */
ix++;
word = "";
continue;
@@ -735,9 +736,11 @@
}
}
- // Android-changed: Not required.
+ // Android-removed: isSetUID's only caller is removed.
+ /*
/**
* check if we are in a set UID program.
- */
- // private static native boolean isSetUID();
+ *
+ private static native boolean isSetUID();
+ */
}
diff --git a/ojluni/src/main/java/java/util/logging/Level.java b/ojluni/src/main/java/java/util/logging/Level.java
index c03b171..17b585b 100644
--- a/ojluni/src/main/java/java/util/logging/Level.java
+++ b/ojluni/src/main/java/java/util/logging/Level.java
@@ -262,8 +262,9 @@
}
private String computeLocalizedLevelName(Locale newLocale) {
- // Android-changed: Use Thread.currentThread().getContextClassLoader(),
- // otherwise we might get a BootClassLoader.
+ // Android-changed: Use Thread.currentThread().getContextClassLoader().
+ // Otherwise, we might get a BootClassLoader.
+ // ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName, newLocale);
ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName, newLocale,
Thread.currentThread().getContextClassLoader());
final String localizedName = rb.getString(name);
diff --git a/ojluni/src/main/java/java/util/logging/LogManager.java b/ojluni/src/main/java/java/util/logging/LogManager.java
index 7a08510..0d51b0f 100644
--- a/ojluni/src/main/java/java/util/logging/LogManager.java
+++ b/ojluni/src/main/java/java/util/logging/LogManager.java
@@ -185,6 +185,7 @@
try {
cname = System.getProperty("java.util.logging.manager");
if (cname != null) {
+ // Android-changed: Extract logic into the getClassInstance() helper.
mgr = (LogManager) getClassInstance(cname).newInstance();
}
} catch (Exception ex) {
@@ -198,7 +199,7 @@
}
});
- }
+ }
// This private class is used as a shutdown hook.
@@ -487,7 +488,7 @@
// Returns the LoggerContext for the user code (i.e. application or AppContext).
// Loggers are isolated from each AppContext.
private LoggerContext getUserContext() {
- // Android-changed: No AWT specific hooks.
+ // Android-changed: Remove AWT specific hooks.
return userContext;
}
@@ -582,20 +583,13 @@
return sysLogger;
}
- private static Class getClassInstance(String cname) {
- Class clz = null;
- if (cname != null) {
- try {
- clz = ClassLoader.getSystemClassLoader().loadClass(cname);
- } catch (ClassNotFoundException ex) {
- try {
- clz = Thread.currentThread().getContextClassLoader().loadClass(cname);
- } catch (ClassNotFoundException innerEx) {
- clz = null;
- }
- }
+ // Android-added: getClassInstance helper method, used in several places in this class.
+ private static Class getClassInstance(String cname) throws ClassNotFoundException {
+ try {
+ return ClassLoader.getSystemClassLoader().loadClass(cname);
+ } catch (ClassNotFoundException ex) {
+ return Thread.currentThread().getContextClassLoader().loadClass(cname);
}
- return clz;
}
// LoggerContext maintains the logger namespace per context.
@@ -641,7 +635,7 @@
// the context requires default loggers, will be added to the context
// logger's tree.
final Logger getGlobalLogger() {
- // Android-changed: s/deprecated/deprecation
+ // Android-changed: Fix SuppressWarnings from "deprecated" to "deprecation".
@SuppressWarnings("deprecation") // avoids initialization cycles.
final Logger global = Logger.global;
return global;
@@ -743,19 +737,9 @@
return addLocalLogger(logger, requiresDefaultLoggers());
}
- boolean addLocalLogger(Logger logger, LogManager manager) {
- // no need to add default loggers if it's not required
- return addLocalLogger(logger, requiresDefaultLoggers(), manager);
- }
-
- boolean addLocalLogger(Logger logger, boolean addDefaultLoggersIfNeeded) {
- return addLocalLogger(logger, addDefaultLoggersIfNeeded, manager);
- }
-
// Add a logger to this context. This method will only set its level
// and process parent loggers. It doesn't set its handlers.
- synchronized boolean addLocalLogger(Logger logger, boolean addDefaultLoggersIfNeeded,
- LogManager manager) {
+ synchronized boolean addLocalLogger(Logger logger, boolean addDefaultLoggersIfNeeded) {
// addDefaultLoggersIfNeeded serves to break recursion when adding
// default loggers. If we're adding one of the default loggers
// (we're being called from ensureDefaultLogger()) then
@@ -957,7 +941,8 @@
for (int i = 0; i < names.length; i++) {
String word = names[i];
try {
- // Android-changed:
+ // Android-changed: Fall back from the system to the context classloader.
+ // Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(word);
Class<?> clz = getClassInstance(word);
Handler hdl = (Handler) clz.newInstance();
// Check if there is a property defining the
@@ -1155,7 +1140,7 @@
}
drainLoggerRefQueueBounded();
LoggerContext cx = getUserContext();
- if (cx.addLocalLogger(logger, this)) {
+ if (cx.addLocalLogger(logger)) {
// Do we have a per logger handler too?
// Note: this will add a 200ms penalty
loadLoggerHandlers(logger, name, name + ".handlers");
@@ -1268,6 +1253,7 @@
// Instantiate the named class. It is its constructor's
// responsibility to initialize the logging configuration, by
// calling readConfiguration(InputStream) with a suitable stream.
+ // Android-changed: Extract logic into the getClassInstance() helper.
getClassInstance(cname).newInstance();
return;
} catch (Exception ex) {
@@ -1288,8 +1274,14 @@
fname = f.getCanonicalPath();
}
- // Android-changed: Look in the boot class-path jar files for the logging.properties.
- // It will not be present in the file system.
+ // BEGIN Android-changed: Look in the boot class-path jar files for the logging.properties.
+ // It may not be present in the file system.
+ /*
+ try (final InputStream in = new FileInputStream(fname)) {
+ final BufferedInputStream bin = new BufferedInputStream(in);
+ readConfiguration(bin);
+ }
+ */
InputStream in;
try {
in = new FileInputStream(fname);
@@ -1308,6 +1300,7 @@
in.close();
}
}
+ // END Android-changed: Look in the boot class-path jar files for the logging.properties.
}
/**
@@ -1419,6 +1412,9 @@
for (int i = 0; i < names.length; i++) {
String word = names[i];
try {
+ // Android-changed: Fall back from the system to the context classloader.
+ // Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(word);
+ // clz.newInstance();
getClassInstance(word).newInstance();
} catch (Exception ex) {
System.err.println("Can't load config class \"" + word + "\"");
@@ -1531,6 +1527,9 @@
String val = getProperty(name);
try {
if (val != null) {
+ // Android-changed: Fall back from the system to the context classloader.
+ // Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(val);
+ // return (Filter) clz.newInstance();
return (Filter) getClassInstance(val).newInstance();
}
} catch (Exception ex) {
@@ -1551,6 +1550,9 @@
String val = getProperty(name);
try {
if (val != null) {
+ // Android-changed: Fall back from the system to the context classloader.
+ // Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(val);
+ // return (Formatter) clz.newInstance();
return (Formatter) getClassInstance(val).newInstance();
}
} catch (Exception ex) {
@@ -1702,6 +1704,7 @@
// Management Support
private static LoggingMXBean loggingMXBean = null;
+ // Android-removed: References to java.lang.management in javadoc.
/**
* String representation of the {@code ObjectName} for the management interface
* for the logging facility.
@@ -1710,12 +1713,10 @@
*
* @since 1.5
*/
- // Android-changed: Remove reference to java.lang.management.ObjectName.
- //
- //@see java.lang.management.PlatformLoggingMXBean
public final static String LOGGING_MXBEAN_NAME
= "java.util.logging:type=Logging";
+ // Android-removed: References to java.lang.management in javadoc.
/**
* Returns <tt>LoggingMXBean</tt> for managing loggers.
*
@@ -1723,17 +1724,6 @@
*
* @since 1.5
*/
- // Android-removed docs areferring to java.lang.management.
- //
- // An alternative way to manage loggers is through the
- // {@link java.lang.management.PlatformLoggingMXBean} interface
- // that can be obtained by calling:
- // <pre>
- // PlatformLoggingMXBean logging = {@link java.lang.management.ManagementFactory#getPlatformMXBean(Class)
- // ManagementFactory.getPlatformMXBean}(PlatformLoggingMXBean.class);
- // </pre>
- //
- // @see java.lang.management.PlatformLoggingMXBean
public static synchronized LoggingMXBean getLoggingMXBean() {
if (loggingMXBean == null) {
loggingMXBean = new Logging();
diff --git a/ojluni/src/main/java/java/util/logging/LogRecord.java b/ojluni/src/main/java/java/util/logging/LogRecord.java
index e5ead8b..3b0e518 100644
--- a/ojluni/src/main/java/java/util/logging/LogRecord.java
+++ b/ojluni/src/main/java/java/util/logging/LogRecord.java
@@ -528,6 +528,12 @@
ClassLoader.getSystemClassLoader());
resourceBundle = bundle;
} catch (MissingResourceException ex) {
+ // Android-changed: Fall back to context classloader before giving up.
+ /*
+ // This is not a good place to throw an exception,
+ // so we simply leave the resourceBundle null.
+ resourceBundle = null;
+ */
try {
resourceBundle = ResourceBundle.getBundle(resourceBundleName, Locale.getDefault(),
Thread.currentThread().getContextClassLoader());
@@ -545,16 +551,24 @@
// Private method to infer the caller's class and method names
private void inferCaller() {
needToInferCaller = false;
- // Android-changed: Use VMStack.getThreadStackTrace.
+ // BEGIN Android-changed: Use VMStack.getThreadStackTrace.
+ /*
+ JavaLangAccess access = SharedSecrets.getJavaLangAccess();
+ Throwable throwable = new Throwable();
+ int depth = access.getStackTraceDepth(throwable);
+ */
StackTraceElement[] stack = VMStack.getThreadStackTrace(Thread.currentThread());
int depth = stack.length;
+ // END Android-changed: Use VMStack.getThreadStackTrace.
boolean lookingForLogger = true;
for (int ix = 0; ix < depth; ix++) {
// Calling getStackTraceElement directly prevents the VM
// from paying the cost of building the entire stack frame.
//
- // Android-changed: Use value from getThreadStackTrace.
+ // Android-changed: Use value from previous getThreadStackTrace call.
+ // StackTraceElement frame =
+ // access.getStackTraceElement(throwable, ix);
StackTraceElement frame = stack[ix];
String cname = frame.getClassName();
boolean isLoggerImpl = isLoggerImplFrame(cname);
diff --git a/ojluni/src/main/java/java/util/logging/Logger.java b/ojluni/src/main/java/java/util/logging/Logger.java
index 8cf98fe..61bbe4e 100644
--- a/ojluni/src/main/java/java/util/logging/Logger.java
+++ b/ojluni/src/main/java/java/util/logging/Logger.java
@@ -1,5 +1,4 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -27,7 +26,6 @@
package java.util.logging;
-import dalvik.system.VMStack;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -39,6 +37,7 @@
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Supplier;
import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
/**
* A Logger object is used to log messages for a specific
@@ -441,7 +440,7 @@
return System.getProperty(key);
}
});
- return Boolean.parseBoolean(s);
+ return Boolean.valueOf(s);
}
}
@@ -500,9 +499,7 @@
// would throw an IllegalArgumentException in the second call
// because the wrapper would result in an attempt to replace
// the existing "resourceBundleForFoo" with null.
- //
- // Android-changed: Use VMStack.getStackClass1.
- return demandLogger(name, null, VMStack.getStackClass1());
+ return demandLogger(name, null, Reflection.getCallerClass());
}
/**
@@ -552,8 +549,7 @@
// adding a new Logger object is handled by LogManager.addLogger().
@CallerSensitive
public static Logger getLogger(String name, String resourceBundleName) {
- // Android-changed: Use VMStack.getStackClass1.
- Class<?> callerClass = VMStack.getStackClass1();
+ Class<?> callerClass = Reflection.getCallerClass();
Logger result = demandLogger(name, resourceBundleName, callerClass);
// MissingResourceException or IllegalArgumentException can be
@@ -641,9 +637,8 @@
LogManager manager = LogManager.getLogManager();
// cleanup some Loggers that have been GC'ed
manager.drainLoggerRefQueueBounded();
- // Android-changed: Use VMStack.getStackClass1.
Logger result = new Logger(null, resourceBundleName,
- VMStack.getStackClass1(), manager, false);
+ Reflection.getCallerClass(), manager, false);
result.anonymous = true;
Logger root = manager.getLogger("");
result.doSetParent(root);
@@ -1894,6 +1889,7 @@
if (useCallersClassLoader) {
// Try with the caller's ClassLoader
ClassLoader callersClassLoader = getCallersClassLoader();
+
if (callersClassLoader == null || callersClassLoader == cl) {
return null;
}
diff --git a/ojluni/src/main/java/java/util/logging/LoggingMXBean.java b/ojluni/src/main/java/java/util/logging/LoggingMXBean.java
index 0c67cc5..14777c0 100644
--- a/ojluni/src/main/java/java/util/logging/LoggingMXBean.java
+++ b/ojluni/src/main/java/java/util/logging/LoggingMXBean.java
@@ -26,6 +26,7 @@
package java.util.logging;
+// Android-removed: References to java.lang.management in javadoc.
/**
* The management interface for the logging facility.
@@ -44,28 +45,6 @@
* @since 1.5
*
*/
-
-// Android-removed: References to java.lang.management.
-//
-// It is recommended
-// to use the {@link java.lang.management.PlatformLoggingMXBean} management
-// interface that implements all attributes defined in this
-// {@code LoggingMXBean}. The
-// {@link java.lang.management.ManagementFactory#getPlatformMXBean(Class)
-// ManagementFactory.getPlatformMXBean} method can be used to obtain
-// the {@code PlatformLoggingMXBean} object representing the management
-// interface for logging.
-//
-// This instance is an {@link javax.management.MXBean MXBean} that
-// can be obtained by calling the {@link LogManager#getLoggingMXBean}
-// method or from the
-// {@linkplain java.lang.management.ManagementFactory#getPlatformMBeanServer
-// platform <tt>MBeanServer</tt>}.
-//
-// The instance registered in the platform {@code MBeanServer}
-// is also a {@link java.lang.management.PlatformLoggingMXBean}.
-//
-// @see java.lang.management.PlatformLoggingMXBean
public interface LoggingMXBean {
/**
diff --git a/ojluni/src/main/java/java/util/logging/MemoryHandler.java b/ojluni/src/main/java/java/util/logging/MemoryHandler.java
index 94153dc..704c155 100644
--- a/ojluni/src/main/java/java/util/logging/MemoryHandler.java
+++ b/ojluni/src/main/java/java/util/logging/MemoryHandler.java
@@ -129,12 +129,13 @@
+ " does not specify a target");
}
Class<?> clz;
-
try {
clz = ClassLoader.getSystemClassLoader().loadClass(targetName);
target = (Handler) clz.newInstance();
- } catch (Exception ex) {
- // Android-changed: Try to load the class from the context class loader.
+ // Android-changed: Fall back to the context classloader before giving up.
+ // } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
+ // throw new RuntimeException("MemoryHandler can't load handler target \"" + targetName + "\"" , e);
+ } catch (Exception e) {
try {
clz = Thread.currentThread().getContextClassLoader()
.loadClass(targetName);
diff --git a/ojluni/src/main/java/java/util/logging/SimpleFormatter.java b/ojluni/src/main/java/java/util/logging/SimpleFormatter.java
index 6433365..12412f1 100644
--- a/ojluni/src/main/java/java/util/logging/SimpleFormatter.java
+++ b/ojluni/src/main/java/java/util/logging/SimpleFormatter.java
@@ -1,4 +1,4 @@
-/*g
+/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
diff --git a/ojluni/src/main/java/java/util/logging/SocketHandler.java b/ojluni/src/main/java/java/util/logging/SocketHandler.java
index e571d68..2561e90 100644
--- a/ojluni/src/main/java/java/util/logging/SocketHandler.java
+++ b/ojluni/src/main/java/java/util/logging/SocketHandler.java
@@ -165,6 +165,7 @@
throw new IllegalArgumentException("Null host name: " + host);
}
+ // Android-added: Enforce cleartext policy.
if (!NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted()) {
throw new IOException("Cleartext traffic not permitted");
}
diff --git a/ojluni/src/main/java/java/util/logging/XMLFormatter.java b/ojluni/src/main/java/java/util/logging/XMLFormatter.java
index f3bb335..ab95f58 100644
--- a/ojluni/src/main/java/java/util/logging/XMLFormatter.java
+++ b/ojluni/src/main/java/java/util/logging/XMLFormatter.java
@@ -152,6 +152,7 @@
escape(sb, message);
sb.append("</message>");
sb.append("\n");
+ // Android-added: Include empty <message/> tag. http://b/25861348#comment17
} else {
sb.append("<message/>");
sb.append("\n");
diff --git a/ojluni/src/main/java/java/util/prefs/AbstractPreferences.java b/ojluni/src/main/java/java/util/prefs/AbstractPreferences.java
index e2e25f7..71616ee 100644
--- a/ojluni/src/main/java/java/util/prefs/AbstractPreferences.java
+++ b/ojluni/src/main/java/java/util/prefs/AbstractPreferences.java
@@ -167,11 +167,18 @@
/**
* Registered preference change listeners.
*/
+ // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+ // It's not clear if this change provides overall benefit; it might be
+ // reverted in future. Discussion: http://b/111195881
+ // private PreferenceChangeListener[] prefListeners =
+ // new PreferenceChangeListener[0];
private final ArrayList<PreferenceChangeListener> prefListeners = new ArrayList<>();
/**
* Registered node change listeners.
*/
+ // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+ // private NodeChangeListener[] nodeListeners = new NodeChangeListener[0];
private final ArrayList<NodeChangeListener> nodeListeners = new ArrayList<>();
/**
@@ -1036,6 +1043,14 @@
if (removed)
throw new IllegalStateException("Node has been removed.");
+ // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+ /*
+ // Copy-on-write
+ PreferenceChangeListener[] old = prefListeners;
+ prefListeners = new PreferenceChangeListener[old.length + 1];
+ System.arraycopy(old, 0, prefListeners, 0, old.length);
+ prefListeners[old.length] = pcl;
+ */
prefListeners.add(pcl);
}
startEventDispatchThreadIfNecessary();
@@ -1045,11 +1060,27 @@
synchronized(lock) {
if (removed)
throw new IllegalStateException("Node has been removed.");
-
+ // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+ // if ((prefListeners == null) || (prefListeners.length == 0))
if (!prefListeners.contains(pcl)) {
throw new IllegalArgumentException("Listener not registered.");
}
+ // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+ /*
+ // Copy-on-write
+ PreferenceChangeListener[] newPl =
+ new PreferenceChangeListener[prefListeners.length - 1];
+ int i = 0;
+ while (i < newPl.length && prefListeners[i] != pcl)
+ newPl[i] = prefListeners[i++];
+
+ if (i == newPl.length && prefListeners[i] != pcl)
+ throw new IllegalArgumentException("Listener not registered.");
+ while (i < newPl.length)
+ newPl[i] = prefListeners[++i];
+ prefListeners = newPl;
+ */
prefListeners.remove(pcl);
}
}
@@ -1061,6 +1092,19 @@
if (removed)
throw new IllegalStateException("Node has been removed.");
+ // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+ /*
+ // Copy-on-write
+ if (nodeListeners == null) {
+ nodeListeners = new NodeChangeListener[1];
+ nodeListeners[0] = ncl;
+ } else {
+ NodeChangeListener[] old = nodeListeners;
+ nodeListeners = new NodeChangeListener[old.length + 1];
+ System.arraycopy(old, 0, nodeListeners, 0, old.length);
+ nodeListeners[old.length] = ncl;
+ }
+ */
nodeListeners.add(ncl);
}
startEventDispatchThreadIfNecessary();
@@ -1070,11 +1114,29 @@
synchronized(lock) {
if (removed)
throw new IllegalStateException("Node has been removed.");
-
+ // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+ // if ((nodeListeners == null) || (nodeListeners.length == 0))
if (!nodeListeners.contains(ncl)) {
throw new IllegalArgumentException("Listener not registered.");
}
+ // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+ /*
+ // Copy-on-write
+ int i = 0;
+ while (i < nodeListeners.length && nodeListeners[i] != ncl)
+ i++;
+ if (i == nodeListeners.length)
+ throw new IllegalArgumentException("Listener not registered.");
+ NodeChangeListener[] newNl =
+ new NodeChangeListener[nodeListeners.length - 1];
+ if (i != 0)
+ System.arraycopy(nodeListeners, 0, newNl, 0, i);
+ if (i != newNl.length)
+ System.arraycopy(nodeListeners, i + 1,
+ newNl, i, newNl.length - i);
+ nodeListeners = newNl;
+ */
nodeListeners.remove(ncl);
}
}
@@ -1493,19 +1555,34 @@
}
}
+ // BEGIN Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+ // Changed documentation.
+ /*
+ /**
+ * Return this node's preference/node change listeners. Even though
+ * we're using a copy-on-write lists, we use synchronized accessors to
+ * ensure information transmission from the writing thread to the
+ * reading thread.
+ *
+ */
/**
* Return this node's preference/node change listeners. All accesses to prefListeners
* and nodeListeners are guarded by |lock|. We return a copy of the list so that the
* EventQueue thread will iterate over a fixed snapshot of the listeners at the time of
* this call.
*/
+ // END Android-changed: Copy-on-read List of listeners, not copy-on-write array.
PreferenceChangeListener[] prefListeners() {
synchronized(lock) {
+ // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+ // return prefListeners;
return prefListeners.toArray(new PreferenceChangeListener[prefListeners.size()]);
}
}
NodeChangeListener[] nodeListeners() {
synchronized(lock) {
+ // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+ // return nodeListeners;
return nodeListeners.toArray(new NodeChangeListener[nodeListeners.size()]);
}
}
@@ -1516,6 +1593,8 @@
* listeners. Invoked with this.lock held.
*/
private void enqueuePreferenceChangeEvent(String key, String newValue) {
+ // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+ // if (prefListeners.length != 0) {
if (!prefListeners.isEmpty()) {
synchronized(eventQueue) {
eventQueue.add(new PreferenceChangeEvent(this, key, newValue));
@@ -1530,6 +1609,8 @@
* this.lock held.
*/
private void enqueueNodeAddedEvent(Preferences child) {
+ // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+ // if (nodeListeners.length != 0) {
if (!nodeListeners.isEmpty()) {
synchronized(eventQueue) {
eventQueue.add(new NodeAddedEvent(this, child));
@@ -1544,6 +1625,8 @@
* this.lock held.
*/
private void enqueueNodeRemovedEvent(Preferences child) {
+ // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+ // if (nodeListeners.length != 0) {
if (!nodeListeners.isEmpty()) {
synchronized(eventQueue) {
eventQueue.add(new NodeRemovedEvent(this, child));
diff --git a/ojluni/src/main/java/java/util/prefs/Preferences.java b/ojluni/src/main/java/java/util/prefs/Preferences.java
index aaf9950..2410c1d 100644
--- a/ojluni/src/main/java/java/util/prefs/Preferences.java
+++ b/ojluni/src/main/java/java/util/prefs/Preferences.java
@@ -224,11 +224,97 @@
*/
public abstract class Preferences {
- // Android-changed: Not final for testing.
- private static PreferencesFactory factory = findPreferencesFactory();
+ // Android-changed: Allow Preferences.factory to be set by tests.
+ // private static final PreferencesFactory factory = factory();
+ private static PreferencesFactory factory = factory();
- // Android-changed: Custom implementation of findPreferencesFactory.
- private static PreferencesFactory findPreferencesFactory() {
+ // BEGIN Android-changed: Logic for constructing the default Preferences factory.
+ /*
+ private static PreferencesFactory factory() {
+ // 1. Try user-specified system property
+ String factoryName = AccessController.doPrivileged(
+ new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty(
+ "java.util.prefs.PreferencesFactory");}});
+ if (factoryName != null) {
+ // FIXME: This code should be run in a doPrivileged and
+ // not use the context classloader, to avoid being
+ // dependent on the invoking thread.
+ // Checking AllPermission also seems wrong.
+ try {
+ return (PreferencesFactory)
+ Class.forName(factoryName, false,
+ ClassLoader.getSystemClassLoader())
+ .newInstance();
+ } catch (Exception ex) {
+ try {
+ // workaround for javaws, plugin,
+ // load factory class using non-system classloader
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new java.security.AllPermission());
+ }
+ return (PreferencesFactory)
+ Class.forName(factoryName, false,
+ Thread.currentThread()
+ .getContextClassLoader())
+ .newInstance();
+ } catch (Exception e) {
+ throw new InternalError(
+ "Can't instantiate Preferences factory "
+ + factoryName, e);
+ }
+ }
+ }
+
+ return AccessController.doPrivileged(
+ new PrivilegedAction<PreferencesFactory>() {
+ public PreferencesFactory run() {
+ return factory1();}});
+ }
+
+ private static PreferencesFactory factory1() {
+ // 2. Try service provider interface
+ Iterator<PreferencesFactory> itr = ServiceLoader
+ .load(PreferencesFactory.class, ClassLoader.getSystemClassLoader())
+ .iterator();
+
+ // choose first provider instance
+ while (itr.hasNext()) {
+ try {
+ return itr.next();
+ } catch (ServiceConfigurationError sce) {
+ if (sce.getCause() instanceof SecurityException) {
+ // Ignore the security exception, try the next provider
+ continue;
+ }
+ throw sce;
+ }
+ }
+
+ // 3. Use platform-specific system-wide default
+ String osName = System.getProperty("os.name");
+ String platformFactory;
+ if (osName.startsWith("Windows")) {
+ platformFactory = "java.util.prefs.WindowsPreferencesFactory";
+ } else if (osName.contains("OS X")) {
+ platformFactory = "java.util.prefs.MacOSXPreferencesFactory";
+ } else {
+ platformFactory = "java.util.prefs.FileSystemPreferencesFactory";
+ }
+ try {
+ return (PreferencesFactory)
+ Class.forName(platformFactory, false,
+ Preferences.class.getClassLoader()).newInstance();
+ } catch (Exception e) {
+ throw new InternalError(
+ "Can't instantiate platform default Preferences factory "
+ + platformFactory, e);
+ }
+ }
+ */
+ private static PreferencesFactory factory() {
// Try the system property first...
PreferencesFactory result = ServiceLoader.loadFromSystemProperty(PreferencesFactory.class);
if (result != null) {
@@ -241,16 +327,16 @@
// Finally return a default...
return new FileSystemPreferencesFactory();
}
+ // END Android-changed: Android-changed: Logic for constructing the default Preferences factory.
- /**
- * @hide for testing only.
- */
- // Android-changed: Allow this to be set for testing.
+ // BEGIN Android-added: Allow Preferences.factory to be set by tests.
+ /** @hide for testing only. */
public static PreferencesFactory setPreferencesFactory(PreferencesFactory pf) {
PreferencesFactory previous = factory;
factory = pf;
return previous;
}
+ // END Android-added: Allow Preferences.factory to be set by tests.
/**
* Maximum length of string allowed as a key (80 characters).
@@ -267,6 +353,7 @@
*/
public static final int MAX_NAME_LENGTH = 80;
+ // Android-added: Document Android's security restrictions on system/user preferences.
/**
* <strong>WARNING:</strong> On Android, the Preference nodes
* corresponding to the "system" and "user" preferences are stored in sections
@@ -316,6 +403,7 @@
return userRoot().node(nodeName(c));
}
+ // Android-added: Document Android's security restrictions on system/user preferences.
/**
* <strong>WARNING:</strong> On Android, the Preference nodes
* corresponding to the "system" and "user" preferences are stored in sections
@@ -391,6 +479,7 @@
*/
private static Permission prefsPerm = new RuntimePermission("preferences");
+ // Android-added: Document Android's security restrictions on system/user preferences.
/**
* <strong>WARNING:</strong> On Android, the Preference nodes
* corresponding to the "system" and "user" preferences are stored in sections
@@ -412,6 +501,7 @@
return factory.userRoot();
}
+ // Android-added: Document Android's security restrictions on system/user preferences.
/**
* <strong>WARNING:</strong> On Android, the Preference nodes
* corresponding to the "system" and "user" preferences are stored in sections
diff --git a/ojluni/src/main/java/java/util/prefs/XmlSupport.java b/ojluni/src/main/java/java/util/prefs/XmlSupport.java
index d15cb90..a90ff19 100644
--- a/ojluni/src/main/java/java/util/prefs/XmlSupport.java
+++ b/ojluni/src/main/java/java/util/prefs/XmlSupport.java
@@ -207,17 +207,21 @@
" versions " + EXTERNAL_XML_VERSION + " or older. You may need" +
" to install a newer version of JDK.");
+ // BEGIN Android-changed: Filter out non-Element nodes.
+ // Use a selector to skip over CDATA / DATA elements.
+ // The selector is specific to children with tag name "root";
+ // export() always creates exactly one such child.
+ // Element xmlRoot = (Element) doc.getDocumentElement().
+ // getChildNodes().item(0);
Element xmlRoot = (Element) doc.getDocumentElement();
- // Android-changed: Use a selector to skip over CDATA / DATA elements.
NodeList elements = xmlRoot.getElementsByTagName("root");
if (elements == null || elements.getLength() != 1) {
throw new InvalidPreferencesFormatException("invalid root node");
}
xmlRoot = (Element) elements.item(0);
- // End android changes.
-
+ // END Android-changed: Filter out non-Element nodes.
Preferences prefsRoot =
(xmlRoot.getAttribute("type").equals("user") ?
Preferences.userRoot() : Preferences.systemRoot());
@@ -281,38 +285,55 @@
Transformer t = tf.newTransformer();
t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());
t.setOutputProperty(OutputKeys.INDENT, "yes");
-
//Transformer resets the "indent" info if the "result" is a StreamResult with
//an OutputStream object embedded, creating a Writer object on top of that
//OutputStream object however works.
t.transform(new DOMSource(doc),
- new StreamResult(new BufferedWriter(new OutputStreamWriter(out, "UTF-8"))));
+ new StreamResult(new BufferedWriter(new OutputStreamWriter(out, "UTF-8"))));
} catch(TransformerException e) {
throw new AssertionError(e);
}
}
- private static List<Element> getChildElements(Element node) {
- NodeList xmlKids = node.getChildNodes();
- ArrayList<Element> elements = new ArrayList<>(xmlKids.getLength());
- for (int i = 0; i < xmlKids.getLength(); ++i) {
- if (xmlKids.item(i) instanceof Element) {
- elements.add((Element) xmlKids.item(i));
- }
+ // BEGIN Android-added: Filter out non-Element nodes.
+ static class NodeListAdapter implements NodeList {
+ private final List<? extends Node> delegate;
+
+ public NodeListAdapter(List<? extends Node> delegate) {
+ this.delegate = Objects.requireNonNull(delegate);
}
- return elements;
+ @Override public Node item(int index) {
+ if (index < 0 || index >= delegate.size()) {
+ return null;
+ }
+ return delegate.get(index);
+ }
+ @Override public int getLength() { return delegate.size(); }
}
+ private static NodeList elementNodesOf(NodeList xmlKids) {
+ List<Element> elements = new ArrayList<>(xmlKids.getLength());
+ for (int i = 0; i < xmlKids.getLength(); ++i) {
+ Node node = xmlKids.item(i);
+ if (node instanceof Element) {
+ elements.add((Element) node);
+ }
+ }
+ return new NodeListAdapter(elements);
+ }
+ // END Android-added: Filter out non-Element nodes.
+
/**
* Recursively traverse the specified preferences node and store
* the described preferences into the system or current user
* preferences tree, as appropriate.
*/
private static void ImportSubtree(Preferences prefsNode, Element xmlNode) {
- // Android-changed: filter out non-element nodes.
- List<Element> xmlKids = getChildElements(xmlNode);
-
+ NodeList xmlKids = xmlNode.getChildNodes();
+ // Android-added: Filter out non-Element nodes.
+ xmlKids = elementNodesOf(xmlKids);
+ int numXmlKids = xmlKids.getLength();
/*
* We first lock the node, import its contents and get
* child nodes. Then we unlock the node and go to children
@@ -327,20 +348,19 @@
return;
// Import any preferences at this node
- // Android
- Element firstXmlKid = xmlKids.get(0);
+ Element firstXmlKid = (Element) xmlKids.item(0);
ImportPrefs(prefsNode, firstXmlKid);
- prefsKids = new Preferences[xmlKids.size() - 1];
+ prefsKids = new Preferences[numXmlKids - 1];
// Get involved children
- for (int i=1; i < xmlKids.size(); i++) {
- Element xmlKid = xmlKids.get(i);
+ for (int i=1; i < numXmlKids; i++) {
+ Element xmlKid = (Element) xmlKids.item(i);
prefsKids[i-1] = prefsNode.node(xmlKid.getAttribute("name"));
}
} // unlocked the node
// import children
- for (int i=1; i < xmlKids.size(); i++)
- ImportSubtree(prefsKids[i-1], xmlKids.get(i));
+ for (int i=1; i < numXmlKids; i++)
+ ImportSubtree(prefsKids[i-1], (Element)xmlKids.item(i));
}
/**
@@ -349,11 +369,13 @@
* preferences node.
*/
private static void ImportPrefs(Preferences prefsNode, Element map) {
- // Android-changed: Use getChildElements.
- List<Element> entries = getChildElements(map);
- for (int i=0, numEntries = entries.size(); i < numEntries; i++) {
- Element entry = entries.get(i);
- prefsNode.put(entry.getAttribute("key"), entry.getAttribute("value"));
+ NodeList entries = map.getChildNodes();
+ // Android-added: Filter out non-Element nodes.
+ entries = elementNodesOf(entries);
+ for (int i=0, numEntries = entries.getLength(); i < numEntries; i++) {
+ Element entry = (Element) entries.item(i);
+ prefsNode.put(entry.getAttribute("key"),
+ entry.getAttribute("value"));
}
}
@@ -411,12 +433,14 @@
NodeList entries = xmlMap.getChildNodes();
for (int i=0, numEntries=entries.getLength(); i<numEntries; i++) {
- // Android-added, android xml serializer generates one-char Text nodes with a single
- // new-line character between expected Element nodes. openJdk code wasn't
- // expecting anything else than Element node.
+ // BEGIN Android-added: Filter out non-Element nodes.
+ // Android xml serializer generates one-char Text nodes with a single
+ // new-line character between expected Element nodes. OpenJDK code wasn't
+ // expecting anything else than Element nodes.
if (!(entries.item(i) instanceof Element)) {
continue;
}
+ // END Android-added: Filter out non-Element nodes.
Element entry = (Element) entries.item(i);
m.put(entry.getAttribute("key"), entry.getAttribute("value"));
}
diff --git a/ojluni/src/main/java/java/util/regex/Matcher.java b/ojluni/src/main/java/java/util/regex/Matcher.java
index a665011..e92cb9d 100644
--- a/ojluni/src/main/java/java/util/regex/Matcher.java
+++ b/ojluni/src/main/java/java/util/regex/Matcher.java
@@ -30,8 +30,8 @@
import libcore.util.NativeAllocationRegistry;
/**
- * An engine that performs match operations on a {@link java.lang.CharSequence
- * </code>character sequence<code>} by interpreting a {@link Pattern}.
+ * An engine that performs match operations on a {@linkplain java.lang.CharSequence
+ * character sequence} by interpreting a {@link Pattern}.
*
* <p> A matcher is created from a pattern by invoking the pattern's {@link
* Pattern#matcher matcher} method. Once created, a matcher can be used to
@@ -105,6 +105,7 @@
*/
public final class Matcher implements MatchResult {
+
/**
* The Pattern object that created this Matcher.
*/
@@ -112,7 +113,29 @@
// This ensures that "this" and pattern remain reachable while we're using pattern.address
// directly.
@ReachabilitySensitive
- private Pattern pattern;
+ private Pattern parentPattern;
+
+ /**
+ * Holds the offsets for the most recent match.
+ */
+ int[] groups;
+
+ /**
+ * The range within the sequence that is to be matched (between 0
+ * and text.length()).
+ */
+ int from, to;
+
+ /**
+ * Holds the input text.
+ */
+ String text;
+
+ /**
+ * Reflects whether a match has been found during the most recent find
+ * operation.
+ */
+ private boolean matchFound;
/**
* The address of the native peer.
@@ -130,54 +153,29 @@
Matcher.class.getClassLoader(), getNativeFinalizer(), nativeSize());
/**
- * Holds the original CharSequence for use in {@link #reset}. {@link #input} is used during
+ * The index of the last position appended in a substitution.
+ */
+ int appendPos = 0;
+
+ /**
+ * Holds the original CharSequence for use in {@link #reset}. {@link #text} is used during
* matching. Note that CharSequence is mutable while String is not, so reset can cause the input
* to match to change.
*/
private CharSequence originalInput;
/**
- * Holds the input text.
+ * If transparentBounds is true then the boundaries of this
+ * matcher's region are transparent to lookahead, lookbehind,
+ * and boundary matching constructs that try to see beyond them.
*/
- private String input;
+ boolean transparentBounds = false;
/**
- * Holds the start of the region, or 0 if the matching should start at the
- * beginning of the text.
+ * If anchoringBounds is true then the boundaries of this
+ * matcher's region match anchors such as ^ and $.
*/
- private int regionStart;
-
- /**
- * Holds the end of the region, or input.length() if the matching should
- * go until the end of the input.
- */
- private int regionEnd;
-
- /**
- * Holds the position where the next append operation will take place.
- */
- private int appendPos;
-
- /**
- * Reflects whether a match has been found during the most recent find
- * operation.
- */
- private boolean matchFound;
-
- /**
- * Holds the offsets for the most recent match.
- */
- private int[] matchOffsets;
-
- /**
- * Reflects whether the bounds of the region are anchoring.
- */
- private boolean anchoringBounds = true;
-
- /**
- * Reflects whether the bounds of the region are transparent.
- */
- private boolean transparentBounds;
+ boolean anchoringBounds = true;
/**
* All matchers have the state used by Pattern during a match.
@@ -193,7 +191,7 @@
* @return The pattern for which this matcher was created
*/
public Pattern pattern() {
- return pattern;
+ return parentPattern;
}
/**
@@ -206,7 +204,7 @@
*/
public MatchResult toMatchResult() {
ensureMatch();
- return new OffsetBasedMatchResult(input, matchOffsets);
+ return new OffsetBasedMatchResult(text, groups);
}
/**
@@ -226,11 +224,9 @@
* @since 1.5
*/
public Matcher usePattern(Pattern newPattern) {
- if (newPattern == null) {
- throw new IllegalArgumentException("newPattern == null");
- }
-
- this.pattern = newPattern;
+ if (newPattern == null)
+ throw new IllegalArgumentException("Pattern cannot be null");
+ parentPattern = newPattern;
synchronized (this) {
if (nativeFinalizer != null) {
@@ -238,21 +234,122 @@
address = 0; // In case openImpl throws.
nativeFinalizer = null;
}
- address = openImpl(pattern.address);
+ address = openImpl(parentPattern.address);
nativeFinalizer = registry.registerNativeAllocation(this, address);
}
- if (input != null) {
+ if (text != null) {
resetForInput();
}
- matchOffsets = new int[(groupCount() + 1) * 2];
+ groups = new int[(groupCount() + 1) * 2];
matchFound = false;
return this;
}
/**
- * Returns the offset after the last character matched. </p>
+ * Resets this matcher.
+ *
+ * <p> Resetting a matcher discards all of its explicit state information
+ * and sets its append position to zero. The matcher's region is set to the
+ * default region, which is its entire character sequence. The anchoring
+ * and transparency of this matcher's region boundaries are unaffected.
+ *
+ * @return This matcher
+ */
+ public Matcher reset() {
+ return reset(originalInput, 0, originalInput.length());
+ }
+
+ /**
+ * Resets this matcher with a new input sequence.
+ *
+ * <p> Resetting a matcher discards all of its explicit state information
+ * and sets its append position to zero. The matcher's region is set to
+ * the default region, which is its entire character sequence. The
+ * anchoring and transparency of this matcher's region boundaries are
+ * unaffected.
+ *
+ * @param input
+ * The new input character sequence
+ *
+ * @return This matcher
+ */
+ public Matcher reset(CharSequence input) {
+ return reset(input, 0, input.length());
+ }
+
+ /**
+ * Returns the start index of the previous match.
+ *
+ * @return The index of the first character matched
+ *
+ * @throws IllegalStateException
+ * If no match has yet been attempted,
+ * or if the previous match operation failed
+ */
+ public int start() {
+ return start(0);
+ }
+
+ /**
+ * Returns the start index of the subsequence captured by the given group
+ * during the previous match operation.
+ *
+ * <p> <a href="Pattern.html#cg">Capturing groups</a> are indexed from left
+ * to right, starting at one. Group zero denotes the entire pattern, so
+ * the expression <i>m.</i><tt>start(0)</tt> is equivalent to
+ * <i>m.</i><tt>start()</tt>. </p>
+ *
+ * @param group
+ * The index of a capturing group in this matcher's pattern
+ *
+ * @return The index of the first character captured by the group,
+ * or <tt>-1</tt> if the match was successful but the group
+ * itself did not match anything
+ *
+ * @throws IllegalStateException
+ * If no match has yet been attempted,
+ * or if the previous match operation failed
+ *
+ * @throws IndexOutOfBoundsException
+ * If there is no capturing group in the pattern
+ * with the given index
+ */
+ public int start(int group) {
+ ensureMatch();
+ if (group < 0 || group > groupCount())
+ throw new IndexOutOfBoundsException("No group " + group);
+ return groups[group * 2];
+ }
+
+ /**
+ * Returns the start index of the subsequence captured by the given
+ * <a href="Pattern.html#groupname">named-capturing group</a> during the
+ * previous match operation.
+ *
+ * @param name
+ * The name of a named-capturing group in this matcher's pattern
+ *
+ * @return The index of the first character captured by the group,
+ * or {@code -1} if the match was successful but the group
+ * itself did not match anything
+ *
+ * @throws IllegalStateException
+ * If no match has yet been attempted,
+ * or if the previous match operation failed
+ *
+ * @throws IllegalArgumentException
+ * If there is no capturing group in the pattern
+ * with the given name
+ * @since 1.8
+ */
+ public int start(String name) {
+ return groups[getMatchedGroupIndex(name) * 2];
+ }
+
+ /**
+ * Returns the offset after the last character matched.
*
* @return The offset after the last character matched
*
@@ -290,7 +387,9 @@
*/
public int end(int group) {
ensureMatch();
- return matchOffsets[(group * 2) + 1];
+ if (group < 0 || group > groupCount())
+ throw new IndexOutOfBoundsException("No group " + group);
+ return groups[group * 2 + 1];
}
/**
@@ -315,11 +414,9 @@
* @since 1.8
*/
public int end(String name) {
- ensureMatch();
- return matchOffsets[getMatchedGroupIndex(pattern.address, name) * 2 + 1];
+ return groups[getMatchedGroupIndex(name) * 2 + 1];
}
-
/**
* Returns the input subsequence matched by the previous match.
*
@@ -380,13 +477,11 @@
*/
public String group(int group) {
ensureMatch();
- int from = matchOffsets[group * 2];
- int to = matchOffsets[(group * 2) + 1];
- if (from == -1 || to == -1) {
+ if (group < 0 || group > groupCount())
+ throw new IndexOutOfBoundsException("No group " + group);
+ if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
return null;
- } else {
- return input.substring(from, to);
- }
+ return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}
/**
@@ -417,15 +512,10 @@
* @since 1.7
*/
public String group(String name) {
- ensureMatch();
- int group = getMatchedGroupIndex(pattern.address, name);
- int from = matchOffsets[group * 2];
- int to = matchOffsets[(group * 2) + 1];
- if (from == -1 || to == -1) {
+ int group = getMatchedGroupIndex(name);
+ if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
return null;
- } else {
- return input.substring(from, to);
- }
+ return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}
/**
@@ -457,7 +547,7 @@
*/
public boolean matches() {
synchronized (this) {
- matchFound = matchesImpl(address, matchOffsets);
+ matchFound = matchesImpl(address, groups);
}
return matchFound;
}
@@ -479,7 +569,7 @@
*/
public boolean find() {
synchronized (this) {
- matchFound = findNextImpl(address, matchOffsets);
+ matchFound = findNextImpl(address, groups);
}
return matchFound;
}
@@ -494,6 +584,7 @@
* invocations of the {@link #find()} method will start at the first
* character not matched by this match. </p>
*
+ * @param start the index to start searching for a match
* @throws IndexOutOfBoundsException
* If start is less than zero or if start is greater than the
* length of the input sequence.
@@ -503,13 +594,12 @@
* pattern
*/
public boolean find(int start) {
+ int limit = getTextLength();
+ if ((start < 0) || (start > limit))
+ throw new IndexOutOfBoundsException("Illegal start index");
reset();
- if (start < 0 || start > input.length()) {
- throw new IndexOutOfBoundsException("start=" + start + "; length=" + input.length());
- }
-
synchronized (this) {
- matchFound = findImpl(address, start, matchOffsets);
+ matchFound = findImpl(address, start, groups);
}
return matchFound;
}
@@ -530,7 +620,7 @@
*/
public boolean lookingAt() {
synchronized (this) {
- matchFound = lookingAtImpl(address, matchOffsets);
+ matchFound = lookingAtImpl(address, groups);
}
return matchFound;
}
@@ -588,8 +678,10 @@
*
* <p> The replacement string may contain references to subsequences
* captured during the previous match: Each occurrence of
- * <tt>$</tt><i>g</i> will be replaced by the result of evaluating the corresponding
- * {@link #group(int) group(g)</tt>} respectively. For <tt>$</tt><i>g</i><tt></tt>,
+ * <tt>${</tt><i>name</i><tt>}</tt> or <tt>$</tt><i>g</i>
+ * will be replaced by the result of evaluating the corresponding
+ * {@link #group(String) group(name)} or {@link #group(int) group(g)}
+ * respectively. For <tt>$</tt><i>g</i>,
* the first number after the <tt>$</tt> is always treated as part of
* the group reference. Subsequent numbers are incorporated into g if
* they would form a legal group reference. Only the numerals '0'
@@ -643,7 +735,8 @@
* that does not exist in the pattern
*/
public Matcher appendReplacement(StringBuffer sb, String replacement) {
- sb.append(input.substring(appendPos, start()));
+
+ sb.append(text.substring(appendPos, start()));
appendEvaluated(sb, replacement);
appendPos = end();
@@ -692,16 +785,19 @@
}
}
+ if (escape) {
+ throw new IllegalArgumentException("character to be escaped is missing");
+ }
+
+ if (dollar) {
+ throw new IllegalArgumentException("Illegal group reference: group index is missing");
+ }
+
if (escapeNamedGroup) {
throw new IllegalArgumentException("Missing ending brace '}' from replacement string");
}
-
- if (escape) {
- throw new ArrayIndexOutOfBoundsException(s.length());
- }
}
-
/**
* Implements a terminal append-and-replace step.
*
@@ -717,8 +813,8 @@
* @return The target string buffer
*/
public StringBuffer appendTail(StringBuffer sb) {
- if (appendPos < regionEnd) {
- sb.append(input.substring(appendPos, regionEnd));
+ if (appendPos < to) {
+ sb.append(text.substring(appendPos, to));
}
return sb;
}
@@ -759,11 +855,17 @@
*/
public String replaceAll(String replacement) {
reset();
- StringBuffer buffer = new StringBuffer(input.length());
- while (find()) {
- appendReplacement(buffer, replacement);
+ boolean result = find();
+ if (result) {
+ StringBuffer sb = new StringBuffer();
+ do {
+ appendReplacement(sb, replacement);
+ result = find();
+ } while (result);
+ appendTail(sb);
+ return sb.toString();
}
- return appendTail(buffer).toString();
+ return text.toString();
}
/**
@@ -800,12 +902,15 @@
* subsequences as needed
*/
public String replaceFirst(String replacement) {
+ if (replacement == null)
+ throw new NullPointerException("replacement");
reset();
- StringBuffer buffer = new StringBuffer(input.length());
- if (find()) {
- appendReplacement(buffer, replacement);
- }
- return appendTail(buffer).toString();
+ if (!find())
+ return text.toString();
+ StringBuffer sb = new StringBuffer();
+ appendReplacement(sb, replacement);
+ appendTail(sb);
+ return sb.toString();
}
/**
@@ -847,7 +952,7 @@
* @since 1.5
*/
public int regionStart() {
- return regionStart;
+ return from;
}
/**
@@ -860,7 +965,7 @@
* @since 1.5
*/
public int regionEnd() {
- return regionEnd;
+ return to;
}
/**
@@ -904,16 +1009,16 @@
*
* <p> By default, a matcher uses opaque bounds.
*
- * @param value a boolean indicating whether to use opaque or transparent
+ * @param b a boolean indicating whether to use opaque or transparent
* regions
* @return this matcher
* @see java.util.regex.Matcher#hasTransparentBounds
* @since 1.5
*/
- public Matcher useTransparentBounds(boolean value) {
+ public Matcher useTransparentBounds(boolean b) {
synchronized (this) {
- transparentBounds = value;
- useTransparentBoundsImpl(address, value);
+ transparentBounds = b;
+ useTransparentBoundsImpl(address, b);
}
return this;
}
@@ -954,15 +1059,15 @@
*
* <p> By default, a matcher uses anchoring region boundaries.
*
- * @param value a boolean indicating whether or not to use anchoring bounds.
+ * @param b a boolean indicating whether or not to use anchoring bounds.
* @return this matcher
* @see java.util.regex.Matcher#hasAnchoringBounds
* @since 1.5
*/
- public Matcher useAnchoringBounds(boolean value) {
+ public Matcher useAnchoringBounds(boolean b) {
synchronized (this) {
- anchoringBounds = value;
- useAnchoringBoundsImpl(address, value);
+ anchoringBounds = b;
+ useAnchoringBoundsImpl(address, b);
}
return this;
}
@@ -1006,7 +1111,6 @@
}
}
-
/**
* <p>Returns true if more input could change a positive match into a
* negative one.
@@ -1028,35 +1132,23 @@
}
/**
- * Resets this matcher.
+ * Returns the end index of the text.
*
- * <p> Resetting a matcher discards all of its explicit state information
- * and sets its append position to zero. The matcher's region is set to the
- * default region, which is its entire character sequence. The anchoring
- * and transparency of this matcher's region boundaries are unaffected.
- *
- * @return This matcher
+ * @return the index after the last character in the text
*/
- public Matcher reset() {
- return reset(originalInput, 0, originalInput.length());
+ int getTextLength() {
+ return text.length();
}
/**
- * Resets this matcher with a new input sequence.
+ * Generates a String from this Matcher's input in the specified range.
*
- * <p> Resetting a matcher discards all of its explicit state information
- * and sets its append position to zero. The matcher's region is set to
- * the default region, which is its entire character sequence. The
- * anchoring and transparency of this matcher's region boundaries are
- * unaffected.
- *
- * @param input
- * The new input character sequence
- *
- * @return This matcher
+ * @param beginIndex the beginning index, inclusive
+ * @param endIndex the ending index, exclusive
+ * @return A String generated from this Matcher's input
*/
- public Matcher reset(CharSequence input) {
- return reset(input, 0, input.length());
+ CharSequence getSubSequence(int beginIndex, int endIndex) {
+ return text.subSequence(beginIndex, endIndex);
}
/**
@@ -1085,9 +1177,9 @@
}
this.originalInput = input;
- this.input = input.toString();
- this.regionStart = start;
- this.regionEnd = end;
+ this.text = input.toString();
+ this.from = start;
+ this.to = end;
resetForInput();
matchFound = false;
@@ -1098,7 +1190,7 @@
private void resetForInput() {
synchronized (this) {
- setInputImpl(address, input, regionStart, regionEnd);
+ setInputImpl(address, text, from, to);
useAnchoringBoundsImpl(address, anchoringBounds);
useTransparentBoundsImpl(address, transparentBounds);
}
@@ -1117,77 +1209,9 @@
}
}
- /**
- * Returns the start index of the previous match. </p>
- *
- * @return The index of the first character matched
- *
- * @throws IllegalStateException
- * If no match has yet been attempted,
- * or if the previous match operation failed
- */
- public int start() {
- return start(0);
- }
-
- /**
- * Returns the start index of the subsequence captured by the given group
- * during the previous match operation.
- *
- * <p> <a href="Pattern.html#cg">Capturing groups</a> are indexed from left
- * to right, starting at one. Group zero denotes the entire pattern, so
- * the expression <i>m.</i><tt>start(0)</tt> is equivalent to
- * <i>m.</i><tt>start()</tt>. </p>
- *
- * @param group
- * The index of a capturing group in this matcher's pattern
- *
- * @return The index of the first character captured by the group,
- * or <tt>-1</tt> if the match was successful but the group
- * itself did not match anything
- *
- * @throws IllegalStateException
- * If no match has yet been attempted,
- * or if the previous match operation failed
- *
- * @throws IndexOutOfBoundsException
- * If there is no capturing group in the pattern
- * with the given index
- */
- public int start(int group) throws IllegalStateException {
+ private int getMatchedGroupIndex(String name) {
ensureMatch();
- return matchOffsets[group * 2];
- }
-
-
- /**
- * Returns the start index of the subsequence captured by the given
- * <a href="Pattern.html#groupname">named-capturing group</a> during the
- * previous match operation.
- *
- * @param name
- * The name of a named-capturing group in this matcher's pattern
- *
- * @return The index of the first character captured by the group,
- * or {@code -1} if the match was successful but the group
- * itself did not match anything
- *
- * @throws IllegalStateException
- * If no match has yet been attempted,
- * or if the previous match operation failed
- *
- * @throws IllegalArgumentException
- * If there is no capturing group in the pattern
- * with the given name
- * @since 1.8
- */
- public int start(String name) {
- ensureMatch();
- return matchOffsets[getMatchedGroupIndex(pattern.address, name) * 2];
- }
-
- private static int getMatchedGroupIndex(long patternAddr, String name) {
- int result = getMatchedGroupIndex0(patternAddr, name);
+ int result = getMatchedGroupIndex0(parentPattern.address, name);
if (result < 0) {
throw new IllegalArgumentException("No capturing group in the pattern " +
"with the name " + name);
diff --git a/ojluni/src/main/java/java/util/regex/Pattern.java b/ojluni/src/main/java/java/util/regex/Pattern.java
index 5938431..1464deb 100644
--- a/ojluni/src/main/java/java/util/regex/Pattern.java
+++ b/ojluni/src/main/java/java/util/regex/Pattern.java
@@ -27,6 +27,8 @@
package java.util.regex;
import dalvik.annotation.optimization.ReachabilitySensitive;
+import dalvik.system.VMRuntime;
+
import libcore.util.NativeAllocationRegistry;
import java.util.Iterator;
@@ -40,14 +42,16 @@
import libcore.util.EmptyArray;
-// Android-changed: Add min API level of 26 for the named capaturing in javadoc
+// Android-changed: Document that named capturing is only available from API 26.
+// Android-changed: Android always uses unicode character classes.
+// UNICODE_CHARACTER_CLASS has no effect on Android.
/**
* A compiled representation of a regular expression.
*
* <p> A regular expression, specified as a string, must first be compiled into
* an instance of this class. The resulting pattern can then be used to create
- * a {@link Matcher} object that can match arbitrary {@link
- * java.lang.CharSequence </code>character sequences<code>} against the regular
+ * a {@link Matcher} object that can match arbitrary {@linkplain
+ * java.lang.CharSequence character sequences} against the regular
* expression. All of the state involved in performing a match resides in the
* matcher, so many matchers can share the same pattern.
*
@@ -74,15 +78,14 @@
* such use.
*
*
- * <a name="sum">
- * <h4> Summary of regular-expression constructs </h4>
+ * <h3><a name="sum">Summary of regular-expression constructs</a></h3>
*
* <table border="0" cellpadding="1" cellspacing="0"
* summary="Regular expression constructs, and what they match">
*
* <tr align="left">
- * <th bgcolor="#CCCCFF" align="left" id="construct">Construct</th>
- * <th bgcolor="#CCCCFF" align="left" id="matches">Matches</th>
+ * <th align="left" id="construct">Construct</th>
+ * <th align="left" id="matches">Matches</th>
* </tr>
*
* <tr><th> </th></tr>
@@ -109,7 +112,7 @@
* <tr><td valign="top" headers="construct characters"><tt>\x</tt><i>{h...h}</i></td>
* <td headers="matches">The character with hexadecimal value <tt>0x</tt><i>h...h</i>
* ({@link java.lang.Character#MIN_CODE_POINT Character.MIN_CODE_POINT}
- * <= <tt>0x</tt><i>h...h</i> <= 
+ * <= <tt>0x</tt><i>h...h</i> <=
* {@link java.lang.Character#MAX_CODE_POINT Character.MAX_CODE_POINT})</td></tr>
* <tr><td valign="top" headers="matches"><tt>\t</tt></td>
* <td headers="matches">The tab character (<tt>'\u0009'</tt>)</td></tr>
@@ -129,24 +132,24 @@
* <tr><th> </th></tr>
* <tr align="left"><th colspan="2" id="classes">Character classes</th></tr>
*
- * <tr><td valign="top" headers="construct classes"><tt>[abc]</tt></td>
- * <td headers="matches"><tt>a</tt>, <tt>b</tt>, or <tt>c</tt> (simple class)</td></tr>
- * <tr><td valign="top" headers="construct classes"><tt>[^abc]</tt></td>
- * <td headers="matches">Any character except <tt>a</tt>, <tt>b</tt>, or <tt>c</tt> (negation)</td></tr>
- * <tr><td valign="top" headers="construct classes"><tt>[a-zA-Z]</tt></td>
- * <td headers="matches"><tt>a</tt> through <tt>z</tt>
- * or <tt>A</tt> through <tt>Z</tt>, inclusive (range)</td></tr>
- * <tr><td valign="top" headers="construct classes"><tt>[a-d[m-p]]</tt></td>
- * <td headers="matches"><tt>a</tt> through <tt>d</tt>,
- * or <tt>m</tt> through <tt>p</tt>: <tt>[a-dm-p]</tt> (union)</td></tr>
- * <tr><td valign="top" headers="construct classes"><tt>[a-z&&[def]]</tt></td>
- * <td headers="matches"><tt>d</tt>, <tt>e</tt>, or <tt>f</tt> (intersection)</tr>
- * <tr><td valign="top" headers="construct classes"><tt>[a-z&&[^bc]]</tt></td>
- * <td headers="matches"><tt>a</tt> through <tt>z</tt>,
- * except for <tt>b</tt> and <tt>c</tt>: <tt>[ad-z]</tt> (subtraction)</td></tr>
- * <tr><td valign="top" headers="construct classes"><tt>[a-z&&[^m-p]]</tt></td>
- * <td headers="matches"><tt>a</tt> through <tt>z</tt>,
- * and not <tt>m</tt> through <tt>p</tt>: <tt>[a-lq-z]</tt>(subtraction)</td></tr>
+ * <tr><td valign="top" headers="construct classes">{@code [abc]}</td>
+ * <td headers="matches">{@code a}, {@code b}, or {@code c} (simple class)</td></tr>
+ * <tr><td valign="top" headers="construct classes">{@code [^abc]}</td>
+ * <td headers="matches">Any character except {@code a}, {@code b}, or {@code c} (negation)</td></tr>
+ * <tr><td valign="top" headers="construct classes">{@code [a-zA-Z]}</td>
+ * <td headers="matches">{@code a} through {@code z}
+ * or {@code A} through {@code Z}, inclusive (range)</td></tr>
+ * <tr><td valign="top" headers="construct classes">{@code [a-d[m-p]]}</td>
+ * <td headers="matches">{@code a} through {@code d},
+ * or {@code m} through {@code p}: {@code [a-dm-p]} (union)</td></tr>
+ * <tr><td valign="top" headers="construct classes">{@code [a-z&&[def]]}</td>
+ * <td headers="matches">{@code d}, {@code e}, or {@code f} (intersection)</tr>
+ * <tr><td valign="top" headers="construct classes">{@code [a-z&&[^bc]]}</td>
+ * <td headers="matches">{@code a} through {@code z},
+ * except for {@code b} and {@code c}: {@code [ad-z]} (subtraction)</td></tr>
+ * <tr><td valign="top" headers="construct classes">{@code [a-z&&[^m-p]]}</td>
+ * <td headers="matches">{@code a} through {@code z},
+ * and not {@code m} through {@code p}: {@code [a-lq-z]}(subtraction)</td></tr>
* <tr><th> </th></tr>
*
* <tr align="left"><th colspan="2" id="predef">Predefined character classes</th></tr>
@@ -157,46 +160,55 @@
* <td headers="matches">A digit: <tt>[0-9]</tt></td></tr>
* <tr><td valign="top" headers="construct predef"><tt>\D</tt></td>
* <td headers="matches">A non-digit: <tt>[^0-9]</tt></td></tr>
+ * <tr><td valign="top" headers="construct predef"><tt>\h</tt></td>
+ * <td headers="matches">A horizontal whitespace character:
+ * <tt>[ \t\xA0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000]</tt></td></tr>
+ * <tr><td valign="top" headers="construct predef"><tt>\H</tt></td>
+ * <td headers="matches">A non-horizontal whitespace character: <tt>[^\h]</tt></td></tr>
* <tr><td valign="top" headers="construct predef"><tt>\s</tt></td>
* <td headers="matches">A whitespace character: <tt>[ \t\n\x0B\f\r]</tt></td></tr>
* <tr><td valign="top" headers="construct predef"><tt>\S</tt></td>
* <td headers="matches">A non-whitespace character: <tt>[^\s]</tt></td></tr>
+ * <tr><td valign="top" headers="construct predef"><tt>\v</tt></td>
+ * <td headers="matches">A vertical whitespace character: <tt>[\n\x0B\f\r\x85\u2028\u2029]</tt>
+ * </td></tr>
+ * <tr><td valign="top" headers="construct predef"><tt>\V</tt></td>
+ * <td headers="matches">A non-vertical whitespace character: <tt>[^\v]</tt></td></tr>
* <tr><td valign="top" headers="construct predef"><tt>\w</tt></td>
* <td headers="matches">A word character: <tt>[a-zA-Z_0-9]</tt></td></tr>
* <tr><td valign="top" headers="construct predef"><tt>\W</tt></td>
* <td headers="matches">A non-word character: <tt>[^\w]</tt></td></tr>
- *
* <tr><th> </th></tr>
- * <tr align="left"><th colspan="2" id="posix">POSIX character classes</b> (US-ASCII only)<b></th></tr>
+ * <tr align="left"><th colspan="2" id="posix"><b>POSIX character classes (US-ASCII only)</b></th></tr>
*
- * <tr><td valign="top" headers="construct posix"><tt>\p{Lower}</tt></td>
- * <td headers="matches">A lower-case alphabetic character: <tt>[a-z]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Upper}</tt></td>
- * <td headers="matches">An upper-case alphabetic character:<tt>[A-Z]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{ASCII}</tt></td>
- * <td headers="matches">All ASCII:<tt>[\x00-\x7F]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Alpha}</tt></td>
- * <td headers="matches">An alphabetic character:<tt>[\p{Lower}\p{Upper}]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Digit}</tt></td>
- * <td headers="matches">A decimal digit: <tt>[0-9]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Alnum}</tt></td>
- * <td headers="matches">An alphanumeric character:<tt>[\p{Alpha}\p{Digit}]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Punct}</tt></td>
- * <td headers="matches">Punctuation: One of <tt>!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~</tt></td></tr>
- * <!-- <tt>[\!"#\$%&'\(\)\*\+,\-\./:;\<=\>\?@\[\\\]\^_`\{\|\}~]</tt>
- * <tt>[\X21-\X2F\X31-\X40\X5B-\X60\X7B-\X7E]</tt> -->
- * <tr><td valign="top" headers="construct posix"><tt>\p{Graph}</tt></td>
- * <td headers="matches">A visible character: <tt>[\p{Alnum}\p{Punct}]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Print}</tt></td>
- * <td headers="matches">A printable character: <tt>[\p{Graph}\x20]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Blank}</tt></td>
- * <td headers="matches">A space or a tab: <tt>[ \t]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Cntrl}</tt></td>
- * <td headers="matches">A control character: <tt>[\x00-\x1F\x7F]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{XDigit}</tt></td>
- * <td headers="matches">A hexadecimal digit: <tt>[0-9a-fA-F]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Space}</tt></td>
- * <td headers="matches">A whitespace character: <tt>[ \t\n\x0B\f\r]</tt></td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Lower}}</td>
+ * <td headers="matches">A lower-case alphabetic character: {@code [a-z]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Upper}}</td>
+ * <td headers="matches">An upper-case alphabetic character:{@code [A-Z]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{ASCII}}</td>
+ * <td headers="matches">All ASCII:{@code [\x00-\x7F]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Alpha}}</td>
+ * <td headers="matches">An alphabetic character:{@code [\p{Lower}\p{Upper}]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Digit}}</td>
+ * <td headers="matches">A decimal digit: {@code [0-9]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Alnum}}</td>
+ * <td headers="matches">An alphanumeric character:{@code [\p{Alpha}\p{Digit}]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Punct}}</td>
+ * <td headers="matches">Punctuation: One of {@code !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~}</td></tr>
+ * <!-- {@code [\!"#\$%&'\(\)\*\+,\-\./:;\<=\>\?@\[\\\]\^_`\{\|\}~]}
+ * {@code [\X21-\X2F\X31-\X40\X5B-\X60\X7B-\X7E]} -->
+ * <tr><td valign="top" headers="construct posix">{@code \p{Graph}}</td>
+ * <td headers="matches">A visible character: {@code [\p{Alnum}\p{Punct}]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Print}}</td>
+ * <td headers="matches">A printable character: {@code [\p{Graph}\x20]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Blank}}</td>
+ * <td headers="matches">A space or a tab: {@code [ \t]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Cntrl}}</td>
+ * <td headers="matches">A control character: {@code [\x00-\x1F\x7F]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{XDigit}}</td>
+ * <td headers="matches">A hexadecimal digit: {@code [0-9a-fA-F]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Space}}</td>
+ * <td headers="matches">A whitespace character: {@code [ \t\n\x0B\f\r]}</td></tr>
*
* <tr><th> </th></tr>
* <tr align="left"><th colspan="2">java.lang.Character classes (simple <a href="#jcc">java character type</a>)</th></tr>
@@ -212,19 +224,19 @@
*
* <tr><th> </th></tr>
* <tr align="left"><th colspan="2" id="unicode">Classes for Unicode scripts, blocks, categories and binary properties</th></tr>
- * * <tr><td valign="top" headers="construct unicode"><tt>\p{IsLatin}</tt></td>
+ * <tr><td valign="top" headers="construct unicode">{@code \p{IsLatin}}</td>
* <td headers="matches">A Latin script character (<a href="#usc">script</a>)</td></tr>
- * <tr><td valign="top" headers="construct unicode"><tt>\p{InGreek}</tt></td>
+ * <tr><td valign="top" headers="construct unicode">{@code \p{InGreek}}</td>
* <td headers="matches">A character in the Greek block (<a href="#ubc">block</a>)</td></tr>
- * <tr><td valign="top" headers="construct unicode"><tt>\p{Lu}</tt></td>
+ * <tr><td valign="top" headers="construct unicode">{@code \p{Lu}}</td>
* <td headers="matches">An uppercase letter (<a href="#ucc">category</a>)</td></tr>
- * <tr><td valign="top" headers="construct unicode"><tt>\p{IsAlphabetic}</tt></td>
+ * <tr><td valign="top" headers="construct unicode">{@code \p{IsAlphabetic}}</td>
* <td headers="matches">An alphabetic character (<a href="#ubpc">binary property</a>)</td></tr>
- * <tr><td valign="top" headers="construct unicode"><tt>\p{Sc}</tt></td>
+ * <tr><td valign="top" headers="construct unicode">{@code \p{Sc}}</td>
* <td headers="matches">A currency symbol</td></tr>
- * <tr><td valign="top" headers="construct unicode"><tt>\P{InGreek}</tt></td>
+ * <tr><td valign="top" headers="construct unicode">{@code \P{InGreek}}</td>
* <td headers="matches">Any character except one in the Greek block (negation)</td></tr>
- * <tr><td valign="top" headers="construct unicode"><tt>[\p{L}&&[^\p{Lu}]] </tt></td>
+ * <tr><td valign="top" headers="construct unicode">{@code [\p{L}&&[^\p{Lu}]]}</td>
* <td headers="matches">Any letter except an uppercase letter (subtraction)</td></tr>
*
* <tr><th> </th></tr>
@@ -249,6 +261,13 @@
* <td headers="matches">The end of the input</td></tr>
*
* <tr><th> </th></tr>
+ * <tr align="left"><th colspan="2" id="lineending">Linebreak matcher</th></tr>
+ * <tr><td valign="top" headers="construct lineending"><tt>\R</tt></td>
+ * <td headers="matches">Any Unicode linebreak sequence, is equivalent to
+ * <tt>\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]
+ * </tt></td></tr>
+ *
+ * <tr><th> </th></tr>
* <tr align="left"><th colspan="2" id="greedy">Greedy quantifiers</th></tr>
*
* <tr><td valign="top" headers="construct greedy"><i>X</i><tt>?</tt></td>
@@ -361,8 +380,7 @@
* <hr>
*
*
- * <a name="bs">
- * <h4> Backslashes, escapes, and quoting </h4>
+ * <h3><a name="bs">Backslashes, escapes, and quoting</a></h3>
*
* <p> The backslash character (<tt>'\'</tt>) serves to introduce escaped
* constructs, as defined in the table above, as well as to quote characters
@@ -390,8 +408,7 @@
* <tt>(hello)</tt> the string literal <tt>"\\(hello\\)"</tt>
* must be used.
*
- * <a name="cc">
- * <h4> Character Classes </h4>
+ * <h3><a name="cc">Character Classes</a></h3>
*
* <p> Character classes may appear within other character classes, and
* may be composed by the union operator (implicit) and the intersection
@@ -420,7 +437,7 @@
* <td><tt>[a-e][i-u]</tt></td></tr>
* <tr><th>5 </th>
* <td>Intersection</td>
- * <td><tt>[a-z&&[aeiou]]</tt></td></tr>
+ * <td>{@code [a-z&&[aeiou]]}</td></tr>
* </table></blockquote>
*
* <p> Note that a different set of metacharacters are in effect inside
@@ -429,8 +446,7 @@
* character class, while the expression <tt>-</tt> becomes a range
* forming metacharacter.
*
- * <a name="lt">
- * <h4> Line terminators </h4>
+ * <h3><a name="lt">Line terminators</a></h3>
*
* <p> A <i>line terminator</i> is a one- or two-character sequence that marks
* the end of a line of the input character sequence. The following are
@@ -465,11 +481,9 @@
* except at the end of input. When in {@link #MULTILINE} mode <tt>$</tt>
* matches just before a line terminator or the end of the input sequence.
*
- * <a name="cg">
- * <h4> Groups and capturing </h4>
+ * <h3><a name="cg">Groups and capturing</a></h3>
*
- * <a name="gnumber">
- * <h5> Group number </h5>
+ * <h4><a name="gnumber">Group number</a></h4>
* <p> Capturing groups are numbered by counting their opening parentheses from
* left to right. In the expression <tt>((A)(B(C)))</tt>, for example, there
* are four such groups: </p>
@@ -492,8 +506,7 @@
* subsequence may be used later in the expression, via a back reference, and
* may also be retrieved from the matcher once the match operation is complete.
*
- * <a name="groupname">
- * <h5> Group name </h5>
+ * <h4><a name="groupname">Group name</a></h4>
* <p>The constructs and APIs are available since API level 26. A capturing group
* can also be assigned a "name", a <tt>named-capturing group</tt>,
* and then be back-referenced later by the "name". Group names are composed of
@@ -523,7 +536,7 @@
* that do not capture text and do not count towards the group total, or
* <i>named-capturing</i> group.
*
- * <h4> Unicode support </h4>
+ * <h3> Unicode support </h3>
*
* <p> This class is in conformance with Level 1 of <a
* href="http://www.unicode.org/reports/tr18/"><i>Unicode Technical
@@ -554,18 +567,18 @@
* <p>
* Scripts, blocks, categories and binary properties can be used both inside
* and outside of a character class.
- * <a name="usc">
+ *
* <p>
- * <b>Scripts</b> are specified either with the prefix {@code Is}, as in
+ * <b><a name="usc">Scripts</a></b> are specified either with the prefix {@code Is}, as in
* {@code IsHiragana}, or by using the {@code script} keyword (or its short
* form {@code sc})as in {@code script=Hiragana} or {@code sc=Hiragana}.
* <p>
* The script names supported by <code>Pattern</code> are the valid script names
* accepted and defined by
* {@link java.lang.Character.UnicodeScript#forName(String) UnicodeScript.forName}.
- * <a name="ubc">
+ *
* <p>
- * <b>Blocks</b> are specified with the prefix {@code In}, as in
+ * <b><a name="ubc">Blocks</a></b> are specified with the prefix {@code In}, as in
* {@code InMongolian}, or by using the keyword {@code block} (or its short
* form {@code blk}) as in {@code block=Mongolian} or {@code blk=Mongolian}.
* <p>
@@ -573,8 +586,8 @@
* accepted and defined by
* {@link java.lang.Character.UnicodeBlock#forName(String) UnicodeBlock.forName}.
* <p>
- * <a name="ucc">
- * <b>Categories</b> may be specified with the optional prefix {@code Is}:
+ *
+ * <b><a name="ucc">Categories</a></b> may be specified with the optional prefix {@code Is}:
* Both {@code \p{L}} and {@code \p{IsL}} denote the category of Unicode
* letters. Same as scripts and blocks, categories can also be specified
* by using the keyword {@code general_category} (or its short form
@@ -586,8 +599,8 @@
* {@link java.lang.Character Character} class. The category names are those
* defined in the Standard, both normative and informative.
* <p>
- * <a name="ubpc">
- * <b>Binary properties</b> are specified with the prefix {@code Is}, as in
+ *
+ * <b><a name="ubpc">Binary properties</a></b> are specified with the prefix {@code Is}, as in
* {@code IsAlphabetic}. The supported binary properties by <code>Pattern</code>
* are
* <ul>
@@ -602,22 +615,21 @@
* <li> White_Space
* <li> Digit
* <li> Hex_Digit
+ * <li> Join_Control
* <li> Noncharacter_Code_Point
* <li> Assigned
* </ul>
-
-
* <p>
- * <b>Predefined Character classes</b> and <b>POSIX character classes</b> are in
- * conformance with the recommendation of <i>Annex C: Compatibility Properties</i>
+ * The following <b>Predefined Character classes</b> and <b>POSIX character classes</b>
+ * are in conformance with the recommendation of <i>Annex C: Compatibility Properties</i>
* of <a href="http://www.unicode.org/reports/tr18/"><i>Unicode Regular Expression
* </i></a>.
- * <p>
+ *
* <table border="0" cellpadding="1" cellspacing="0"
* summary="predefined and posix character classes in Unicode mode">
* <tr align="left">
- * <th bgcolor="#CCCCFF" align="left" id="classes">Classes</th>
- * <th bgcolor="#CCCCFF" align="left" id="matches">Matches</th>
+ * <th align="left" id="predef_classes">Classes</th>
+ * <th align="left" id="predef_matches">Matches</th>
*</tr>
* <tr><td><tt>\p{Lower}</tt></td>
* <td>A lowercase character:<tt>\p{IsLowercase}</tt></td></tr>
@@ -636,9 +648,9 @@
* <tr><td><tt>\p{Graph}</tt></td>
* <td>A visible character: <tt>[^\p{IsWhite_Space}\p{gc=Cc}\p{gc=Cs}\p{gc=Cn}]</tt></td></tr>
* <tr><td><tt>\p{Print}</tt></td>
- * <td>A printable character: <tt>[\p{Graph}\p{Blank}&&[^\p{Cntrl}]]</tt></td></tr>
+ * <td>A printable character: {@code [\p{Graph}\p{Blank}&&[^\p{Cntrl}]]}</td></tr>
* <tr><td><tt>\p{Blank}</tt></td>
- * <td>A space or a tab: <tt>[\p{IsWhite_Space}&&[^\p{gc=Zl}\p{gc=Zp}\x0a\x0b\x0c\x0d\x85]]</tt></td></tr>
+ * <td>A space or a tab: {@code [\p{IsWhite_Space}&&[^\p{gc=Zl}\p{gc=Zp}\x0a\x0b\x0c\x0d\x85]]}</td></tr>
* <tr><td><tt>\p{Cntrl}</tt></td>
* <td>A control character: <tt>\p{gc=Cc}</tt></td></tr>
* <tr><td><tt>\p{XDigit}</tt></td>
@@ -654,7 +666,7 @@
* <tr><td><tt>\S</tt></td>
* <td>A non-whitespace character: <tt>[^\s]</tt></td></tr>
* <tr><td><tt>\w</tt></td>
- * <td>A word character: <tt>[\p{Alpha}\p{gc=Mn}\p{gc=Me}\p{gc=Mc}\p{Digit}\p{gc=Pc}]</tt></td></tr>
+ * <td>A word character: <tt>[\p{Alpha}\p{gc=Mn}\p{gc=Me}\p{gc=Mc}\p{Digit}\p{gc=Pc}\p{IsJoin_Control}]</tt></td></tr>
* <tr><td><tt>\W</tt></td>
* <td>A non-word character: <tt>[^\w]</tt></td></tr>
* </table>
@@ -663,9 +675,9 @@
* Categories that behave like the java.lang.Character
* boolean is<i>methodname</i> methods (except for the deprecated ones) are
* available through the same <tt>\p{</tt><i>prop</i><tt>}</tt> syntax where
- * the specified property has the name <tt>java<i>methodname</i></tt>.
+ * the specified property has the name <tt>java<i>methodname</i></tt></a>.
*
- * <h4> Comparison to Perl 5 </h4>
+ * <h3> Comparison to Perl 5 </h3>
*
* <p>The <code>Pattern</code> engine performs traditional NFA-based matching
* with ordered alternation as occurs in Perl 5.
@@ -674,12 +686,6 @@
*
* <ul>
* <li><p> Predefined character classes (Unicode character)
- * <p><tt>\h </tt>A horizontal whitespace
- * <p><tt>\H </tt>A non horizontal whitespace
- * <p><tt>\v </tt>A vertical whitespace
- * <p><tt>\V </tt>A non vertical whitespace
- * <p><tt>\R </tt>Any Unicode linebreak sequence
- * <tt>\u005cu000D\u005cu000A|[\u005cu000A\u005cu000B\u005cu000C\u005cu000D\u005cu0085\u005cu2028\u005cu2029]</tt>
* <p><tt>\X </tt>Match Unicode
* <a href="http://www.unicode.org/reports/tr18/#Default_Grapheme_Clusters">
* <i>extended grapheme cluster</i></a>
@@ -766,7 +772,8 @@
* @spec JSR-51
*/
-public final class Pattern implements java.io.Serializable
+public final class Pattern
+ implements java.io.Serializable
{
/**
@@ -894,9 +901,10 @@
*/
public static final int CANON_EQ = 0x80;
+ // Android-changed: Android always uses unicode character classes.
/**
* Enables the Unicode version of <i>Predefined character classes</i> and
- * <i>POSIX character classes</i> as eefined by <a href="http://www.unicode.org/reports/tr18/"><i>Unicode Technical
+ * <i>POSIX character classes</i> as defined by <a href="http://www.unicode.org/reports/tr18/"><i>Unicode Technical
* Standard #18: Unicode Regular Expression</i></a>
* <i>Annex C: Compatibility Properties</i>.
* <p>
@@ -921,6 +929,8 @@
*
* @serial
*/
+ // Android-changed: reimplement matching logic natively via ICU.
+ // private String pattern;
private final String pattern;
/**
@@ -928,21 +938,26 @@
*
* @serial
*/
+ // Android-changed: reimplement matching logic natively via ICU.
+ // private int flags;
private final int flags;
+ // BEGIN Android-changed: reimplement matching logic natively via ICU.
+ // We only need some tie-ins to native memory, instead of a large number
+ // of fields on the .java side.
@ReachabilitySensitive
transient long address;
private static final NativeAllocationRegistry registry = new NativeAllocationRegistry(
Pattern.class.getClassLoader(), getNativeFinalizer(), nativeSize());
-
+ // END Android-changed: reimplement matching logic natively via ICU.
/**
- * Compiles the given regular expression into a pattern. </p>
+ * Compiles the given regular expression into a pattern.
*
* @param regex
* The expression to be compiled
- *
+ * @return the given regular expression compiled into a pattern
* @throws PatternSyntaxException
* If the expression's syntax is invalid
*/
@@ -952,7 +967,7 @@
/**
* Compiles the given regular expression into a pattern with the given
- * flags. </p>
+ * flags.
*
* @param regex
* The expression to be compiled
@@ -964,6 +979,7 @@
* {@link #LITERAL}, {@link #UNICODE_CHARACTER_CLASS}
* and {@link #COMMENTS}
*
+ * @return the given regular expression compiled into a pattern with the given flags
* @throws IllegalArgumentException
* If bit values other than those corresponding to the defined
* match flags are set in <tt>flags</tt>
@@ -971,13 +987,12 @@
* @throws PatternSyntaxException
* If the expression's syntax is invalid
*/
- public static Pattern compile(String regex, int flags) throws PatternSyntaxException {
+ public static Pattern compile(String regex, int flags) {
return new Pattern(regex, flags);
}
/**
* Returns the regular expression from which this pattern was compiled.
- * </p>
*
* @return The source of this pattern
*/
@@ -999,7 +1014,6 @@
/**
* Creates a matcher that will match the given input against this pattern.
- * </p>
*
* @param input
* The character sequence to be matched
@@ -1007,12 +1021,21 @@
* @return A new matcher for this pattern
*/
public Matcher matcher(CharSequence input) {
+ // Android-removed: Pattern is eagerly compiled() upon construction.
+ /*
+ if (!compiled) {
+ synchronized(this) {
+ if (!compiled)
+ compile();
+ }
+ }
+ */
Matcher m = new Matcher(this, input);
return m;
}
/**
- * Returns this pattern's match flags. </p>
+ * Returns this pattern's match flags.
*
* @return The match flags specified when this pattern was compiled
*/
@@ -1042,7 +1065,7 @@
*
* @param input
* The character sequence to be matched
- *
+ * @return whether or not the regular expression matches on the input
* @throws PatternSyntaxException
* If the expression's syntax is invalid
*/
@@ -1052,6 +1075,8 @@
return m.matches();
}
+ // Android-changed: Adopt split() behavior change only for apps targeting API > 28.
+ // http://b/109659282#comment7
/**
* Splits the given input sequence around matches of this pattern.
*
@@ -1059,10 +1084,16 @@
* input sequence that is terminated by another subsequence that matches
* this pattern or is terminated by the end of the input sequence. The
* substrings in the array are in the order in which they occur in the
- * input. If this pattern does not match any subsequence of the input then
+ * input. If this pattern does not match any subsequence of the input then
* the resulting array has just one element, namely the input sequence in
* string form.
*
+ * <p> When there is a positive-width match at the beginning of the input
+ * sequence then an empty leading substring is included at the beginning
+ * of the resulting array. A zero-width match at the beginning however
+ * can only produce such an empty leading substring for apps running on or
+ * targeting API versions <= 28.
+ *
* <p> The <tt>limit</tt> parameter controls the number of times the
* pattern is applied and therefore affects the length of the resulting
* array. If the limit <i>n</i> is greater than zero then the pattern
@@ -1079,9 +1110,9 @@
*
* <blockquote><table cellpadding=1 cellspacing=0
* summary="Split examples showing regex, limit, and result">
- * <tr><th><P align="left"><i>Regex </i></th>
- * <th><P align="left"><i>Limit </i></th>
- * <th><P align="left"><i>Result </i></th></tr>
+ * <tr><th align="left"><i>Regex </i></th>
+ * <th align="left"><i>Limit </i></th>
+ * <th align="left"><i>Result </i></th></tr>
* <tr><td align=center>:</td>
* <td align=center>2</td>
* <td><tt>{ "boo", "and:foo" }</tt></td></tr>
@@ -1102,7 +1133,6 @@
* <td><tt>{ "b", "", ":and:f" }</tt></td></tr>
* </table></blockquote>
*
- *
* @param input
* The character sequence to be split
*
@@ -1113,11 +1143,12 @@
* around matches of this pattern
*/
public String[] split(CharSequence input, int limit) {
+ // BEGIN Android-added: fastSplit() to speed up simple cases.
String[] fast = fastSplit(pattern, input.toString(), limit);
if (fast != null) {
return fast;
}
-
+ // END Android-added: fastSplit() to speed up simple cases.
int index = 0;
boolean matchLimited = limit > 0;
ArrayList<String> matchList = new ArrayList<>();
@@ -1126,6 +1157,17 @@
// Add segments before each match found
while(m.find()) {
if (!matchLimited || matchList.size() < limit - 1) {
+ if (index == 0 && index == m.start() && m.start() == m.end()) {
+ // no empty leading substring included for zero-width match
+ // at the beginning of the input char sequence.
+ // BEGIN Android-changed: split() compat behavior for apps targeting <= 28.
+ // continue;
+ int targetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
+ if (targetSdkVersion > 28) {
+ continue;
+ }
+ // END Android-changed: split() compat behavior for apps targeting <= 28.
+ }
String match = input.subSequence(index, m.start()).toString();
matchList.add(match);
index = m.end();
@@ -1154,6 +1196,7 @@
return matchList.subList(0, resultSize).toArray(result);
}
+ // BEGIN Android-added: fastSplit() to speed up simple cases.
private static final String FASTSPLIT_METACHARACTERS = "\\?*+[](){}^$.|";
/**
@@ -1232,6 +1275,7 @@
result[separatorCount] = input.substring(begin, lastPartEnd);
return result;
}
+ // END Android-added: fastSplit() to speed up simple cases.
/**
* Splits the given input sequence around matches of this pattern.
@@ -1246,8 +1290,8 @@
*
* <blockquote><table cellpadding=1 cellspacing=0
* summary="Split examples showing regex and result">
- * <tr><th><P align="left"><i>Regex </i></th>
- * <th><P align="left"><i>Result</i></th></tr>
+ * <tr><th align="left"><i>Regex </i></th>
+ * <th align="left"><i>Result</i></th></tr>
* <tr><td align=center>:</td>
* <td><tt>{ "boo", "and", "foo" }</tt></td></tr>
* <tr><td align=center>o</td>
@@ -1307,15 +1351,47 @@
// Read in all fields
s.defaultReadObject();
+
+ // Android-removed: reimplement matching logic natively via ICU.
+ // // Initialize counts
+ // capturingGroupCount = 1;
+ // localCount = 0;
+
+ // Android-changed: Pattern is eagerly compiled() upon construction.
+ /*
+ // if length > 0, the Pattern is lazily compiled
+ compiled = false;
+ if (pattern.length() == 0) {
+ root = new Start(lastAccept);
+ matchRoot = lastAccept;
+ compiled = true;
+ }
+ */
compile();
}
+ // Android-changed: reimplement matching logic natively via ICU.
+ // Dropped documentation reference to Start and LastNode implementation
+ // details which do not apply on Android.
/**
* This private constructor is used to create all Patterns. The pattern
* string and match flags are all that is needed to completely describe
* a Pattern.
*/
private Pattern(String p, int f) {
+ pattern = p;
+ flags = f;
+
+ // BEGIN Android-changed: Only specific flags are supported.
+ /*
+ // to use UNICODE_CASE if UNICODE_CHARACTER_CLASS present
+ if ((flags & UNICODE_CHARACTER_CLASS) != 0)
+ flags |= UNICODE_CASE;
+
+ // Reset group index count
+ capturingGroupCount = 1;
+ localCount = 0;
+ */
if ((f & CANON_EQ) != 0) {
throw new UnsupportedOperationException("CANON_EQ flag not supported");
}
@@ -1323,11 +1399,23 @@
if ((f & ~supportedFlags) != 0) {
throw new IllegalArgumentException("Unsupported flags: " + (f & ~supportedFlags));
}
- this.pattern = p;
- this.flags = f;
- compile();
+ // END Android-changed: Only specific flags are supported supported.
+
+ // BEGIN Android-removed: Pattern is eagerly compiled() upon construction.
+ // if (pattern.length() > 0) {
+ // END Android-removed: Pattern is eagerly compiled() upon construction.
+ compile();
+ // Android-removed: reimplement matching logic natively via ICU.
+ /*
+ } else {
+ root = new Start(lastAccept);
+ matchRoot = lastAccept;
+ }
+ */
}
+ // BEGIN Android-changed: reimplement matching logic natively via ICU.
+ // Use native implementation instead of > 3000 lines of helper methods.
private void compile() throws PatternSyntaxException {
if (pattern == null) {
throw new NullPointerException("pattern == null");
@@ -1348,6 +1436,7 @@
private static native long compileImpl(String regex, int flags);
private static native long getNativeFinalizer();
private static native int nativeSize();
+ // END Android-changed: reimplement matching logic natively via ICU.
/**
* Creates a predicate which can be used to match a string.
diff --git a/ojluni/src/main/java/java/util/stream/AbstractPipeline.java b/ojluni/src/main/java/java/util/stream/AbstractPipeline.java
index 9bdea9c..627bb32 100644
--- a/ojluni/src/main/java/java/util/stream/AbstractPipeline.java
+++ b/ojluni/src/main/java/java/util/stream/AbstractPipeline.java
@@ -68,8 +68,9 @@
* @param <E_OUT> type of output elements
* @param <S> type of the subclass implementing {@code BaseStream}
* @since 1.8
- * @hide Visibility for CTS only (OpenJDK 8 streams tests).
+ * @hide Made public for CTS tests only (OpenJDK 8 streams tests).
*/
+// Android-changed: Made public for CTS tests only.
public abstract class AbstractPipeline<E_IN, E_OUT, S extends BaseStream<E_OUT, S>>
extends PipelineHelper<E_OUT> implements BaseStream<E_OUT, S> {
private static final String MSG_STREAM_LINKED = "stream has already been operated upon or closed";
@@ -242,6 +243,7 @@
* @return a flat array-backed Node that holds the collected output elements
*/
@SuppressWarnings("unchecked")
+ // Android-changed: Made public for CTS tests only.
public final Node<E_OUT> evaluateToArrayNode(IntFunction<E_OUT[]> generator) {
if (linkedOrConsumed)
throw new IllegalStateException(MSG_STREAM_LINKED);
@@ -380,6 +382,7 @@
* intermediate operations
* @see StreamOpFlag
*/
+ // Android-changed: Made public for CTS tests only.
public final int getStreamFlags() {
return StreamOpFlag.toStreamFlags(combinedFlags);
}
@@ -501,6 +504,7 @@
}
@Override
+ // Android-changed: Made public for CTS tests only.
public final int getStreamAndOpFlags() {
return combinedFlags;
}
@@ -511,6 +515,7 @@
@Override
@SuppressWarnings("unchecked")
+ // Android-changed: Made public for CTS tests only.
public final <P_IN> Sink<P_IN> wrapSink(Sink<E_OUT> sink) {
Objects.requireNonNull(sink);
@@ -533,6 +538,7 @@
@Override
@SuppressWarnings("unchecked")
+ // Android-changed: Made public for CTS tests only.
public final <P_IN> Node<E_OUT> evaluate(Spliterator<P_IN> spliterator,
boolean flatten,
IntFunction<E_OUT[]> generator) {
@@ -558,6 +564,7 @@
*
* @return the output shape
*/
+ // Android-changed: Made public for CTS tests only.
public abstract StreamShape getOutputShape();
/**
@@ -570,6 +577,7 @@
* @param generator the array generator
* @return a Node holding the output of the pipeline
*/
+ // Android-changed: Made public for CTS tests only.
public abstract <P_IN> Node<E_OUT> evaluateToNode(PipelineHelper<E_OUT> helper,
Spliterator<P_IN> spliterator,
boolean flattenTree,
@@ -584,6 +592,7 @@
* @param supplier the supplier of a spliterator
* @return a wrapping spliterator compatible with this shape
*/
+ // Android-changed: Made public for CTS tests only.
public abstract <P_IN> Spliterator<E_OUT> wrap(PipelineHelper<E_OUT> ph,
Supplier<Spliterator<P_IN>> supplier,
boolean isParallel);
@@ -593,6 +602,7 @@
* spliterator when a method is invoked on the lazy spliterator.
* @param supplier the supplier of a spliterator
*/
+ // Android-changed: Made public for CTS tests only.
public abstract Spliterator<E_OUT> lazySpliterator(Supplier<? extends Spliterator<E_OUT>> supplier);
/**
@@ -603,6 +613,7 @@
* @param spliterator the spliterator to pull elements from
* @param sink the sink to push elements to
*/
+ // Android-changed: Made public for CTS tests only.
public abstract void forEachWithCancel(Spliterator<E_OUT> spliterator, Sink<E_OUT> sink);
/**
@@ -621,6 +632,7 @@
* @return a node builder
*/
@Override
+ // Android-changed: Made public for CTS tests only.
public abstract Node.Builder<E_OUT> makeNodeBuilder(long exactSizeIfKnown,
IntFunction<E_OUT[]> generator);
@@ -635,6 +647,7 @@
*
* @return {@code true} if this operation is stateful
*/
+ // Android-changed: Made public for CTS tests only.
public abstract boolean opIsStateful();
/**
@@ -656,6 +669,7 @@
* each element, and passes the results (if any) to the provided
* {@code Sink}.
*/
+ // Android-changed: Made public for CTS tests only.
public abstract Sink<E_IN> opWrapSink(int flags, Sink<E_OUT> sink);
/**
@@ -673,6 +687,7 @@
* @param generator the array generator
* @return a {@code Node} describing the result of the evaluation
*/
+ // Android-changed: Made public for CTS tests only.
public <P_IN> Node<E_OUT> opEvaluateParallel(PipelineHelper<E_OUT> helper,
Spliterator<P_IN> spliterator,
IntFunction<E_OUT[]> generator) {
@@ -700,6 +715,7 @@
* @return a {@code Spliterator} describing the result of the evaluation
*/
@SuppressWarnings("unchecked")
+ // Android-changed: Made public for CTS tests only.
public <P_IN> Spliterator<E_OUT> opEvaluateParallelLazy(PipelineHelper<E_OUT> helper,
Spliterator<P_IN> spliterator) {
return opEvaluateParallel(helper, spliterator, i -> (E_OUT[]) new Object[i]).spliterator();
diff --git a/ojluni/src/main/java/java/util/stream/BaseStream.java b/ojluni/src/main/java/java/util/stream/BaseStream.java
index b0be000..35d46e0 100644
--- a/ojluni/src/main/java/java/util/stream/BaseStream.java
+++ b/ojluni/src/main/java/java/util/stream/BaseStream.java
@@ -25,6 +25,8 @@
package java.util.stream;
import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Collection;
import java.util.Iterator;
import java.util.Spliterator;
diff --git a/ojluni/src/main/java/java/util/stream/DistinctOps.java b/ojluni/src/main/java/java/util/stream/DistinctOps.java
index 0b7713e..22fbe05 100644
--- a/ojluni/src/main/java/java/util/stream/DistinctOps.java
+++ b/ojluni/src/main/java/java/util/stream/DistinctOps.java
@@ -65,6 +65,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public <P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,
Spliterator<P_IN> spliterator,
IntFunction<T[]> generator) {
@@ -100,6 +101,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public <P_IN> Spliterator<T> opEvaluateParallelLazy(PipelineHelper<T> helper, Spliterator<P_IN> spliterator) {
if (StreamOpFlag.DISTINCT.isKnown(helper.getStreamAndOpFlags())) {
// No-op
@@ -116,6 +118,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<T> opWrapSink(int flags, Sink<T> sink) {
Objects.requireNonNull(sink);
diff --git a/ojluni/src/main/java/java/util/stream/DoublePipeline.java b/ojluni/src/main/java/java/util/stream/DoublePipeline.java
index 25c19c6..e61e5de 100644
--- a/ojluni/src/main/java/java/util/stream/DoublePipeline.java
+++ b/ojluni/src/main/java/java/util/stream/DoublePipeline.java
@@ -52,6 +52,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+// Android-changed: Made public for CTS tests only.
public abstract class DoublePipeline<E_IN>
extends AbstractPipeline<E_IN, Double, DoubleStream>
implements DoubleStream {
@@ -128,11 +129,13 @@
// Shape-specific methods
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final StreamShape getOutputShape() {
return StreamShape.DOUBLE_VALUE;
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final <P_IN> Node<Double> evaluateToNode(PipelineHelper<Double> helper,
Spliterator<P_IN> spliterator,
boolean flattenTree,
@@ -141,6 +144,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final <P_IN> Spliterator<Double> wrap(PipelineHelper<Double> ph,
Supplier<Spliterator<P_IN>> supplier,
boolean isParallel) {
@@ -149,11 +153,13 @@
@Override
@SuppressWarnings("unchecked")
+ // Android-changed: Make public, to match the method it's overriding.
public final Spliterator.OfDouble lazySpliterator(Supplier<? extends Spliterator<Double>> supplier) {
return new StreamSpliterators.DelegatingSpliterator.OfDouble((Supplier<Spliterator.OfDouble>) supplier);
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final void forEachWithCancel(Spliterator<Double> spliterator, Sink<Double> sink) {
Spliterator.OfDouble spl = adapt(spliterator);
DoubleConsumer adaptedSink = adapt(sink);
@@ -161,6 +167,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final Node.Builder<Double> makeNodeBuilder(long exactSizeIfKnown, IntFunction<Double[]> generator) {
return Nodes.doubleBuilder(exactSizeIfKnown);
}
@@ -191,6 +198,7 @@
return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedDouble<Double>(sink) {
@Override
@@ -208,6 +216,7 @@
return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Double> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedDouble<U>(sink) {
@Override
@@ -225,6 +234,7 @@
return new IntPipeline.StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Double> opWrapSink(int flags, Sink<Integer> sink) {
return new Sink.ChainedDouble<Integer>(sink) {
@Override
@@ -242,6 +252,7 @@
return new LongPipeline.StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Double> opWrapSink(int flags, Sink<Long> sink) {
return new Sink.ChainedDouble<Long>(sink) {
@Override
@@ -258,6 +269,7 @@
return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedDouble<Double>(sink) {
@Override
@@ -284,6 +296,7 @@
return this;
return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE, StreamOpFlag.NOT_ORDERED) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
return sink;
}
@@ -296,6 +309,7 @@
return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SIZED) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedDouble<Double>(sink) {
@Override
@@ -319,6 +333,7 @@
return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
0) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedDouble<Double>(sink) {
@Override
@@ -514,8 +529,9 @@
* Source stage of a DoubleStream
*
* @param <E_IN> type of elements in the upstream source
- * @hide Visibility for CTS only (OpenJDK 8 streams tests).
+ * @hide Made public for CTS tests only (OpenJDK 8 streams tests).
*/
+ // Android-changed: Made public for CTS tests only.
public static class Head<E_IN> extends DoublePipeline<E_IN> {
/**
* Constructor for the source stage of a DoubleStream.
@@ -526,6 +542,7 @@
* in {@link StreamOpFlag}
* @param parallel {@code true} if the pipeline is parallel
*/
+ // Android-changed: Made public for CTS tests only.
public Head(Supplier<? extends Spliterator<Double>> source,
int sourceFlags, boolean parallel) {
super(source, sourceFlags, parallel);
@@ -539,17 +556,20 @@
* in {@link StreamOpFlag}
* @param parallel {@code true} if the pipeline is parallel
*/
+ // Android-changed: Made public for CTS tests only.
public Head(Spliterator<Double> source,
int sourceFlags, boolean parallel) {
super(source, sourceFlags, parallel);
}
@Override
+ // Android-changed: Made public for CTS tests only.
public final boolean opIsStateful() {
throw new UnsupportedOperationException();
}
@Override
+ // Android-changed: Made public for CTS tests only.
public final Sink<E_IN> opWrapSink(int flags, Sink<Double> sink) {
throw new UnsupportedOperationException();
}
@@ -585,6 +605,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+ // Android-changed: Made public for CTS tests only.
public abstract static class StatelessOp<E_IN> extends DoublePipeline<E_IN> {
/**
* Construct a new DoubleStream by appending a stateless intermediate
@@ -594,6 +615,7 @@
* @param inputShape the stream shape for the upstream pipeline stage
* @param opFlags operation flags for the new stage
*/
+ // Android-changed: Made public for CTS tests only.
public StatelessOp(AbstractPipeline<?, E_IN, ?> upstream,
StreamShape inputShape,
int opFlags) {
@@ -602,6 +624,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final boolean opIsStateful() {
return false;
}
@@ -614,6 +637,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+ // Android-changed: Made public for CTS tests only.
public abstract static class StatefulOp<E_IN> extends DoublePipeline<E_IN> {
/**
* Construct a new DoubleStream by appending a stateful intermediate
@@ -623,6 +647,7 @@
* @param inputShape the stream shape for the upstream pipeline stage
* @param opFlags operation flags for the new stage
*/
+ // Android-changed: Made public for CTS tests only.
public StatefulOp(AbstractPipeline<?, E_IN, ?> upstream,
StreamShape inputShape,
int opFlags) {
@@ -631,11 +656,13 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final boolean opIsStateful() {
return true;
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public abstract <P_IN> Node<Double> opEvaluateParallel(PipelineHelper<Double> helper,
Spliterator<P_IN> spliterator,
IntFunction<Double[]> generator);
diff --git a/ojluni/src/main/java/java/util/stream/DoubleStream.java b/ojluni/src/main/java/java/util/stream/DoubleStream.java
index 347587e..4d5d23d 100644
--- a/ojluni/src/main/java/java/util/stream/DoubleStream.java
+++ b/ojluni/src/main/java/java/util/stream/DoubleStream.java
@@ -25,6 +25,8 @@
package java.util.stream;
import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.DoubleSummaryStatistics;
diff --git a/ojluni/src/main/java/java/util/stream/IntPipeline.java b/ojluni/src/main/java/java/util/stream/IntPipeline.java
index 60ab3b3..11f0bb7 100644
--- a/ojluni/src/main/java/java/util/stream/IntPipeline.java
+++ b/ojluni/src/main/java/java/util/stream/IntPipeline.java
@@ -51,6 +51,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+// Android-changed: Made public for CTS tests only.
public abstract class IntPipeline<E_IN>
extends AbstractPipeline<E_IN, Integer, IntStream>
implements IntStream {
@@ -131,11 +132,13 @@
// Shape-specific methods
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final StreamShape getOutputShape() {
return StreamShape.INT_VALUE;
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final <P_IN> Node<Integer> evaluateToNode(PipelineHelper<Integer> helper,
Spliterator<P_IN> spliterator,
boolean flattenTree,
@@ -144,6 +147,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final <P_IN> Spliterator<Integer> wrap(PipelineHelper<Integer> ph,
Supplier<Spliterator<P_IN>> supplier,
boolean isParallel) {
@@ -152,11 +156,13 @@
@Override
@SuppressWarnings("unchecked")
+ // Android-changed: Make public, to match the method it's overriding.
public final Spliterator.OfInt lazySpliterator(Supplier<? extends Spliterator<Integer>> supplier) {
return new StreamSpliterators.DelegatingSpliterator.OfInt((Supplier<Spliterator.OfInt>) supplier);
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final void forEachWithCancel(Spliterator<Integer> spliterator, Sink<Integer> sink) {
Spliterator.OfInt spl = adapt(spliterator);
IntConsumer adaptedSink = adapt(sink);
@@ -164,6 +170,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final Node.Builder<Integer> makeNodeBuilder(long exactSizeIfKnown,
IntFunction<Integer[]> generator) {
return Nodes.intBuilder(exactSizeIfKnown);
@@ -205,6 +212,7 @@
return new DoublePipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Integer> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedInt<Double>(sink) {
@Override
@@ -227,6 +235,7 @@
return new StatelessOp<Integer>(this, StreamShape.INT_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
return new Sink.ChainedInt<Integer>(sink) {
@Override
@@ -244,6 +253,7 @@
return new ReferencePipeline.StatelessOp<Integer, U>(this, StreamShape.INT_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Integer> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedInt<U>(sink) {
@Override
@@ -261,6 +271,7 @@
return new LongPipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Integer> opWrapSink(int flags, Sink<Long> sink) {
return new Sink.ChainedInt<Long>(sink) {
@Override
@@ -278,6 +289,7 @@
return new DoublePipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Integer> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedInt<Double>(sink) {
@Override
@@ -294,6 +306,7 @@
return new StatelessOp<Integer>(this, StreamShape.INT_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
return new Sink.ChainedInt<Integer>(sink) {
@Override
@@ -320,6 +333,7 @@
return this;
return new StatelessOp<Integer>(this, StreamShape.INT_VALUE, StreamOpFlag.NOT_ORDERED) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
return sink;
}
@@ -332,6 +346,7 @@
return new StatelessOp<Integer>(this, StreamShape.INT_VALUE,
StreamOpFlag.NOT_SIZED) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
return new Sink.ChainedInt<Integer>(sink) {
@Override
@@ -355,6 +370,7 @@
return new StatelessOp<Integer>(this, StreamShape.INT_VALUE,
0) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
return new Sink.ChainedInt<Integer>(sink) {
@Override
@@ -513,6 +529,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+ // Android-changed: Made public for CTS tests only.
public static class Head<E_IN> extends IntPipeline<E_IN> {
/**
* Constructor for the source stage of an IntStream.
@@ -523,6 +540,7 @@
* in {@link StreamOpFlag}
* @param parallel {@code true} if the pipeline is parallel
*/
+ // Android-changed: Made public for CTS tests only.
public Head(Supplier<? extends Spliterator<Integer>> source,
int sourceFlags, boolean parallel) {
super(source, sourceFlags, parallel);
@@ -536,17 +554,20 @@
* in {@link StreamOpFlag}
* @param parallel {@code true} if the pipeline is parallel
*/
+ // Android-changed: Made public for CTS tests only.
public Head(Spliterator<Integer> source,
int sourceFlags, boolean parallel) {
super(source, sourceFlags, parallel);
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final boolean opIsStateful() {
throw new UnsupportedOperationException();
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final Sink<E_IN> opWrapSink(int flags, Sink<Integer> sink) {
throw new UnsupportedOperationException();
}
@@ -581,6 +602,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+ // Android-changed: Made public for CTS tests only.
public abstract static class StatelessOp<E_IN> extends IntPipeline<E_IN> {
/**
* Construct a new IntStream by appending a stateless intermediate
@@ -589,6 +611,7 @@
* @param inputShape The stream shape for the upstream pipeline stage
* @param opFlags Operation flags for the new stage
*/
+ // Android-changed: Made public for CTS tests only.
public StatelessOp(AbstractPipeline<?, E_IN, ?> upstream,
StreamShape inputShape,
int opFlags) {
@@ -597,6 +620,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final boolean opIsStateful() {
return false;
}
@@ -609,6 +633,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+ // Android-changed: Made public for CTS tests only.
public abstract static class StatefulOp<E_IN> extends IntPipeline<E_IN> {
/**
* Construct a new IntStream by appending a stateful intermediate
@@ -617,6 +642,7 @@
* @param inputShape The stream shape for the upstream pipeline stage
* @param opFlags Operation flags for the new stage
*/
+ // Android-changed: Made public for CTS tests only.
public StatefulOp(AbstractPipeline<?, E_IN, ?> upstream,
StreamShape inputShape,
int opFlags) {
@@ -625,11 +651,13 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final boolean opIsStateful() {
return true;
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public abstract <P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper,
Spliterator<P_IN> spliterator,
IntFunction<Integer[]> generator);
diff --git a/ojluni/src/main/java/java/util/stream/LongPipeline.java b/ojluni/src/main/java/java/util/stream/LongPipeline.java
index e7f6a5ad..768a378 100644
--- a/ojluni/src/main/java/java/util/stream/LongPipeline.java
+++ b/ojluni/src/main/java/java/util/stream/LongPipeline.java
@@ -52,6 +52,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+// Android-changed: Made public for CTS tests only.
public abstract class LongPipeline<E_IN>
extends AbstractPipeline<E_IN, Long, LongStream>
implements LongStream {
@@ -129,11 +130,13 @@
// Shape-specific methods
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final StreamShape getOutputShape() {
return StreamShape.LONG_VALUE;
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final <P_IN> Node<Long> evaluateToNode(PipelineHelper<Long> helper,
Spliterator<P_IN> spliterator,
boolean flattenTree,
@@ -142,6 +145,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final <P_IN> Spliterator<Long> wrap(PipelineHelper<Long> ph,
Supplier<Spliterator<P_IN>> supplier,
boolean isParallel) {
@@ -150,11 +154,13 @@
@Override
@SuppressWarnings("unchecked")
+ // Android-changed: Make public, to match the method it's overriding.
public final Spliterator.OfLong lazySpliterator(Supplier<? extends Spliterator<Long>> supplier) {
return new StreamSpliterators.DelegatingSpliterator.OfLong((Supplier<Spliterator.OfLong>) supplier);
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final void forEachWithCancel(Spliterator<Long> spliterator, Sink<Long> sink) {
Spliterator.OfLong spl = adapt(spliterator);
LongConsumer adaptedSink = adapt(sink);
@@ -162,6 +168,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final Node.Builder<Long> makeNodeBuilder(long exactSizeIfKnown, IntFunction<Long[]> generator) {
return Nodes.longBuilder(exactSizeIfKnown);
}
@@ -186,6 +193,7 @@
return new DoublePipeline.StatelessOp<Long>(this, StreamShape.LONG_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Long> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedLong<Double>(sink) {
@Override
@@ -208,6 +216,7 @@
return new StatelessOp<Long>(this, StreamShape.LONG_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
return new Sink.ChainedLong<Long>(sink) {
@Override
@@ -225,6 +234,7 @@
return new ReferencePipeline.StatelessOp<Long, U>(this, StreamShape.LONG_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Long> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedLong<U>(sink) {
@Override
@@ -242,6 +252,7 @@
return new IntPipeline.StatelessOp<Long>(this, StreamShape.LONG_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Long> opWrapSink(int flags, Sink<Integer> sink) {
return new Sink.ChainedLong<Integer>(sink) {
@Override
@@ -259,6 +270,7 @@
return new DoublePipeline.StatelessOp<Long>(this, StreamShape.LONG_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Long> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedLong<Double>(sink) {
@Override
@@ -275,6 +287,7 @@
return new StatelessOp<Long>(this, StreamShape.LONG_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
return new Sink.ChainedLong<Long>(sink) {
@Override
@@ -301,6 +314,7 @@
return this;
return new StatelessOp<Long>(this, StreamShape.LONG_VALUE, StreamOpFlag.NOT_ORDERED) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
return sink;
}
@@ -313,6 +327,7 @@
return new StatelessOp<Long>(this, StreamShape.LONG_VALUE,
StreamOpFlag.NOT_SIZED) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
return new Sink.ChainedLong<Long>(sink) {
@Override
@@ -336,6 +351,7 @@
return new StatelessOp<Long>(this, StreamShape.LONG_VALUE,
0) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
return new Sink.ChainedLong<Long>(sink) {
@Override
@@ -494,8 +510,9 @@
*
* @param <E_IN> type of elements in the upstream source
* @since 1.8
- * @hide Visibility for CTS only (OpenJDK 8 streams tests).
+ * @hide Made public for CTS tests only (OpenJDK 8 streams tests).
*/
+ // Android-changed: Made public for CTS tests only.
public static class Head<E_IN> extends LongPipeline<E_IN> {
/**
* Constructor for the source stage of a LongStream.
@@ -506,6 +523,7 @@
* in {@link StreamOpFlag}
* @param parallel {@code true} if the pipeline is parallel
*/
+ // Android-changed: Made public for CTS tests only.
public Head(Supplier<? extends Spliterator<Long>> source,
int sourceFlags, boolean parallel) {
super(source, sourceFlags, parallel);
@@ -519,17 +537,20 @@
* in {@link StreamOpFlag}
* @param parallel {@code true} if the pipeline is parallel
*/
+ // Android-changed: Made public for CTS tests only.
public Head(Spliterator<Long> source,
int sourceFlags, boolean parallel) {
super(source, sourceFlags, parallel);
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final boolean opIsStateful() {
throw new UnsupportedOperationException();
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final Sink<E_IN> opWrapSink(int flags, Sink<Long> sink) {
throw new UnsupportedOperationException();
}
@@ -561,6 +582,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+ // Android-changed: Made public for CTS tests only.
public abstract static class StatelessOp<E_IN> extends LongPipeline<E_IN> {
/**
* Construct a new LongStream by appending a stateless intermediate
@@ -569,6 +591,7 @@
* @param inputShape The stream shape for the upstream pipeline stage
* @param opFlags Operation flags for the new stage
*/
+ // Android-changed: Made public for CTS tests only.
public StatelessOp(AbstractPipeline<?, E_IN, ?> upstream,
StreamShape inputShape,
int opFlags) {
@@ -577,6 +600,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final boolean opIsStateful() {
return false;
}
@@ -589,6 +613,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+ // Android-changed: Made public for CTS tests only.
public abstract static class StatefulOp<E_IN> extends LongPipeline<E_IN> {
/**
* Construct a new LongStream by appending a stateful intermediate
@@ -598,6 +623,7 @@
* @param opFlags Operation flags for the new stage
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+ // Android-changed: Made public for CTS tests only.
public StatefulOp(AbstractPipeline<?, E_IN, ?> upstream,
StreamShape inputShape,
int opFlags) {
@@ -606,11 +632,13 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final boolean opIsStateful() {
return true;
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public abstract <P_IN> Node<Long> opEvaluateParallel(PipelineHelper<Long> helper,
Spliterator<P_IN> spliterator,
IntFunction<Long[]> generator);
diff --git a/ojluni/src/main/java/java/util/stream/LongStream.java b/ojluni/src/main/java/java/util/stream/LongStream.java
index 84189ef..a2d429e 100644
--- a/ojluni/src/main/java/java/util/stream/LongStream.java
+++ b/ojluni/src/main/java/java/util/stream/LongStream.java
@@ -24,8 +24,9 @@
*/
package java.util.stream;
-import java.math.BigInteger;
import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.LongSummaryStatistics;
@@ -791,11 +792,7 @@
// Split the range in two and concatenate
// Note: if the range is [Long.MIN_VALUE, Long.MAX_VALUE) then
// the lower range, [Long.MIN_VALUE, 0) will be further split in two
- // Android-changed: no divideUnsigned support yet, use BigInteger instead.
- long m = startInclusive +
- BigInteger.valueOf(endExclusive).subtract(BigInteger.valueOf(startInclusive))
- .divide(BigInteger.valueOf(2)).longValue() + 1;
-
+ long m = startInclusive + Long.divideUnsigned(endExclusive - startInclusive, 2) + 1;
return concat(range(startInclusive, m), range(m, endExclusive));
} else {
return StreamSupport.longStream(
@@ -829,11 +826,7 @@
// Note: if the range is [Long.MIN_VALUE, Long.MAX_VALUE] then
// the lower range, [Long.MIN_VALUE, 0), and upper range,
// [0, Long.MAX_VALUE], will both be further split in two
- // Android-changed: no divideUnsigned support yet, use BigInteger instead.
- long m = startInclusive +
- BigInteger.valueOf(endInclusive).subtract(BigInteger.valueOf(startInclusive))
- .divide(BigInteger.valueOf(2)).longValue() + 1;
-
+ long m = startInclusive + Long.divideUnsigned(endInclusive - startInclusive, 2) + 1;
return concat(range(startInclusive, m), rangeClosed(m, endInclusive));
} else {
return StreamSupport.longStream(
diff --git a/ojluni/src/main/java/java/util/stream/Node.java b/ojluni/src/main/java/java/util/stream/Node.java
index 4a72ca4..e20de78 100644
--- a/ojluni/src/main/java/java/util/stream/Node.java
+++ b/ojluni/src/main/java/java/util/stream/Node.java
@@ -58,6 +58,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+// Android-changed: Made public for CTS tests only.
public interface Node<T> {
/**
diff --git a/ojluni/src/main/java/java/util/stream/PipelineHelper.java b/ojluni/src/main/java/java/util/stream/PipelineHelper.java
index 06a4f92..832d68a 100644
--- a/ojluni/src/main/java/java/util/stream/PipelineHelper.java
+++ b/ojluni/src/main/java/java/util/stream/PipelineHelper.java
@@ -53,6 +53,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+// Android-changed: Made public for CTS tests only.
public abstract class PipelineHelper<P_OUT> {
/**
@@ -70,6 +71,7 @@
* @return the combined stream and operation flags
* @see StreamOpFlag
*/
+ // Android-changed: Made public for CTS tests only.
public abstract int getStreamAndOpFlags();
/**
@@ -151,6 +153,7 @@
* @return a {@code Sink} that implements the pipeline stages and sends
* results to the provided {@code Sink}
*/
+ // Android-changed: Made public for CTS tests only.
public abstract<P_IN> Sink<P_IN> wrapSink(Sink<P_OUT> sink);
/**
@@ -198,6 +201,7 @@
* @param generator a factory function for array instances
* @return the {@code Node} containing all output elements
*/
+ // Android-changed: Made public for CTS tests only.
public abstract<P_IN> Node<P_OUT> evaluate(Spliterator<P_IN> spliterator,
boolean flatten,
IntFunction<P_OUT[]> generator);
diff --git a/ojluni/src/main/java/java/util/stream/ReferencePipeline.java b/ojluni/src/main/java/java/util/stream/ReferencePipeline.java
index ddec43e..84ec8c5 100644
--- a/ojluni/src/main/java/java/util/stream/ReferencePipeline.java
+++ b/ojluni/src/main/java/java/util/stream/ReferencePipeline.java
@@ -55,6 +55,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+// Android-changed: Made public for CTS tests only.
public abstract class ReferencePipeline<P_IN, P_OUT>
extends AbstractPipeline<P_IN, P_OUT, Stream<P_OUT>>
implements Stream<P_OUT> {
@@ -98,11 +99,13 @@
// Shape-specific methods
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final StreamShape getOutputShape() {
return StreamShape.REFERENCE;
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final <P_IN> Node<P_OUT> evaluateToNode(PipelineHelper<P_OUT> helper,
Spliterator<P_IN> spliterator,
boolean flattenTree,
@@ -111,6 +114,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final <P_IN> Spliterator<P_OUT> wrap(PipelineHelper<P_OUT> ph,
Supplier<Spliterator<P_IN>> supplier,
boolean isParallel) {
@@ -118,16 +122,19 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final Spliterator<P_OUT> lazySpliterator(Supplier<? extends Spliterator<P_OUT>> supplier) {
return new StreamSpliterators.DelegatingSpliterator<>(supplier);
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final void forEachWithCancel(Spliterator<P_OUT> spliterator, Sink<P_OUT> sink) {
do { } while (!sink.cancellationRequested() && spliterator.tryAdvance(sink));
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final Node.Builder<P_OUT> makeNodeBuilder(long exactSizeIfKnown, IntFunction<P_OUT[]> generator) {
return Nodes.builder(exactSizeIfKnown, generator);
}
@@ -151,6 +158,7 @@
return this;
return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE, StreamOpFlag.NOT_ORDERED) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
return sink;
}
@@ -163,6 +171,7 @@
return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE,
StreamOpFlag.NOT_SIZED) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
@Override
@@ -204,6 +213,7 @@
return new IntPipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<P_OUT> opWrapSink(int flags, Sink<Integer> sink) {
return new Sink.ChainedReference<P_OUT, Integer>(sink) {
@Override
@@ -221,6 +231,7 @@
return new LongPipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<P_OUT> opWrapSink(int flags, Sink<Long> sink) {
return new Sink.ChainedReference<P_OUT, Long>(sink) {
@Override
@@ -238,6 +249,7 @@
return new DoublePipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<P_OUT> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedReference<P_OUT, Double>(sink) {
@Override
@@ -283,6 +295,7 @@
return new IntPipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<P_OUT> opWrapSink(int flags, Sink<Integer> sink) {
return new Sink.ChainedReference<P_OUT, Integer>(sink) {
IntConsumer downstreamAsInt = downstream::accept;
@@ -311,6 +324,7 @@
return new DoublePipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<P_OUT> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedReference<P_OUT, Double>(sink) {
DoubleConsumer downstreamAsDouble = downstream::accept;
@@ -339,6 +353,7 @@
return new LongPipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<P_OUT> opWrapSink(int flags, Sink<Long> sink) {
return new Sink.ChainedReference<P_OUT, Long>(sink) {
LongConsumer downstreamAsLong = downstream::accept;
@@ -366,6 +381,7 @@
return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE,
0) {
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
@Override
@@ -436,7 +452,7 @@
// super type of U an ArrayStoreException will be thrown.
@SuppressWarnings("rawtypes")
IntFunction rawGenerator = (IntFunction) generator;
- // TODO(b/29399275): Eclipse compiler requires explicit (Node<A[]>) cast below.
+ // Android-changed: Eclipse compiler requires explicit (Node<A[]>) cast (b/29399275).
return (A[]) Nodes.flatten((Node<A[]>) evaluateToArrayNode(rawGenerator), rawGenerator)
.asArray(rawGenerator);
}
@@ -539,6 +555,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+ // Android-changed: Made public for CTS tests only.
public static class Head<E_IN, E_OUT> extends ReferencePipeline<E_IN, E_OUT> {
/**
* Constructor for the source stage of a Stream.
@@ -548,6 +565,7 @@
* @param sourceFlags the source flags for the stream source, described
* in {@link StreamOpFlag}
*/
+ // Android-changed: Made public for CTS tests only.
public Head(Supplier<? extends Spliterator<?>> source,
int sourceFlags, boolean parallel) {
super(source, sourceFlags, parallel);
@@ -560,17 +578,20 @@
* @param sourceFlags the source flags for the stream source, described
* in {@link StreamOpFlag}
*/
+ // Android-changed: Made public for CTS tests only.
public Head(Spliterator<?> source,
int sourceFlags, boolean parallel) {
super(source, sourceFlags, parallel);
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final boolean opIsStateful() {
throw new UnsupportedOperationException();
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final Sink<E_IN> opWrapSink(int flags, Sink<E_OUT> sink) {
throw new UnsupportedOperationException();
}
@@ -606,6 +627,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+ // Android-changed: Made public for CTS tests only.
public abstract static class StatelessOp<E_IN, E_OUT>
extends ReferencePipeline<E_IN, E_OUT> {
/**
@@ -616,6 +638,7 @@
* @param inputShape The stream shape for the upstream pipeline stage
* @param opFlags Operation flags for the new stage
*/
+ // Android-changed: Made public for CTS tests only.
public StatelessOp(AbstractPipeline<?, E_IN, ?> upstream,
StreamShape inputShape,
int opFlags) {
@@ -624,6 +647,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final boolean opIsStateful() {
return false;
}
@@ -637,6 +661,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+ // Android-changed: Made public for CTS tests only.
public abstract static class StatefulOp<E_IN, E_OUT>
extends ReferencePipeline<E_IN, E_OUT> {
/**
@@ -646,6 +671,7 @@
* @param inputShape The stream shape for the upstream pipeline stage
* @param opFlags Operation flags for the new stage
*/
+ // Android-changed: Made public for CTS tests only.
public StatefulOp(AbstractPipeline<?, E_IN, ?> upstream,
StreamShape inputShape,
int opFlags) {
@@ -654,11 +680,13 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public final boolean opIsStateful() {
return true;
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public abstract <P_IN> Node<E_OUT> opEvaluateParallel(PipelineHelper<E_OUT> helper,
Spliterator<P_IN> spliterator,
IntFunction<E_OUT[]> generator);
diff --git a/ojluni/src/main/java/java/util/stream/Sink.java b/ojluni/src/main/java/java/util/stream/Sink.java
index 032fd45..2c5609c 100644
--- a/ojluni/src/main/java/java/util/stream/Sink.java
+++ b/ojluni/src/main/java/java/util/stream/Sink.java
@@ -115,6 +115,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+// Android-changed: Made public for CTS tests only.
public interface Sink<T> extends Consumer<T> {
/**
* Resets the sink state to receive a fresh data set. This must be called
diff --git a/ojluni/src/main/java/java/util/stream/SliceOps.java b/ojluni/src/main/java/java/util/stream/SliceOps.java
index 3042197..6a6f85e 100644
--- a/ojluni/src/main/java/java/util/stream/SliceOps.java
+++ b/ojluni/src/main/java/java/util/stream/SliceOps.java
@@ -130,6 +130,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public <P_IN> Spliterator<T> opEvaluateParallelLazy(PipelineHelper<T> helper, Spliterator<P_IN> spliterator) {
long size = helper.exactOutputSizeIfKnown(spliterator);
if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
@@ -157,6 +158,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public <P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,
Spliterator<P_IN> spliterator,
IntFunction<T[]> generator) {
@@ -186,6 +188,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<T> opWrapSink(int flags, Sink<T> sink) {
return new Sink.ChainedReference<T, T>(sink) {
long n = skip;
@@ -246,6 +249,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public <P_IN> Spliterator<Integer> opEvaluateParallelLazy(PipelineHelper<Integer> helper,
Spliterator<P_IN> spliterator) {
long size = helper.exactOutputSizeIfKnown(spliterator);
@@ -266,6 +270,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public <P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper,
Spliterator<P_IN> spliterator,
IntFunction<Integer[]> generator) {
@@ -295,6 +300,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
return new Sink.ChainedInt<Integer>(sink) {
long n = skip;
@@ -355,6 +361,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public <P_IN> Spliterator<Long> opEvaluateParallelLazy(PipelineHelper<Long> helper,
Spliterator<P_IN> spliterator) {
long size = helper.exactOutputSizeIfKnown(spliterator);
@@ -375,6 +382,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public <P_IN> Node<Long> opEvaluateParallel(PipelineHelper<Long> helper,
Spliterator<P_IN> spliterator,
IntFunction<Long[]> generator) {
@@ -404,6 +412,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
return new Sink.ChainedLong<Long>(sink) {
long n = skip;
@@ -464,6 +473,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public <P_IN> Spliterator<Double> opEvaluateParallelLazy(PipelineHelper<Double> helper,
Spliterator<P_IN> spliterator) {
long size = helper.exactOutputSizeIfKnown(spliterator);
@@ -484,6 +494,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public <P_IN> Node<Double> opEvaluateParallel(PipelineHelper<Double> helper,
Spliterator<P_IN> spliterator,
IntFunction<Double[]> generator) {
@@ -513,6 +524,7 @@
}
@Override
+ // Android-changed: Make public, to match the method it's overriding.
public Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedDouble<Double>(sink) {
long n = skip;
diff --git a/ojluni/src/main/java/java/util/stream/SpinedBuffer.java b/ojluni/src/main/java/java/util/stream/SpinedBuffer.java
index c91c4ff..d21518a 100644
--- a/ojluni/src/main/java/java/util/stream/SpinedBuffer.java
+++ b/ojluni/src/main/java/java/util/stream/SpinedBuffer.java
@@ -54,6 +54,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+// Android-changed: Made public for CTS tests only.
public class SpinedBuffer<E>
extends AbstractSpinedBuffer
implements Consumer<E>, Iterable<E> {
@@ -94,6 +95,7 @@
* is negative
*/
@SuppressWarnings("unchecked")
+ // Android-changed: Made public for CTS tests only.
public SpinedBuffer(int initialCapacity) {
super(initialCapacity);
curChunk = (E[]) new Object[1 << initialChunkPower];
@@ -103,6 +105,7 @@
* Constructs an empty list with an initial capacity of sixteen.
*/
@SuppressWarnings("unchecked")
+ // Android-changed: Made public for CTS tests only.
public SpinedBuffer() {
super();
curChunk = (E[]) new Object[1 << initialChunkPower];
@@ -415,9 +418,8 @@
* @param <E> the wrapper type for this primitive type
* @param <T_ARR> the array type for this primitive type
* @param <T_CONS> the Consumer type for this primitive type
- * @hide Visible for CTS testing only (OpenJDK8 tests).
*/
- public abstract static class OfPrimitive<E, T_ARR, T_CONS>
+ abstract static class OfPrimitive<E, T_ARR, T_CONS>
extends AbstractSpinedBuffer implements Iterable<E> {
/*
@@ -723,10 +725,13 @@
* An ordered collection of {@code int} values.
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+ // Android-changed: Made public for CTS tests only.
public static class OfInt extends SpinedBuffer.OfPrimitive<Integer, int[], IntConsumer>
implements IntConsumer {
+ // Android-changed: Made public for CTS tests only.
public OfInt() { }
+ // Android-changed: Made public for CTS tests only.
public OfInt(int initialCapacity) {
super(initialCapacity);
}
@@ -837,10 +842,13 @@
* An ordered collection of {@code long} values.
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+ // Android-changed: Made public for CTS tests only.
public static class OfLong extends SpinedBuffer.OfPrimitive<Long, long[], LongConsumer>
implements LongConsumer {
+ // Android-changed: Made public for CTS tests only.
public OfLong() { }
+ // Android-changed: Made public for CTS tests only.
public OfLong(int initialCapacity) {
super(initialCapacity);
}
@@ -952,11 +960,14 @@
* An ordered collection of {@code double} values.
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+ // Android-changed: Made public for CTS tests only.
public static class OfDouble
extends SpinedBuffer.OfPrimitive<Double, double[], DoubleConsumer>
implements DoubleConsumer {
+ // Android-changed: Made public for CTS tests only.
public OfDouble() { }
+ // Android-changed: Made public for CTS tests only.
public OfDouble(int initialCapacity) {
super(initialCapacity);
}
diff --git a/ojluni/src/main/java/java/util/stream/Stream.java b/ojluni/src/main/java/java/util/stream/Stream.java
index d4cb9ff..c35fc05 100644
--- a/ojluni/src/main/java/java/util/stream/Stream.java
+++ b/ojluni/src/main/java/java/util/stream/Stream.java
@@ -25,6 +25,8 @@
package java.util.stream;
import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
@@ -126,7 +128,8 @@
*
* <p>Streams have a {@link #close()} method and implement {@link AutoCloseable},
* but nearly all stream instances do not actually need to be closed after use.
- * Generally, only streams whose source is an IO channel will require closing. Most streams
+ * Generally, only streams whose source is an IO channel (such as those returned
+ * by {@link Files#lines(Path, Charset)}) will require closing. Most streams
* are backed by collections, arrays, or generating functions, which require no
* special resource management. (If a stream does require closing, it can be
* declared as a resource in a {@code try}-with-resources statement.)
diff --git a/ojluni/src/main/java/java/util/stream/StreamOpFlag.java b/ojluni/src/main/java/java/util/stream/StreamOpFlag.java
index 3477a33..83a3660 100644
--- a/ojluni/src/main/java/java/util/stream/StreamOpFlag.java
+++ b/ojluni/src/main/java/java/util/stream/StreamOpFlag.java
@@ -202,6 +202,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+// Android-changed: Made public for CTS tests only.
public enum StreamOpFlag {
/*
@@ -458,6 +459,7 @@
*
* @return the bitmap for setting this characteristic
*/
+ // Android-changed: Made public for CTS tests only.
public int set() {
return set;
}
@@ -467,6 +469,7 @@
*
* @return the bitmap for clearing this characteristic
*/
+ // Android-changed: Made public for CTS tests only.
public int clear() {
return clear;
}
@@ -476,6 +479,7 @@
*
* @return true if a stream-based flag, otherwise false.
*/
+ // Android-changed: Made public for CTS tests only.
public boolean isStreamFlag() {
return maskTable.get(Type.STREAM) > 0;
}
@@ -488,6 +492,7 @@
* operation flags
* @return true if this flag is known, otherwise false.
*/
+ // Android-changed: Made public for CTS tests only.
public boolean isKnown(int flags) {
return (flags & preserve) == set;
}
@@ -499,6 +504,7 @@
* @param flags the operation flags or combined stream and operations flags.
* @return true if this flag is preserved, otherwise false.
*/
+ // Android-changed: Made public for CTS tests only.
public boolean isCleared(int flags) {
return (flags & preserve) == clear;
}
@@ -509,6 +515,7 @@
* @param flags the combined stream and operations flags.
* @return true if this flag is preserved, otherwise false.
*/
+ // Android-changed: Made public for CTS tests only.
public boolean isPreserved(int flags) {
return (flags & preserve) == preserve;
}
@@ -519,6 +526,7 @@
* @param t the flag type.
* @return true if this flag can be set for the flag type, otherwise false.
*/
+ // Android-changed: Made public for CTS tests only.
public boolean canSet(Type t) {
return (maskTable.get(t) & SET_BITS) > 0;
}
@@ -526,26 +534,31 @@
/**
* The bit mask for spliterator characteristics
*/
+ // Android-changed: Made public for CTS tests only.
public static final int SPLITERATOR_CHARACTERISTICS_MASK = createMask(Type.SPLITERATOR);
/**
* The bit mask for source stream flags.
*/
+ // Android-changed: Made public for CTS tests only.
public static final int STREAM_MASK = createMask(Type.STREAM);
/**
* The bit mask for intermediate operation flags.
*/
+ // Android-changed: Made public for CTS tests only.
public static final int OP_MASK = createMask(Type.OP);
/**
* The bit mask for terminal operation flags.
*/
+ // Android-changed: Made public for CTS tests only.
public static final int TERMINAL_OP_MASK = createMask(Type.TERMINAL_OP);
/**
* The bit mask for upstream terminal operation flags.
*/
+ // Android-changed: Made public for CTS tests only.
public static final int UPSTREAM_TERMINAL_OP_MASK = createMask(Type.UPSTREAM_TERMINAL_OP);
private static int createMask(Type t) {
@@ -583,51 +596,61 @@
* The initial value to be combined with the stream flags of the first
* stream in the pipeline.
*/
+ // Android-changed: Made public for CTS tests only.
public static final int INITIAL_OPS_VALUE = FLAG_MASK_IS | FLAG_MASK_NOT;
/**
* The bit value to set or inject {@link #DISTINCT}.
*/
+ // Android-changed: Made public for CTS tests only.
public static final int IS_DISTINCT = DISTINCT.set;
/**
* The bit value to clear {@link #DISTINCT}.
*/
+ // Android-changed: Made public for CTS tests only.
public static final int NOT_DISTINCT = DISTINCT.clear;
/**
* The bit value to set or inject {@link #SORTED}.
*/
+ // Android-changed: Made public for CTS tests only.
public static final int IS_SORTED = SORTED.set;
/**
* The bit value to clear {@link #SORTED}.
*/
+ // Android-changed: Made public for CTS tests only.
public static final int NOT_SORTED = SORTED.clear;
/**
* The bit value to set or inject {@link #ORDERED}.
*/
+ // Android-changed: Made public for CTS tests only.
public static final int IS_ORDERED = ORDERED.set;
/**
* The bit value to clear {@link #ORDERED}.
*/
+ // Android-changed: Made public for CTS tests only.
public static final int NOT_ORDERED = ORDERED.clear;
/**
* The bit value to set {@link #SIZED}.
*/
+ // Android-changed: Made public for CTS tests only.
public static final int IS_SIZED = SIZED.set;
/**
* The bit value to clear {@link #SIZED}.
*/
+ // Android-changed: Made public for CTS tests only.
public static final int NOT_SIZED = SIZED.clear;
/**
* The bit value to inject {@link #SHORT_CIRCUIT}.
*/
+ // Android-changed: Made public for CTS tests only.
public static final int IS_SHORT_CIRCUIT = SHORT_CIRCUIT.set;
private static int getMask(int flags) {
@@ -684,6 +707,7 @@
* The value {#link INITIAL_OPS_VALUE} must be used as the seed value.
* @return the updated combined stream and operation flags.
*/
+ // Android-changed: Made public for CTS tests only.
public static int combineOpFlags(int newStreamOrOpFlags, int prevCombOpFlags) {
// 0x01 or 0x10 nibbles are transformed to 0x11
// 0x00 nibbles remain unchanged
@@ -701,6 +725,7 @@
* @param combOpFlags the combined stream and operation flags.
* @return the stream flags.
*/
+ // Android-changed: Made public for CTS tests only.
public static int toStreamFlags(int combOpFlags) {
// By flipping the nibbles 0x11 become 0x00 and 0x01 become 0x10
// Shift left 1 to restore set flags and mask off anything other than the set flags
@@ -713,6 +738,7 @@
* @param streamFlags the stream flags.
* @return the spliterator characteristic bit set.
*/
+ // Android-changed: Made public for CTS tests only.
public static int toCharacteristics(int streamFlags) {
return streamFlags & SPLITERATOR_CHARACTERISTICS_MASK;
}
@@ -730,6 +756,7 @@
* bit set.
* @return the stream flags.
*/
+ // Android-changed: Made public for CTS tests only.
public static int fromCharacteristics(Spliterator<?> spliterator) {
int characteristics = spliterator.characteristics();
if ((characteristics & Spliterator.SORTED) != 0 && spliterator.getComparator() != null) {
@@ -748,6 +775,7 @@
* @param characteristics the spliterator characteristic bit set.
* @return the stream flags.
*/
+ // Android-changed: Made public for CTS tests only.
public static int fromCharacteristics(int characteristics) {
return characteristics & SPLITERATOR_CHARACTERISTICS_MASK;
}
diff --git a/ojluni/src/main/java/java/util/stream/StreamShape.java b/ojluni/src/main/java/java/util/stream/StreamShape.java
index 2c5f83b..5bcae4a 100644
--- a/ojluni/src/main/java/java/util/stream/StreamShape.java
+++ b/ojluni/src/main/java/java/util/stream/StreamShape.java
@@ -47,6 +47,7 @@
* @since 1.8
* @hide Visible for CTS testing only (OpenJDK8 tests).
*/
+// Android-changed: Made public for CTS tests only.
public enum StreamShape {
/**
* The shape specialization corresponding to {@code Stream} and elements
diff --git a/ojluni/src/main/java/java/util/stream/package-info.java b/ojluni/src/main/java/java/util/stream/package-info.java
index 17b070a..016c86d 100644
--- a/ojluni/src/main/java/java/util/stream/package-info.java
+++ b/ojluni/src/main/java/java/util/stream/package-info.java
@@ -82,7 +82,13 @@
* {@link java.util.stream.Stream#of(Object[])},
* {@link java.util.stream.IntStream#range(int, int)}
* or {@link java.util.stream.Stream#iterate(Object, UnaryOperator)};</li>
- * </li>
+ * <li>The lines of a file can be obtained from {@link java.io.BufferedReader#lines()};</li>
+ * <li>Streams of file paths can be obtained from methods in {@link java.nio.file.Files};</li>
+ * <li>Streams of random numbers can be obtained from {@link java.util.Random#ints()};</li>
+ * <li>Numerous other stream-bearing methods in the JDK, including
+ * {@link java.util.BitSet#stream()},
+ * {@link java.util.regex.Pattern#splitAsStream(java.lang.CharSequence)},
+ * and {@link java.util.jar.JarFile#stream()}.</li>
* </ul>
*
* <p>Additional stream sources can be provided by third-party libraries using
diff --git a/ojluni/src/main/java/java/util/zip/Deflater.java b/ojluni/src/main/java/java/util/zip/Deflater.java
index 578bd56..5c7dffd 100644
--- a/ojluni/src/main/java/java/util/zip/Deflater.java
+++ b/ojluni/src/main/java/java/util/zip/Deflater.java
@@ -79,7 +79,7 @@
// Android-added: @ReachabilitySensitive
// Finalization clears zsRef, and thus can't be allowed to occur early.
// Unlike some other CloseGuard uses, the spec allows clients to rely on finalization
- // here. Thus dropping a deflater without calling close() should work correctly.
+ // here. Thus dropping a deflater without calling end() should work correctly.
// It thus does not suffice to just rely on the CloseGuard annotation.
@ReachabilitySensitive
private final ZStreamRef zsRef;
@@ -91,7 +91,7 @@
private long bytesRead;
private long bytesWritten;
- // Android-changed: added close guard
+ // Android-added: CloseGuard support.
@ReachabilitySensitive
private final CloseGuard guard = CloseGuard.get();
@@ -165,6 +165,14 @@
*/
public static final int FULL_FLUSH = 3;
+ // Android-removed: initIDs handled in register method.
+ /*
+ static {
+ /* Zip library is loaded from System.initializeSystemClass *
+ initIDs();
+ }
+ */
+
/**
* Creates a new compressor using the specified compression level.
* If 'nowrap' is true then the ZLIB header and checksum fields will
@@ -177,7 +185,7 @@
this.level = level;
this.strategy = DEFAULT_STRATEGY;
this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap));
- // Android-changed: added close guard
+ // Android-added: CloseGuard support.
guard.open("end");
}
@@ -547,7 +555,7 @@
*/
public void end() {
synchronized (zsRef) {
- // Android-changed: added close guard
+ // Android-added: CloseGuard support.
guard.close();
long addr = zsRef.address();
zsRef.clear();
@@ -562,7 +570,7 @@
* Closes the compressor when garbage is collected.
*/
protected void finalize() {
- // Android-changed: added close guard
+ // Android-added: CloseGuard support.
if (guard != null) {
guard.warnIfOpen();
}
diff --git a/ojluni/src/main/java/java/util/zip/DeflaterInputStream.java b/ojluni/src/main/java/java/util/zip/DeflaterInputStream.java
index 26c5b19..c3f7802 100644
--- a/ojluni/src/main/java/java/util/zip/DeflaterInputStream.java
+++ b/ojluni/src/main/java/java/util/zip/DeflaterInputStream.java
@@ -201,14 +201,23 @@
off += n;
len -= n;
}
- // Android-changed: set reachEOF eagerly (not just when the number of bytes is zero).
- // so that available is more accurate.
+ // BEGIN Android-changed: Return more accurate value from available().
+ // Set reachEOF eagerly when the Deflater has finished, and not just when the number of
+ // bytes is zero so that available is more accurate.
+ // See http://b/111589691
+ /*
+ if (cnt == 0 && def.finished()) {
+ reachEOF = true;
+ cnt = -1;
+ }
+ */
if (def.finished()) {
- reachEOF =true;
+ reachEOF = true;
if (cnt == 0) {
cnt = -1;
}
}
+ // END Android-changed: Return more accurate value from available().
return cnt;
}
diff --git a/ojluni/src/main/java/java/util/zip/DeflaterOutputStream.java b/ojluni/src/main/java/java/util/zip/DeflaterOutputStream.java
index 7b7d113..7821737 100644
--- a/ojluni/src/main/java/java/util/zip/DeflaterOutputStream.java
+++ b/ojluni/src/main/java/java/util/zip/DeflaterOutputStream.java
@@ -249,7 +249,12 @@
* @throws IOException if an I/O error has occurred
*/
protected void deflate() throws IOException {
- // Android-changed: output all available compressed data (b/4005091)
+ // Android-changed: Output all available compressed data (b/4005091).
+ // See http://b/111496419 for more details.
+ // int len = def.deflate(buf, 0, buf.length);
+ // if (len > 0) {
+ // out.write(buf, 0, len);
+ // }
int len = 0;
while ((len = def.deflate(buf, 0, buf.length)) > 0) {
out.write(buf, 0, len);
diff --git a/ojluni/src/main/java/java/util/zip/GZIPInputStream.java b/ojluni/src/main/java/java/util/zip/GZIPInputStream.java
index 915d446..109454c 100644
--- a/ojluni/src/main/java/java/util/zip/GZIPInputStream.java
+++ b/ojluni/src/main/java/java/util/zip/GZIPInputStream.java
@@ -75,9 +75,17 @@
*/
public GZIPInputStream(InputStream in, int size) throws IOException {
super(in, new Inflater(true), size);
- // Android-changed: Unconditionally close external inflaters (b/26462400)
+ // Android-removed: Unconditionally close external inflaters (b/26462400)
// usesDefaultInflater = true;
- readHeader(in);
+ // BEGIN Android-changed: Do not rely on finalization to inf.end().
+ // readHeader(in);
+ try {
+ readHeader(in);
+ } catch (Exception e) {
+ inf.end();
+ throw e;
+ }
+ // END Android-changed: Do not rely on finalization to inf.end().
}
/**
diff --git a/ojluni/src/main/java/java/util/zip/Inflater.java b/ojluni/src/main/java/java/util/zip/Inflater.java
index 8a1ba6f..eb8754e 100644
--- a/ojluni/src/main/java/java/util/zip/Inflater.java
+++ b/ojluni/src/main/java/java/util/zip/Inflater.java
@@ -80,7 +80,7 @@
// Android-added: @ReachabilitySensitive
// Finalization clears zsRef, and thus can't be allowed to occur early.
// Unlike some other CloseGuard uses, the spec allows clients to rely on finalization
- // here. Thus dropping a deflater without calling close() should work correctly.
+ // here. Thus dropping a deflater without calling end() should work correctly.
// It thus does not suffice to just rely on the CloseGuard annotation.
@ReachabilitySensitive
private final ZStreamRef zsRef;
@@ -91,12 +91,20 @@
private long bytesRead;
private long bytesWritten;
- // Android-changed: added CloseGuard instance
+ // Android-added: CloseGuard support.
@ReachabilitySensitive
private final CloseGuard guard = CloseGuard.get();
private static final byte[] defaultBuf = new byte[0];
+ // Android-removed: initIDs handled in register method.
+ /*
+ static {
+ /* Zip library is loaded from System.initializeSystemClass *
+ initIDs();
+ }
+ */
+
/**
* Creates a new decompressor. If the parameter 'nowrap' is true then
* the ZLIB header and checksum fields will not be used. This provides
@@ -110,7 +118,7 @@
*/
public Inflater(boolean nowrap) {
zsRef = new ZStreamRef(init(nowrap));
- // Android-changed: added close guard
+ // Android-added: CloseGuard support.
guard.open("end");
}
@@ -378,6 +386,7 @@
*/
public void end() {
synchronized (zsRef) {
+ // Android-added: CloseGuard support.
guard.close();
long addr = zsRef.address();
@@ -393,7 +402,7 @@
* Closes the decompressor when garbage is collected.
*/
protected void finalize() {
- // Android-changed: added close guard
+ // Android-added: CloseGuard support.
if (guard != null) {
guard.warnIfOpen();
}
@@ -403,9 +412,8 @@
private void ensureOpen () {
assert Thread.holdsLock(zsRef);
- // Android-changed: Throw IllegalStateException instead of a NullPointerException.
if (zsRef.address() == 0)
- throw new IllegalStateException("Inflater has been closed");
+ throw new NullPointerException("Inflater has been closed");
}
boolean ended() {
diff --git a/ojluni/src/main/java/java/util/zip/InflaterInputStream.java b/ojluni/src/main/java/java/util/zip/InflaterInputStream.java
index 0ae662e..b65adbe 100644
--- a/ojluni/src/main/java/java/util/zip/InflaterInputStream.java
+++ b/ojluni/src/main/java/java/util/zip/InflaterInputStream.java
@@ -56,7 +56,20 @@
*/
protected int len;
- // Android-changed: closed is now protected.
+ // Android-changed: Make closed accessible to subclasses.
+ // This was made protected because it needed to be accessed by
+ // StrictJarFile.ZipInflaterInputStream. Unfortunately, it was not marked as @hide and so it
+ // inadvertently became part of the public API. It will be marked as @removed to remove it from
+ // the public API in a future release of Android. See http://b/111592689 for more information.
+ // private boolean closed = false;
+ /**
+ * Indicates whether the {@link #close()} method has been called, internal use only.
+ *
+ * @deprecated This field will be removed from a future version of Android and should not be
+ * used. Subclasses that access this field need to be modified to keep track of their own
+ * closed state by overriding close().
+ */
+ @Deprecated
protected boolean closed = false;
// this flag is set to true after EOF has reached
@@ -102,6 +115,7 @@
}
// Android-changed: Unconditionally close external inflaters (b/26462400)
+ // See http://b/111630946 for more details.
// boolean usesDefaultInflater = false;
/**
@@ -163,12 +177,6 @@
fill();
}
}
-
- // Android-changed: Eagerly set reachEOF.
- if (inf.finished()) {
- reachEOF = true;
- }
-
return n;
} catch (DataFormatException e) {
String s = e.getMessage();
@@ -190,6 +198,14 @@
ensureOpen();
if (reachEOF) {
return 0;
+ // BEGIN Android-added: Return more accurate value from available().
+ // Integrates change http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/dbcf47bfb044 made as part
+ // of https://bugs.openjdk.java.net/browse/JDK-7031075.
+ } else if (inf.finished()) {
+ // the end of the compressed data stream has been reached
+ reachEOF = true;
+ return 0;
+ // END Android-added: Return more accurate value from available().
} else {
return 1;
}
diff --git a/ojluni/src/main/java/java/util/zip/ZipEntry.java b/ojluni/src/main/java/java/util/zip/ZipEntry.java
index 57433e0..0de6756 100644
--- a/ojluni/src/main/java/java/util/zip/ZipEntry.java
+++ b/ojluni/src/main/java/java/util/zip/ZipEntry.java
@@ -32,7 +32,6 @@
import java.util.Objects;
import java.util.concurrent.TimeUnit;
-
import static java.util.zip.ZipConstants64.*;
/**
@@ -42,7 +41,6 @@
*/
public
class ZipEntry implements ZipConstants, Cloneable {
-
String name; // entry name
long xdostime = -1; // last modification time (in extended DOS time,
// where milliseconds lost in conversion might
@@ -57,7 +55,8 @@
int flag = 0; // general purpose flag
byte[] extra; // optional extra field data for entry
String comment; // optional comment string for entry
- // Android-changed: Add dataOffset for internal use.
+ // Android-added: Add dataOffset for internal use.
+ // Used by android.util.jar.StrictJarFile from frameworks.
long dataOffset;
/**
@@ -75,21 +74,6 @@
*/
static final long DOSTIME_BEFORE_1980 = (1 << 21) | (1 << 16);
- /** @hide - Called from StrictJarFile native code. */
- public ZipEntry(String name, String comment, long crc, long compressedSize,
- long size, int compressionMethod, int xdostime, byte[] extra,
- long dataOffset) {
- this.name = name;
- this.comment = comment;
- this.crc = crc;
- this.csize = compressedSize;
- this.size = size;
- this.method = compressionMethod;
- this.xdostime = xdostime;
- this.dataOffset = dataOffset;
- this.setExtra0(extra, false);
- }
-
/**
* Approximately 128 years, in milliseconds (ignoring leap years etc).
*
@@ -105,10 +89,26 @@
* should be sufficient.
* @hide
*/
- // Android-changed: public for testing purposes
+ // Android-changed: Make UPPER_DOSTIME_BOUND public hidden for testing purposes.
public static final long UPPER_DOSTIME_BOUND =
128L * 365 * 24 * 60 * 60 * 1000;
+ // Android-added: New constructor for use by StrictJarFile native code.
+ /** @hide */
+ public ZipEntry(String name, String comment, long crc, long compressedSize,
+ long size, int compressionMethod, int xdostime, byte[] extra,
+ long dataOffset) {
+ this.name = name;
+ this.comment = comment;
+ this.crc = crc;
+ this.csize = compressedSize;
+ this.size = size;
+ this.method = compressionMethod;
+ this.xdostime = xdostime;
+ this.dataOffset = dataOffset;
+ this.setExtra0(extra, false);
+ }
+
/**
* Creates a new zip entry with the specified name.
*
@@ -122,6 +122,9 @@
public ZipEntry(String name) {
Objects.requireNonNull(name, "name");
// Android-changed: Explicitly use UTF_8 instead of the default charset.
+ // if (name.length() > 0xFFFF) {
+ // throw new IllegalArgumentException("entry name too long");
+ // }
if (name.getBytes(StandardCharsets.UTF_8).length > 0xffff) {
throw new IllegalArgumentException(name + " too long: " +
name.getBytes(StandardCharsets.UTF_8).length);
@@ -152,6 +155,7 @@
flag = e.flag;
extra = e.extra;
comment = e.comment;
+ // Android-added: Add dataOffset for internal use.
dataOffset = e.dataOffset;
}
@@ -160,6 +164,7 @@
*/
ZipEntry() {}
+ // Android-added: Add dataOffset for internal use.
/** @hide */
public long getDataOffset() {
return dataOffset;
@@ -218,8 +223,6 @@
* @see #setLastModifiedTime(FileTime)
*/
public long getTime() {
- // Android-changed: Use xdostime, returning mtime would be a
- // functional difference
if (mtime != null) {
return mtime.toMillis();
}
@@ -573,18 +576,12 @@
* @see #getComment()
*/
public void setComment(String comment) {
- // Android-changed: Explicitly allow null comments (or allow comments to be
- // cleared).
- if (comment == null) {
- this.comment = null;
- return;
- }
-
- // Android-changed: Explicitly use UTF-8.
- if (comment.getBytes(StandardCharsets.UTF_8).length > 0xffff) {
+ // BEGIN Android-added: Explicitly use UTF_8 instead of the default charset.
+ if (comment != null && comment.getBytes(StandardCharsets.UTF_8).length > 0xffff) {
throw new IllegalArgumentException(comment + " too long: " +
comment.getBytes(StandardCharsets.UTF_8).length);
}
+ // END Android-added: Explicitly use UTF_8 instead of the default charset.
this.comment = comment;
}
diff --git a/ojluni/src/main/java/java/util/zip/ZipFile.java b/ojluni/src/main/java/java/util/zip/ZipFile.java
index bc2e6cf..851aab1 100644
--- a/ojluni/src/main/java/java/util/zip/ZipFile.java
+++ b/ojluni/src/main/java/java/util/zip/ZipFile.java
@@ -62,19 +62,37 @@
*/
public
class ZipFile implements ZipConstants, Closeable {
- private long jzfile; // address of jzfile data
+ // Android-note: jzfile does not require @ReachabilitySensitive annotation.
+ // The @ReachabilitySensitive annotation is usually added to instance fields that references
+ // native data that is cleaned up when the instance becomes unreachable. Its presence ensures
+ // that the instance object is not finalized until the field is no longer used. Without it an
+ // instance could be finalized during execution of an instance method iff that method's this
+ // variable holds the last reference to the instance and the method had copied all the fields
+ // it needs out of the instance. That would release the native data, invalidating its reference
+ // and would cause serious problems if the method had taken a copy of that field and
+ // then called a native method that would try to use it.
+ //
+ // This field does not require the annotation because all usages of this field are enclosed
+ // within a synchronized(this) block and finalizing of the object referenced in a synchronized
+ // block is not allowed as that would release its monitor that is currently in use.
+ private long jzfile; // address of jzfile data
private final String name; // zip file name
private final int total; // total number of entries
private final boolean locsig; // if zip file starts with LOCSIG (usually true)
private volatile boolean closeRequested = false;
// Android-added: CloseGuard support
- // Not declared @ReachabilitySensitive, since all relevant methods, including finalize()
- // synchronize on this, preventing premature finalization.
private final CloseGuard guard = CloseGuard.get();
- // Android-changed, needed for alternative OPEN_DELETE implementation
- // that doesn't use unlink before closing the file.
+ // Android-added: Do not use unlink() to implement OPEN_DELETE.
+ // Upstream uses unlink() to cause the file name to be removed from the filesystem after it is
+ // opened but that does not work on fuse fs as it causes problems with lseek. Android simply
+ // keeps a reference to the File so that it can explicitly delete it during close.
+ //
+ // OpenJDK 9+181 has a pure Java implementation of ZipFile that does not use unlink() and
+ // instead does something very similar to what Android does. If Android adopts it then this
+ // patch can be dropped.
+ // See http://b/28950284 and http://b/28901232 for more details.
private final File fileToRemoveOnClose;
private static final int STORED = ZipEntry.STORED;
@@ -94,10 +112,27 @@
*/
public static final int OPEN_DELETE = 0x4;
+ // Android-removed: initIDs() not used on Android.
+ /*
+ static {
+ /* Zip library is loaded from System.initializeSystemClass *
+ initIDs();
+ }
+
+ private static native void initIDs();
+ */
+
private static final boolean usemmap;
static {
- // Android-changed: always use mmap.
+ // Android-changed: Always use mmap.
+ /*
+ // A system prpperty to disable mmap use to avoid vm crash when
+ // in-use zip file is accidently overwritten by others.
+ String prop = sun.misc.VM.getSavedProperty("sun.zip.disableMemoryMapping");
+ usemmap = (prop == null ||
+ !(prop.length() == 0 || prop.equalsIgnoreCase("true")));
+ */
usemmap = true;
}
@@ -207,51 +242,35 @@
throw new IllegalArgumentException("Illegal mode: 0x"+
Integer.toHexString(mode));
}
-
- // Android-changed: Error out early if the file is too short or non-existent.
- long length = file.length();
- if (length < ZipConstants.ENDHDR) {
- if (length == 0 && !file.exists()) {
- throw new FileNotFoundException("File doesn't exist: " + file);
- } else {
- throw new ZipException("File too short to be a zip file: " + file.length());
+ String name = file.getPath();
+ // Android-removed: SecurityManager is always null
+ /*
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkRead(name);
+ if ((mode & OPEN_DELETE) != 0) {
+ sm.checkDelete(name);
}
}
+ */
- // Android-changed, handle OPEN_DELETE case in #close().
+ // Android-added: Do not use unlink() to implement OPEN_DELETE.
fileToRemoveOnClose = ((mode & OPEN_DELETE) != 0) ? file : null;
- String name = file.getPath();
- // Android-changed: SecurityManager is always null
- // SecurityManager sm = System.getSecurityManager();
- // if (sm != null) {
- // sm.checkRead(name);
- // if ((mode & OPEN_DELETE) != 0) {
- // sm.checkDelete(name);
- // }
- // }
if (charset == null)
throw new NullPointerException("charset is null");
this.zc = ZipCoder.get(charset);
- // Android-changed: Skip perf counters
+ // Android-removed: Skip perf counters
// long t0 = System.nanoTime();
jzfile = open(name, mode, file.lastModified(), usemmap);
- // Android-changed: Skip perf counters
+ // Android-removed: Skip perf counters
// sun.misc.PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0);
// sun.misc.PerfCounter.getZipFileCount().increment();
this.name = name;
this.total = getTotal(jzfile);
this.locsig = startsWithLOC(jzfile);
- Enumeration<? extends ZipEntry> entries = entries();
-
+ // Android-added: CloseGuard support
guard.open("close");
-
- // Android-changed: Error out early if the zipfile has no entries.
- if (size() == 0 || !entries.hasMoreElements()) {
- close();
- throw new ZipException("No entries");
- }
-
}
/**
@@ -380,10 +399,16 @@
synchronized (this) {
ensureOpen();
if (!zc.isUTF8() && (entry.flag & EFS) != 0) {
- // Android-changed: addSlash set to true, android is fine with "/" at the end
+ // Android-changed: Find entry by name, falling back to name/ if cannot be found.
+ // Needed for ClassPathURLStreamHandler handling of URLs without trailing slashes.
+ // This was added as part of the work to move StrictJarFile from libcore to
+ // framework, see http://b/111293098 for more details.
+ // It should be possible to revert this after upgrading to OpenJDK 8u144 or above.
+ // jzentry = getEntry(jzfile, zc.getBytesUTF8(entry.name), false);
jzentry = getEntry(jzfile, zc.getBytesUTF8(entry.name), true);
} else {
- // Android-changed: addSlash set to true, android is fine with "/" at the end
+ // Android-changed: Find entry by name, falling back to name/ if cannot be found.
+ // jzentry = getEntry(jzfile, zc.getBytes(entry.name), false);
jzentry = getEntry(jzfile, zc.getBytes(entry.name), true);
}
if (jzentry == 0) {
@@ -401,6 +426,7 @@
// MORE: Compute good size for inflater stream:
long size = getEntrySize(jzentry) + 2; // Inflater likes a bit of slack
// Android-changed: Use 64k buffer size, performs better than 8k.
+ // See http://b/65491407.
// if (size > 65536) size = 8192;
if (size > 65536) size = 65536;
if (size <= 0) size = 4096;
@@ -642,32 +668,47 @@
public void close() throws IOException {
if (closeRequested)
return;
- guard.close();
+ // Android-added: CloseGuard support
+ if (guard != null) {
+ guard.close();
+ }
closeRequested = true;
synchronized (this) {
// Close streams, release their inflaters
- synchronized (streams) {
- if (false == streams.isEmpty()) {
- Map<InputStream, Inflater> copy = new HashMap<>(streams);
- streams.clear();
- for (Map.Entry<InputStream, Inflater> e : copy.entrySet()) {
- e.getKey().close();
- Inflater inf = e.getValue();
- if (inf != null) {
- inf.end();
+ // BEGIN Android-added: null field check to avoid NullPointerException during finalize.
+ // If the constructor threw an exception then the streams / inflaterCache fields can
+ // be null and close() can be called by the finalizer.
+ if (streams != null) {
+ // END Android-added: null field check to avoid NullPointerException during finalize.
+ synchronized (streams) {
+ if (false == streams.isEmpty()) {
+ Map<InputStream, Inflater> copy = new HashMap<>(streams);
+ streams.clear();
+ for (Map.Entry<InputStream, Inflater> e : copy.entrySet()) {
+ e.getKey().close();
+ Inflater inf = e.getValue();
+ if (inf != null) {
+ inf.end();
+ }
}
}
}
+ // BEGIN Android-added: null field check to avoid NullPointerException during finalize.
}
- // Release cached inflaters
- Inflater inf;
- synchronized (inflaterCache) {
- while (null != (inf = inflaterCache.poll())) {
- inf.end();
+ if (inflaterCache != null) {
+ // END Android-added: null field check to avoid NullPointerException during finalize.
+ // Release cached inflaters
+ Inflater inf;
+ synchronized (inflaterCache) {
+ while (null != (inf = inflaterCache.poll())) {
+ inf.end();
+ }
}
+ // BEGIN Android-added: null field check to avoid NullPointerException during finalize.
}
+ // END Android-added: null field check to avoid NullPointerException during finalize.
if (jzfile != 0) {
// Close the zip file
@@ -676,7 +717,7 @@
close(zf);
}
- // Android-changed, explicit delete for OPEN_DELETE ZipFile.
+ // Android-added: Do not use unlink() to implement OPEN_DELETE.
if (fileToRemoveOnClose != null) {
fileToRemoveOnClose.delete();
}
@@ -698,14 +739,11 @@
* @see java.util.zip.ZipFile#close()
*/
protected void finalize() throws IOException {
- // Android-note: finalize() won't be invoked while important instance methods are running.
- // Both those methods and this method synchronize on "this", ensuring reachability
- // until the monitor is released.
+ // Android-added: CloseGuard support
if (guard != null) {
guard.warnIfOpen();
}
-
- close(); // Synchronizes on "this".
+ close();
}
private static native void close(long jzfile);
@@ -745,8 +783,12 @@
}
public int read(byte b[], int off, int len) throws IOException {
- // Android-changed: Always throw an exception on read if the zipfile
- // has already been closed.
+ // Android-added: Always throw an exception when reading from closed zipfile.
+ // Required by the JavaDoc for InputStream.read(byte[], int, int). Upstream version
+ // 8u121-b13 is not compliant but that bug has been fixed in upstream version 9+181
+ // as part of a major change to switch to a pure Java implementation.
+ // See https://bugs.openjdk.java.net/browse/JDK-8145260 and
+ // https://bugs.openjdk.java.net/browse/JDK-8142508.
ensureOpenOrZipException();
synchronized (ZipFile.this) {
@@ -762,7 +804,8 @@
len = (int) rem;
}
- // Android-changed: Moved
+ // Android-removed: Always throw an exception when reading from closed zipfile.
+ // Moved to the start of the method.
//ensureOpenOrZipException();
len = ZipFile.read(ZipFile.this.jzfile, jzentry, pos, b,
off, len);
@@ -827,15 +870,33 @@
}
}
+ // Android-removed: Access startsWithLocHeader() directly.
+ /*
+ static {
+ sun.misc.SharedSecrets.setJavaUtilZipFileAccess(
+ new sun.misc.JavaUtilZipFileAccess() {
+ public boolean startsWithLocHeader(ZipFile zip) {
+ return zip.startsWithLocHeader();
+ }
+ }
+ );
+ }
+ */
+
/**
* Returns {@code true} if, and only if, the zip file begins with {@code
* LOCSIG}.
* @hide
*/
+ // Android-changed: Access startsWithLocHeader() directly.
+ // Make hidden public for use by sun.misc.URLClassPath
+ // private boolean startsWithLocHeader() {
public boolean startsWithLocHeader() {
return locsig;
}
+ // BEGIN Android-added: Provide access to underlying file descriptor for testing.
+ // See http://b/111148957 for background information.
/** @hide */
// @VisibleForTesting
public int getFileDescriptor() {
@@ -843,6 +904,7 @@
}
private static native int getFileDescriptor(long jzfile);
+ // END Android-added: Provide access to underlying file descriptor for testing.
private static native long open(String name, int mode, long lastModified,
boolean usemmap) throws IOException;
diff --git a/ojluni/src/main/java/java/util/zip/ZipInputStream.java b/ojluni/src/main/java/java/util/zip/ZipInputStream.java
index cda8b81..0413f47 100644
--- a/ojluni/src/main/java/java/util/zip/ZipInputStream.java
+++ b/ojluni/src/main/java/java/util/zip/ZipInputStream.java
@@ -124,10 +124,12 @@
if ((entry = readLOC()) == null) {
return null;
}
- // BEGIN Android-changed
+ // Android-changed: Return more accurate value from available().
+ // Initialize the remaining field with the number of bytes that can be read from the entry
+ // for both uncompressed and compressed entries so that it can be used to provide a more
+ // accurate return value for available().
// if (entry.method == STORED) {
if (entry.method == STORED || entry.method == DEFLATED) {
- // END Android-changed
remaining = entry.size;
}
entryEOF = false;
@@ -159,10 +161,14 @@
*/
public int available() throws IOException {
ensureOpen();
- // BEGIN Android-changed
+ // Android-changed: Return more accurate value from available().
+ // Tracks the remaining bytes in order to return a more accurate value for the available
+ // bytes. Given an entry of size N both Android and upstream will return 1 until N bytes
+ // have been read at which point Android will return 0 and upstream will return 1.
+ // Upstream will only return 0 after an attempt to read a byte fails because the EOF has
+ // been reached. See http://b/111439440 for more details.
// if (entryEOF) {
if (entryEOF || (entry != null && remaining == 0)) {
- // END Android-changed
return 0;
} else {
return 1;
@@ -206,9 +212,10 @@
entry = null;
} else {
crc.update(b, off, len);
- // BEGIN Android-changed
+ // Android-added: Return more accurate value from available().
+ // Update the remaining field so it is an accurate count of the number of bytes
+ // remaining in this stream, after deflation.
remaining -= len;
- // END Android-changed
}
return len;
case STORED:
diff --git a/ojluni/src/main/java/java/util/zip/ZipOutputStream.java b/ojluni/src/main/java/java/util/zip/ZipOutputStream.java
index b4ac81d..dd005ec 100644
--- a/ojluni/src/main/java/java/util/zip/ZipOutputStream.java
+++ b/ojluni/src/main/java/java/util/zip/ZipOutputStream.java
@@ -53,7 +53,7 @@
* total entry count fields, such as the ones in jdk6, and even
* some in jdk7.
*/
- // Android-changed: Force to false.
+ // Android-changed: Always allow use of Zip64.
private static final boolean inhibitZip64 = false;
// Boolean.parseBoolean(
// java.security.AccessController.doPrivileged(
@@ -358,10 +358,6 @@
if (finished) {
return;
}
- // Android-changed: Fix for ZipOutputStreamTest#testCreateEmpty
- if (xentries.isEmpty()) {
- throw new ZipException("No entries");
- }
if (current != null) {
closeEntry();
}
diff --git a/ojluni/src/main/java/javax/crypto/JceSecurity.java b/ojluni/src/main/java/javax/crypto/JceSecurity.java
index 4572627..b0ae07e 100644
--- a/ojluni/src/main/java/javax/crypto/JceSecurity.java
+++ b/ojluni/src/main/java/javax/crypto/JceSecurity.java
@@ -218,7 +218,7 @@
static {
try {
- NULL_URL = new URL("http://null.oracle.com/");
+ NULL_URL = new URL("http://null.sun.com/");
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -255,69 +255,14 @@
// BEGIN Android-removed: JCE crypto strength restrictions are never in place on Android.
/*
- * This is called from within an doPrivileged block.
- *
- * Following logic is used to decide what policy files are selected.
- *
- * If the new Security property (crypto.policy) is set in the
- * java.security file, or has been set dynamically using the
- * Security.setProperty() call before the JCE framework has
- * been initialized, that setting will be used.
- * Remember - this property is not defined by default. A conscious
- * user edit or an application call is required.
- *
- * Otherwise, if user has policy jar files installed in the legacy
- * jre/lib/security/ directory, the JDK will honor whatever
- * setting is set by those policy files. (legacy/current behavior)
- *
- * If none of the above 2 conditions are met, the JDK will default
- * to using the limited crypto policy files found in the
- * jre/lib/security/policy/limited/ directory
- *
private static void setupJurisdictionPolicies() throws Exception {
- // Sanity check the crypto.policy Security property. Single
- // directory entry, no pseudo-directories (".", "..", leading/trailing
- // path separators). normalize()/getParent() will help later.
- String javaHomeProperty = System.getProperty("java.home");
- String cryptoPolicyProperty = Security.getProperty("crypto.policy");
- Path cpPath = (cryptoPolicyProperty == null) ? null :
- Paths.get(cryptoPolicyProperty);
+ String javaHomeDir = System.getProperty("java.home");
+ String sep = File.separator;
+ String pathToPolicyJar = javaHomeDir + sep + "lib" + sep +
+ "security" + sep;
- if ((cpPath != null) && ((cpPath.getNameCount() != 1) ||
- (cpPath.compareTo(cpPath.getFileName())) != 0)) {
- throw new SecurityException(
- "Invalid policy directory name format: " +
- cryptoPolicyProperty);
- }
-
- if (cpPath == null) {
- // Security property is not set, use default path
- cpPath = Paths.get(javaHomeProperty, "lib", "security");
- } else {
- // populate with java.home
- cpPath = Paths.get(javaHomeProperty, "lib", "security",
- "policy", cryptoPolicyProperty);
- }
-
- if (debug != null) {
- debug.println("crypto policy directory: " + cpPath);
- }
-
- File exportJar = new File(cpPath.toFile(),"US_export_policy.jar");
- File importJar = new File(cpPath.toFile(),"local_policy.jar");
-
- if (cryptoPolicyProperty == null && (!exportJar.exists() ||
- !importJar.exists())) {
- // Compatibility set up. If crypto.policy is not defined.
- // check to see if legacy jars exist in lib directory. If
- // they don't exist, we default to limited policy mode.
- cpPath = Paths.get(
- javaHomeProperty, "lib", "security", "policy", "limited");
- // point to the new jar files in limited directory
- exportJar = new File(cpPath.toFile(),"US_export_policy.jar");
- importJar = new File(cpPath.toFile(),"local_policy.jar");
- }
-
+ File exportJar = new File(pathToPolicyJar, "US_export_policy.jar");
+ File importJar = new File(pathToPolicyJar, "local_policy.jar");
URL jceCipherURL = ClassLoader.getSystemResource
("javax/crypto/Cipher.class");
diff --git a/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java b/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
index ec4254a..58e3591 100644
--- a/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
+++ b/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
@@ -178,7 +178,7 @@
}
}
- // BEGIN Android-changed: Use lazily-created OkHttp hostname verifier
+ // BEGIN Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
// The RI default hostname verifier is a static member of the class, which means
// it's created when the class is initialized. As well, its default verifier
// just fails all verification attempts, whereas we use OkHttp's verifier.
@@ -211,7 +211,7 @@
* The <code>hostnameVerifier</code> for this object.
*/
protected HostnameVerifier hostnameVerifier;
- // END Android-changed: Use lazily-created OkHttp hostname verifier
+ // END Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
/**
* Sets the default <code>HostnameVerifier</code> inherited by a
@@ -239,6 +239,8 @@
if (sm != null) {
sm.checkPermission(new SSLPermission("setHostnameVerifier"));
}
+ // Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
+ // defaultHostnameVerifier = v;
NoPreloadHolder.defaultHostnameVerifier = v;
}
@@ -250,6 +252,8 @@
* @see #setDefaultHostnameVerifier(HostnameVerifier)
*/
public static HostnameVerifier getDefaultHostnameVerifier() {
+ // Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
+ // return defaultHostnameVerifier;
return NoPreloadHolder.defaultHostnameVerifier;
}
@@ -284,7 +288,12 @@
* @see #setDefaultHostnameVerifier(HostnameVerifier)
*/
public HostnameVerifier getHostnameVerifier() {
- // Android-added: Use the default verifier if none is set
+ // Android-added: Use the default verifier if none is set.
+ // Note that this also has the side effect of *setting* (if unset)
+ // hostnameVerifier to be the default one. It's not clear why this
+ // was done (commit abd00f0eaa46f71f98e75a631c268c812d1ec7c1) but
+ // we're keeping this behavior for lack of a strong reason to do
+ // otherwise.
if (hostnameVerifier == null) {
hostnameVerifier = NoPreloadHolder.defaultHostnameVerifier;
}
@@ -358,6 +367,9 @@
* @param sf the SSL socket factory
* @throws IllegalArgumentException if the <code>SSLSocketFactory</code>
* parameter is null.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkSetFactory</code> method does not allow
+ * a socket factory to be specified.
* @see #getSSLSocketFactory()
*/
public void setSSLSocketFactory(SSLSocketFactory sf) {
diff --git a/ojluni/src/main/java/javax/security/auth/callback/Callback.java b/ojluni/src/main/java/javax/security/auth/callback/Callback.java
index 83855ca..d95c87f1 100644
--- a/ojluni/src/main/java/javax/security/auth/callback/Callback.java
+++ b/ojluni/src/main/java/javax/security/auth/callback/Callback.java
@@ -26,6 +26,13 @@
package javax.security.auth.callback;
+// Android-changed: Removed @see tags (targets do not exist on Android):
+// @see javax.security.auth.callback.ChoiceCallback
+// @see javax.security.auth.callback.ConfirmationCallback
+// @see javax.security.auth.callback.LanguageCallback
+// @see javax.security.auth.callback.NameCallback
+// @see javax.security.auth.callback.TextInputCallback
+// @see javax.security.auth.callback.TextOutputCallback
/**
* <p> Implementations of this interface are passed to a
* {@code CallbackHandler}, allowing underlying security services
@@ -41,12 +48,6 @@
* underlying security services.
*
* @see javax.security.auth.callback.CallbackHandler
- * @see javax.security.auth.callback.ChoiceCallback
- * @see javax.security.auth.callback.ConfirmationCallback
- * @see javax.security.auth.callback.LanguageCallback
- * @see javax.security.auth.callback.NameCallback
* @see javax.security.auth.callback.PasswordCallback
- * @see javax.security.auth.callback.TextInputCallback
- * @see javax.security.auth.callback.TextOutputCallback
*/
public interface Callback { }
diff --git a/ojluni/src/main/java/javax/security/auth/login/LoginException.java b/ojluni/src/main/java/javax/security/auth/login/LoginException.java
index 75eedec..c8fa8cb 100644
--- a/ojluni/src/main/java/javax/security/auth/login/LoginException.java
+++ b/ojluni/src/main/java/javax/security/auth/login/LoginException.java
@@ -25,10 +25,10 @@
package javax.security.auth.login;
+// Android-changed: Removed @see tag (target does not exist on Android):
+// @see javax.security.auth.login.LoginContext
/**
* This is the basic login exception.
- *
- * @see javax.security.auth.login.LoginContext
*/
public class LoginException extends java.security.GeneralSecurityException {
diff --git a/ojluni/src/main/java/jdk/net/ExtendedSocketOptions.java b/ojluni/src/main/java/jdk/net/ExtendedSocketOptions.java
index 73c67d8..644fc4d 100644
--- a/ojluni/src/main/java/jdk/net/ExtendedSocketOptions.java
+++ b/ojluni/src/main/java/jdk/net/ExtendedSocketOptions.java
@@ -32,7 +32,8 @@
* {@link java.net.StandardSocketOptions}. These options may be platform
* specific.
*/
-//@jdk.Exported
+// Android-removed: @jdk.Exported, not present on Android.
+// @jdk.Exported
public final class ExtendedSocketOptions {
private static class ExtSocketOption<T> implements SocketOption<T> {
diff --git a/ojluni/src/main/java/jdk/net/NetworkPermission.java b/ojluni/src/main/java/jdk/net/NetworkPermission.java
index 96d7a8e..b102571 100644
--- a/ojluni/src/main/java/jdk/net/NetworkPermission.java
+++ b/ojluni/src/main/java/jdk/net/NetworkPermission.java
@@ -32,8 +32,8 @@
/**
* Legacy security code; do not use.
*/
-
-//@jdk.Exported
+// Android-removed: @jdk.Exported, not present on Android.
+// @jdk.Exported
public final class NetworkPermission extends BasicPermission {
public NetworkPermission(String name) {
diff --git a/ojluni/src/main/java/jdk/net/SocketFlow.java b/ojluni/src/main/java/jdk/net/SocketFlow.java
index a8ca749..59875a8 100644
--- a/ojluni/src/main/java/jdk/net/SocketFlow.java
+++ b/ojluni/src/main/java/jdk/net/SocketFlow.java
@@ -43,7 +43,8 @@
* When a security manager is installed, a {@link NetworkPermission}
* is required to set or get this option.
*/
-//@jdk.Exported
+// Android-removed: @jdk.Exported, not present on Android.
+// @jdk.Exported
public class SocketFlow {
private static final int UNSET = -1;
@@ -64,7 +65,8 @@
* one of these statuses, which reflect the state of socket's
* flow.
*/
-// @jdk.Exported
+ // Android-removed: @jdk.Exported, not present on Android.
+ // @jdk.Exported
public enum Status {
/**
* Set or get socket option has not been called yet. Status
diff --git a/ojluni/src/main/java/jdk/net/Sockets.java b/ojluni/src/main/java/jdk/net/Sockets.java
index 1187eb3..197a905 100644
--- a/ojluni/src/main/java/jdk/net/Sockets.java
+++ b/ojluni/src/main/java/jdk/net/Sockets.java
@@ -55,7 +55,8 @@
*
* @see java.nio.channels.NetworkChannel
*/
-//@jdk.Exported
+// Android-removed: @jdk.Exported, not present on Android.
+// @jdk.Exported
public class Sockets {
private final static HashMap<Class<?>,Set<SocketOption<?>>>
diff --git a/ojluni/src/main/java/sun/invoke/util/VerifyAccess.java b/ojluni/src/main/java/sun/invoke/util/VerifyAccess.java
index 94c401f..6ce6fcf 100644
--- a/ojluni/src/main/java/sun/invoke/util/VerifyAccess.java
+++ b/ojluni/src/main/java/sun/invoke/util/VerifyAccess.java
@@ -185,29 +185,75 @@
return false;
}
+ // Android-removed: Unused method.
+ /*
/**
* Decide if the given method type, attributed to a member or symbolic
* reference of a given reference class, is really visible to that class.
* @param type the supposed type of a member or symbolic reference of refc
* @param refc the class attempting to make the reference
- */
+ *
public static boolean isTypeVisible(Class<?> type, Class<?> refc) {
- if (type == refc) return true; // easy check
+ if (type == refc) {
+ return true; // easy check
+ }
while (type.isArray()) type = type.getComponentType();
- if (type.isPrimitive() || type == Object.class) return true;
- ClassLoader parent = type.getClassLoader();
- if (parent == null) return true;
- ClassLoader child = refc.getClassLoader();
- if (child == null) return false;
- if (parent == child || loadersAreRelated(parent, child, true))
+ if (type.isPrimitive() || type == Object.class) {
return true;
- // Do it the hard way: Look up the type name from the refc loader.
- try {
- Class<?> res = child.loadClass(type.getName());
- return (type == res);
- } catch (ClassNotFoundException ex) {
+ }
+ ClassLoader typeLoader = type.getClassLoader();
+ ClassLoader refcLoader = refc.getClassLoader();
+ if (typeLoader == refcLoader) {
+ return true;
+ }
+ if (refcLoader == null && typeLoader != null) {
return false;
}
+ if (typeLoader == null && type.getName().startsWith("java.")) {
+ // Note: The API for actually loading classes, ClassLoader.defineClass,
+ // guarantees that classes with names beginning "java." cannot be aliased,
+ // because class loaders cannot load them directly.
+ return true;
+ }
+
+ // Do it the hard way: Look up the type name from the refc loader.
+ //
+ // Force the refc loader to report and commit to a particular binding for this type name (type.getName()).
+ //
+ // In principle, this query might force the loader to load some unrelated class,
+ // which would cause this query to fail (and the original caller to give up).
+ // This would be wasted effort, but it is expected to be very rare, occurring
+ // only when an attacker is attempting to create a type alias.
+ // In the normal case, one class loader will simply delegate to the other,
+ // and the same type will be visible through both, with no extra loading.
+ //
+ // It is important to go through Class.forName instead of ClassLoader.loadClass
+ // because Class.forName goes through the JVM system dictionary, which records
+ // the class lookup once for all. This means that even if a not-well-behaved class loader
+ // would "change its mind" about the meaning of the name, the Class.forName request
+ // will use the result cached in the JVM system dictionary. Note that the JVM system dictionary
+ // will record the first successful result. Unsuccessful results are not stored.
+ //
+ // We use doPrivileged in order to allow an unprivileged caller to ask an arbitrary
+ // class loader about the binding of the proposed name (type.getName()).
+ // The looked up type ("res") is compared for equality against the proposed
+ // type ("type") and then is discarded. Thus, the worst that can happen to
+ // the "child" class loader is that it is bothered to load and report a class
+ // that differs from "type"; this happens once due to JVM system dictionary
+ // memoization. And the caller never gets to look at the alternate type binding
+ // ("res"), whether it exists or not.
+ final String name = type.getName();
+ Class<?> res = java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Class>() {
+ public Class<?> run() {
+ try {
+ return Class.forName(name, false, refcLoader);
+ } catch (ClassNotFoundException | LinkageError e) {
+ return null; // Assume the class is not found
+ }
+ }
+ });
+ return (type == res);
}
/**
@@ -215,7 +261,7 @@
* reference of a given reference class, is really visible to that class.
* @param type the supposed type of a member or symbolic reference of refc
* @param refc the class attempting to make the reference
- */
+ *
public static boolean isTypeVisible(java.lang.invoke.MethodType type, Class<?> refc) {
for (int n = -1, max = type.parameterCount(); n < max; n++) {
Class<?> ptype = (n < 0 ? type.returnType() : type.parameterType(n));
@@ -224,6 +270,7 @@
}
return true;
}
+ */
/**
* Test if two classes have the same class loader and package qualifier.
@@ -253,8 +300,10 @@
return true;
}
+ // Android-removed: Unused method.
+ /*
/** Return the package name for this class.
- */
+ *
public static String getPackageName(Class<?> cls) {
assert(!cls.isArray());
String name = cls.getName();
@@ -262,6 +311,7 @@
if (dot < 0) return "";
return name.substring(0, dot);
}
+ */
/**
* Test if two classes are defined as part of the same package member (top-level class).
@@ -287,6 +337,8 @@
return pkgmem;
}
+ // Android-removed: Unused method.
+ /*
private static boolean loadersAreRelated(ClassLoader loader1, ClassLoader loader2,
boolean loader1MustBeParent) {
if (loader1 == loader2 || loader1 == null
@@ -305,15 +357,19 @@
}
return false;
}
+ */
+ // Android-removed: Unused method.
+ /*
/**
* Is the class loader of parentClass identical to, or an ancestor of,
* the class loader of childClass?
* @param parentClass a class
* @param childClass another class, which may be a descendent of the first class
* @return whether parentClass precedes or equals childClass in class loader order
- */
+ *
public static boolean classLoaderIsAncestor(Class<?> parentClass, Class<?> childClass) {
return loadersAreRelated(parentClass.getClassLoader(), childClass.getClassLoader(), true);
}
+ */
}
diff --git a/ojluni/src/main/java/sun/misc/SharedSecrets.java b/ojluni/src/main/java/sun/misc/SharedSecrets.java
index d21aa4d..45cd489 100644
--- a/ojluni/src/main/java/sun/misc/SharedSecrets.java
+++ b/ojluni/src/main/java/sun/misc/SharedSecrets.java
@@ -35,15 +35,191 @@
for this purpose, namely the loss of compile-time checking. */
public class SharedSecrets {
- // BEGIN Android-changed: Pruned unused access interfaces
+ // BEGIN Android-removed: Pruned unused access interfaces
+ /*
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static JavaUtilJarAccess javaUtilJarAccess;
+ private static JavaLangAccess javaLangAccess;
+ private static JavaLangRefAccess javaLangRefAccess;
+ private static JavaIOAccess javaIOAccess;
+ private static JavaNetAccess javaNetAccess;
+ private static JavaNetHttpCookieAccess javaNetHttpCookieAccess;
+ private static JavaNioAccess javaNioAccess;
+ */
+ // END Android-removed: Pruned unused access interfaces
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
+ // BEGIN Android-removed: Pruned unused access interfaces
+ /*
+ private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess;
+ private static JavaSecurityAccess javaSecurityAccess;
+ private static JavaUtilZipFileAccess javaUtilZipFileAccess;
+ private static JavaAWTAccess javaAWTAccess;
+ private static JavaOISAccess javaOISAccess;
+ private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
+
+ public static JavaUtilJarAccess javaUtilJarAccess() {
+ if (javaUtilJarAccess == null) {
+ // Ensure JarFile is initialized; we know that that class
+ // provides the shared secret
+ unsafe.ensureClassInitialized(JarFile.class);
+ }
+ return javaUtilJarAccess;
+ }
+
+ public static void setJavaUtilJarAccess(JavaUtilJarAccess access) {
+ javaUtilJarAccess = access;
+ }
+
+ public static void setJavaLangAccess(JavaLangAccess jla) {
+ javaLangAccess = jla;
+ }
+
+ public static JavaLangAccess getJavaLangAccess() {
+ return javaLangAccess;
+ }
+
+ public static void setJavaLangRefAccess(JavaLangRefAccess jlra) {
+ javaLangRefAccess = jlra;
+ }
+
+ public static JavaLangRefAccess getJavaLangRefAccess() {
+ return javaLangRefAccess;
+ }
+
+ public static void setJavaNetAccess(JavaNetAccess jna) {
+ javaNetAccess = jna;
+ }
+
+ public static JavaNetAccess getJavaNetAccess() {
+ return javaNetAccess;
+ }
+
+ public static void setJavaNetHttpCookieAccess(JavaNetHttpCookieAccess a) {
+ javaNetHttpCookieAccess = a;
+ }
+
+ public static JavaNetHttpCookieAccess getJavaNetHttpCookieAccess() {
+ if (javaNetHttpCookieAccess == null)
+ unsafe.ensureClassInitialized(java.net.HttpCookie.class);
+ return javaNetHttpCookieAccess;
+ }
+
+ public static void setJavaNioAccess(JavaNioAccess jna) {
+ javaNioAccess = jna;
+ }
+
+ public static JavaNioAccess getJavaNioAccess() {
+ if (javaNioAccess == null) {
+ // Ensure java.nio.ByteOrder is initialized; we know that
+ // this class initializes java.nio.Bits that provides the
+ // shared secret.
+ unsafe.ensureClassInitialized(java.nio.ByteOrder.class);
+ }
+ return javaNioAccess;
+ }
+
+ public static void setJavaIOAccess(JavaIOAccess jia) {
+ javaIOAccess = jia;
+ }
+
+ public static JavaIOAccess getJavaIOAccess() {
+ if (javaIOAccess == null) {
+ unsafe.ensureClassInitialized(Console.class);
+ }
+ return javaIOAccess;
+ }
+ */
+ // END Android-removed: Pruned unused access interfaces
public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) {
javaIOFileDescriptorAccess = jiofda;
}
public static JavaIOFileDescriptorAccess getJavaIOFileDescriptorAccess() {
+ // Android-changed: ensureClassInitialized isn't supported in Android. Use Class.forName.
+ // if (javaIOFileDescriptorAccess == null)
+ // unsafe.ensureClassInitialized(FileDescriptor.class);
+ if (javaIOFileDescriptorAccess == null) {
+ try {
+ Class.forName("java.io.FileDescriptor");
+ } catch (ClassNotFoundException e) {
+ // Throw if FileDescriptor class is not found. Something wrong in runtime / libcore.
+ throw new RuntimeException(e);
+ }
+ }
return javaIOFileDescriptorAccess;
}
- // END Android-changed: Pruned unused access interfaces
+
+ // BEGIN Android-removed: Pruned unused access interfaces
+ /*
+ public static void setJavaOISAccess(JavaOISAccess access) {
+ javaOISAccess = access;
+ }
+
+ public static JavaOISAccess getJavaOISAccess() {
+ if (javaOISAccess == null)
+ unsafe.ensureClassInitialized(ObjectInputStream.class);
+
+ return javaOISAccess;
+ }
+
+
+ public static void setJavaSecurityProtectionDomainAccess
+ (JavaSecurityProtectionDomainAccess jspda) {
+ javaSecurityProtectionDomainAccess = jspda;
+ }
+
+ public static JavaSecurityProtectionDomainAccess
+ getJavaSecurityProtectionDomainAccess() {
+ if (javaSecurityProtectionDomainAccess == null)
+ unsafe.ensureClassInitialized(ProtectionDomain.class);
+ return javaSecurityProtectionDomainAccess;
+ }
+
+ public static void setJavaSecurityAccess(JavaSecurityAccess jsa) {
+ javaSecurityAccess = jsa;
+ }
+
+ public static JavaSecurityAccess getJavaSecurityAccess() {
+ if (javaSecurityAccess == null) {
+ unsafe.ensureClassInitialized(AccessController.class);
+ }
+ return javaSecurityAccess;
+ }
+
+ public static JavaUtilZipFileAccess getJavaUtilZipFileAccess() {
+ if (javaUtilZipFileAccess == null)
+ unsafe.ensureClassInitialized(java.util.zip.ZipFile.class);
+ return javaUtilZipFileAccess;
+ }
+
+ public static void setJavaUtilZipFileAccess(JavaUtilZipFileAccess access) {
+ javaUtilZipFileAccess = access;
+ }
+
+ public static void setJavaAWTAccess(JavaAWTAccess jaa) {
+ javaAWTAccess = jaa;
+ }
+
+ public static JavaAWTAccess getJavaAWTAccess() {
+ // this may return null in which case calling code needs to
+ // provision for.
+ if (javaAWTAccess == null) {
+ return null;
+ }
+ return javaAWTAccess;
+ }
+
+ public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
+ if (javaObjectInputStreamAccess == null) {
+ unsafe.ensureClassInitialized(ObjectInputStream.class);
+ }
+ return javaObjectInputStreamAccess;
+ }
+
+ public static void setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess access) {
+ javaObjectInputStreamAccess = access;
+ }
+ */
+ // END Android-removed: Pruned unused access interfaces
}
diff --git a/ojluni/src/main/java/sun/misc/Unsafe.java b/ojluni/src/main/java/sun/misc/Unsafe.java
index c9ba16e..aaa9e70 100644
--- a/ojluni/src/main/java/sun/misc/Unsafe.java
+++ b/ojluni/src/main/java/sun/misc/Unsafe.java
@@ -26,7 +26,8 @@
package sun.misc;
import dalvik.annotation.optimization.FastNative;
-import dalvik.system.VMStack;
+import sun.reflect.Reflection;
+
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -55,11 +56,12 @@
* very limited situations.
*/
public static Unsafe getUnsafe() {
+ Class<?> caller = Reflection.getCallerClass();
/*
* Only code on the bootclasspath is allowed to get at the
* Unsafe instance.
*/
- ClassLoader calling = VMStack.getCallingClassLoader();
+ ClassLoader calling = (caller == null) ? null : caller.getClassLoader();
if ((calling != null) && (calling != Unsafe.class.getClassLoader())) {
throw new SecurityException("Unsafe access denied");
}
diff --git a/ojluni/src/main/java/sun/net/ftp/impl/FtpClient.java b/ojluni/src/main/java/sun/net/ftp/impl/FtpClient.java
index 0c117d4..da2a739 100644
--- a/ojluni/src/main/java/sun/net/ftp/impl/FtpClient.java
+++ b/ojluni/src/main/java/sun/net/ftp/impl/FtpClient.java
@@ -517,6 +517,10 @@
* @return <code>true</code> if the command was successful
* @throws IOException
*/
+ // Android-changed: Integrate upstream fix to guard against '\n'.
+ // Integrates OpenJDK's "8170222: Better transfers of files".
+ // See http://b/35784677 .
+ // private boolean issueCommand(String cmd) throws IOException {
private boolean issueCommand(String cmd) throws IOException,
sun.net.ftp.FtpProtocolException {
if (!isConnected()) {
@@ -529,12 +533,14 @@
// ignore...
}
}
+ // BEGIN Android-added: Integrate upstream fix to guard against '\n'.
if (cmd.indexOf('\n') != -1) {
sun.net.ftp.FtpProtocolException ex
= new sun.net.ftp.FtpProtocolException("Illegal FTP command");
ex.initCause(new IllegalArgumentException("Illegal carriage return"));
throw ex;
}
+ // END Android-added: Integrate upstream fix to guard against '\n'.
sendServer(cmd + "\r\n");
return readReply();
}
diff --git a/ojluni/src/main/java/sun/net/spi/DefaultProxySelector.java b/ojluni/src/main/java/sun/net/spi/DefaultProxySelector.java
index fac57e2..2fc7fd1 100644
--- a/ojluni/src/main/java/sun/net/spi/DefaultProxySelector.java
+++ b/ojluni/src/main/java/sun/net/spi/DefaultProxySelector.java
@@ -117,7 +117,9 @@
* basis, and change it only when the "source", i.e. the system property,
* did change.
*/
-
+ // Android-note: Integrated some upstream changes from beyond OpenJDK8u121-b13.
+ // This includes NonProxyInfo.pattern -> hostsPool and associated changes.
+ // See http://b/62368386
static class NonProxyInfo {
// Default value for nonProxyHosts, this provides backward compatibility
// by excluding localhost and its litteral notations.
diff --git a/ojluni/src/main/java/sun/net/spi/nameservice/NameService.java b/ojluni/src/main/java/sun/net/spi/nameservice/NameService.java
index 6fbd4ff..4191ef4 100644
--- a/ojluni/src/main/java/sun/net/spi/nameservice/NameService.java
+++ b/ojluni/src/main/java/sun/net/spi/nameservice/NameService.java
@@ -28,6 +28,9 @@
import java.net.UnknownHostException;
public interface NameService {
+ // Android-changed: Support for network (netId)-specific DNS resolution.
+ // For use by frameworks/base's android.net.Network.
+ // public java.net.InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException;
public java.net.InetAddress[] lookupAllHostAddr(String host, int netId) throws UnknownHostException;
public String getHostByAddr(byte[] addr) throws UnknownHostException;
}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/jar/JarURLConnection.java b/ojluni/src/main/java/sun/net/www/protocol/jar/JarURLConnection.java
index d7c4424..b0aa959 100644
--- a/ojluni/src/main/java/sun/net/www/protocol/jar/JarURLConnection.java
+++ b/ojluni/src/main/java/sun/net/www/protocol/jar/JarURLConnection.java
@@ -125,8 +125,12 @@
* to get the jarFile, and set it as our permission.
*/
if (getUseCaches()) {
+ // Android-added: Upstream fix to avoid affecting useCaches setting.
+ // This line and the one further down were integrated from an
+ // upstream commit beyond OpenJDK 8u121-b13. See http://b/62368386
boolean oldUseCaches = jarFileURLConnection.getUseCaches();
jarFileURLConnection = factory.getConnection(jarFile);
+ // Android-added: Upstream fix to avoid affecting useCaches setting.
jarFileURLConnection.setUseCaches(oldUseCaches);
}
diff --git a/ojluni/src/main/java/sun/nio/ch/ChannelInputStream.java b/ojluni/src/main/java/sun/nio/ch/ChannelInputStream.java
index b629517..e2f8092 100644
--- a/ojluni/src/main/java/sun/nio/ch/ChannelInputStream.java
+++ b/ojluni/src/main/java/sun/nio/ch/ChannelInputStream.java
@@ -29,6 +29,7 @@
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
+import java.nio.channels.spi.*;
/**
@@ -44,13 +45,8 @@
extends InputStream
{
- // Android-changed: This code didn't make sense. In particular, the block channel is
- // useless because we throw if the channel is non-blocking!. It would only make sense
- // if it's called on a blocking channel (but we're asked to make it non-blocking before
- // the read) we never do that, though.
- //
- // read(ReadableByteChannel,ByteBuffer, boolean block)
- public static int read(ReadableByteChannel ch, ByteBuffer bb)
+ public static int read(ReadableByteChannel ch, ByteBuffer bb,
+ boolean block)
throws IOException
{
if (ch instanceof SelectableChannel) {
@@ -59,13 +55,11 @@
boolean bm = sc.isBlocking();
if (!bm)
throw new IllegalBlockingModeException();
- // Android-removed.
- // if (bm != block)
- // sc.configureBlocking(block);
+ if (bm != block)
+ sc.configureBlocking(block);
int n = ch.read(bb);
- // Android-removed.
- // if (bm != block)
- // sc.configureBlocking(bm);
+ if (bm != block)
+ sc.configureBlocking(bm);
return n;
}
} else {
@@ -113,7 +107,7 @@
protected int read(ByteBuffer bb)
throws IOException
{
- return ChannelInputStream.read(ch, bb);
+ return ChannelInputStream.read(ch, bb, true);
}
public int available() throws IOException {
diff --git a/ojluni/src/main/java/sun/nio/ch/DatagramChannelImpl.java b/ojluni/src/main/java/sun/nio/ch/DatagramChannelImpl.java
index 0338f01..49ad55c 100644
--- a/ojluni/src/main/java/sun/nio/ch/DatagramChannelImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/DatagramChannelImpl.java
@@ -28,36 +28,17 @@
import java.io.FileDescriptor;
import java.io.IOException;
-import java.net.DatagramSocket;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.NetworkInterface;
-import java.net.PortUnreachableException;
-import java.net.ProtocolFamily;
-import java.net.SocketAddress;
-import java.net.SocketOption;
-import java.net.StandardProtocolFamily;
-import java.net.StandardSocketOptions;
+import java.net.*;
import java.nio.ByteBuffer;
-import java.nio.channels.AlreadyBoundException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.DatagramChannel;
-import java.nio.channels.MembershipKey;
-import java.nio.channels.NotYetConnectedException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.UnsupportedAddressTypeException;
-import java.nio.channels.spi.SelectorProvider;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
+import java.nio.channels.*;
+import java.nio.channels.spi.*;
+import java.util.*;
import dalvik.annotation.optimization.ReachabilitySensitive;
import dalvik.system.BlockGuard;
import dalvik.system.CloseGuard;
-import sun.net.ExtendedOptionsImpl;
import sun.net.ResourceManager;
+import sun.net.ExtendedOptionsImpl;
/**
* An implementation of DatagramChannels.
@@ -72,9 +53,10 @@
private static NativeDispatcher nd = new DatagramDispatcher();
// Our file descriptor
- // Android-changed: Make the fd package visible so that we can expose it through DatagramSocketAdaptor.
// Android-added: @ReachabilitySensitive.
@ReachabilitySensitive
+ // Android-changed: Make the fd visible for DatagramSocketAdaptor.
+ // private final FileDescriptor fd;
final FileDescriptor fd;
// fd value needed for dev/poll. This value will remain valid
@@ -146,7 +128,6 @@
this.fdVal = IOUtil.fdVal(fd);
this.state = ST_UNCONNECTED;
// Android-added: CloseGuard support.
- // Net#socket will set |fd| if it succeeds.
if (fd != null && fd.valid()) {
guard.open("close");
}
@@ -178,7 +159,6 @@
this.fdVal = IOUtil.fdVal(fd);
this.state = ST_UNCONNECTED;
// Android-added: CloseGuard support.
- // Net#socket will set |fd| if it succeeds.
if (fd != null && fd.valid()) {
guard.open("close");
}
@@ -371,15 +351,13 @@
throw new IllegalArgumentException("Read-only buffer");
if (dst == null)
throw new NullPointerException();
- // Android-changed: Do not attempt to bind to 0 (or 0.0.0.0) if there hasn't been
- // an explicit call to bind() yet. Fail fast and return null.
- if (localAddress == null)
- return null;
synchronized (readLock) {
ensureOpen();
// Socket was not bound before attempting receive
- // if (localAddress() == null)
+ // Android-changed: Do not implicitly to bind to 0 (or 0.0.0.0), return null instead.
+ if (localAddress() == null)
// bind(null);
+ return null;
int n = 0;
ByteBuffer bb = null;
try {
@@ -445,6 +423,7 @@
int newSize = Math.max(rem, 1);
ByteBuffer bb = Util.getTemporaryDirectBuffer(newSize);
try {
+ // Android-added: BlockGuard support.
BlockGuard.getThreadPolicy().onNetwork();
int n = receiveIntoNativeBuffer(fd, bb, newSize, 0);
@@ -508,6 +487,7 @@
if (!isOpen())
return 0;
writerThread = NativeThread.current();
+ // Android-added: BlockGuard support.
BlockGuard.getThreadPolicy().onNetwork();
do {
@@ -1090,9 +1070,15 @@
}
}
+ // BEGIN Android-changed: Add CloseGuard support and call superclass finalizer.
+ /*
+ protected void finalize() throws IOException {
+ // fd is null if constructor threw exception
+ if (fd != null)
+ close();
+ */
protected void finalize() throws Throwable {
try {
- // Android-added: CloseGuard support.
if (guard != null) {
guard.warnIfOpen();
}
@@ -1102,6 +1088,7 @@
} finally {
super.finalize();
}
+ // END Android-changed: Add CloseGuard support and call superclass finalizer.
}
/**
@@ -1208,6 +1195,8 @@
throws IOException;
static {
+ // Android removed: Native code initialization not required.
+ // IOUtil.load();
initIDs();
}
diff --git a/ojluni/src/main/java/sun/nio/ch/DatagramDispatcher.java b/ojluni/src/main/java/sun/nio/ch/DatagramDispatcher.java
index 328e4ee..d012534 100644
--- a/ojluni/src/main/java/sun/nio/ch/DatagramDispatcher.java
+++ b/ojluni/src/main/java/sun/nio/ch/DatagramDispatcher.java
@@ -37,22 +37,31 @@
class DatagramDispatcher extends NativeDispatcher
{
+ // Android-removed: Native code initialization not required.
+ // static {
+ // IOUtil.load();
+ // }
+
int read(FileDescriptor fd, long address, int len) throws IOException {
+ // Android-added: BlockGuard support.
BlockGuard.getThreadPolicy().onNetwork();
return read0(fd, address, len);
}
long readv(FileDescriptor fd, long address, int len) throws IOException {
+ // Android-added: BlockGuard support.
BlockGuard.getThreadPolicy().onNetwork();
return readv0(fd, address, len);
}
int write(FileDescriptor fd, long address, int len) throws IOException {
+ // Android-added: BlockGuard support.
BlockGuard.getThreadPolicy().onNetwork();
return write0(fd, address, len);
}
long writev(FileDescriptor fd, long address, int len) throws IOException {
+ // Android-added: BlockGuard support.
BlockGuard.getThreadPolicy().onNetwork();
return writev0(fd, address, len);
}
diff --git a/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java b/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
index d752d1a..a32356f 100644
--- a/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
@@ -105,10 +105,11 @@
this.parent = parent;
this.path = path;
this.nd = new FileDispatcherImpl(append);
- // Android-added: CloseGuard support.
+ // BEGIN Android-added: CloseGuard support.
if (fd != null && fd.valid()) {
guard.open("close");
}
+ // END Android-added: CloseGuard support.
}
// Used by FileInputStream.getChannel() and RandomAccessFile.getChannel()
@@ -167,6 +168,7 @@
}
+ // BEGIN Android-added: CloseGuard support.
protected void finalize() throws Throwable {
try {
if (guard != null) {
@@ -177,6 +179,7 @@
super.finalize();
}
}
+ // END Android-added: CloseGuard support.
public int read(ByteBuffer dst) throws IOException {
ensureOpen();
@@ -294,9 +297,13 @@
ti = threads.add();
if (!isOpen())
return 0;
+ // BEGIN Android-added: BlockGuard support.
+ // Note: position() itself doesn't seem to block, so this may be overzealous
+ // when position() is not followed by a read/write operation. http://b/77263638
if (append) {
BlockGuard.getThreadPolicy().onWriteToDisk();
}
+ // END Android-added: BlockGuard support.
do {
// in append-mode then position is advanced to end before writing
p = (append) ? nd.size(fd) : position0(fd, -1);
@@ -322,6 +329,9 @@
ti = threads.add();
if (!isOpen())
return null;
+ // Android-added: BlockGuard support.
+ // Note: position() itself doesn't seem to block, so this may be overzealous
+ // when position() is not followed by a read/write operation. http://b/77263638
BlockGuard.getThreadPolicy().onReadFromDisk();
do {
p = position0(fd, newPosition);
@@ -367,6 +377,7 @@
int rv = -1;
long p = -1;
int ti = -1;
+ long rp = -1;
try {
begin();
ti = threads.add();
@@ -402,8 +413,8 @@
if (p > newSize)
p = newSize;
do {
- rv = (int)position0(fd, p);
- } while ((rv == IOStatus.INTERRUPTED) && isOpen());
+ rp = position0(fd, p);
+ } while ((rp == IOStatus.INTERRUPTED) && isOpen());
return this;
} finally {
threads.remove(ti);
@@ -462,6 +473,7 @@
ti = threads.add();
if (!isOpen())
return -1;
+ // Android-added: BlockGuard support.
BlockGuard.getThreadPolicy().onWriteToDisk();
do {
n = transferTo0(fd, position, icount, targetFD);
@@ -936,35 +948,13 @@
return null;
if (filesize < position + size) { // Extend file size
- // BEGIN Android-changed
- /*
if (!writable) {
throw new IOException("Channel not open for writing " +
"- cannot extend file to required size");
}
- */
- // END Android-changed
- int rv = 0;
+ int rv;
do {
- // BEGIN Android-changed
- //int rv = nd.truncate(fd, position + size);
- try {
- rv = nd.truncate(fd, position + size);
- } catch (IOException r) {
- try {
- // If we're dealing with non-regular files, for example,
- // character devices such as /dev/zero. In those
- // cases, we ignore the failed truncation and continue
- // on.
- if (android.system.OsConstants.S_ISREG(Libcore.os.fstat(fd).st_mode)) {
- throw r;
- }
- } catch (ErrnoException e) {
- e.rethrowAsIOException();
- }
- break;
- }
- // END Android-changed
+ rv = nd.truncate(fd, position + size);
} while ((rv == IOStatus.INTERRUPTED) && isOpen());
if (!isOpen())
return null;
@@ -973,6 +963,13 @@
addr = 0;
// a valid file descriptor is not required
FileDescriptor dummy = new FileDescriptor();
+ // Android-changed: Allocate a DirectByteBuffer directly.
+ /*
+ if ((!writable) || (imode == MAP_RO))
+ return Util.newMappedByteBufferR(0, 0, dummy, null);
+ else
+ return Util.newMappedByteBuffer(0, 0, dummy, null);
+ */
return new DirectByteBuffer(0, 0, dummy, null,
(!writable) || (imode == MAP_RO) /* readOnly */);
}
@@ -981,8 +978,9 @@
long mapPosition = position - pagePosition;
long mapSize = size + pagePosition;
try {
- // If no exception was thrown from map0, the address is valid
+ // Android-added: BlockGuard support.
BlockGuard.getThreadPolicy().onReadFromDisk();
+ // If no exception was thrown from map0, the address is valid
addr = map0(imode, mapPosition, mapSize);
} catch (OutOfMemoryError x) {
// An OutOfMemoryError may indicate that we've exhausted memory
@@ -1015,6 +1013,20 @@
assert (addr % allocationGranularity == 0);
int isize = (int)size;
Unmapper um = new Unmapper(addr, mapSize, isize, mfd);
+ // Android-changed: Allocate a DirectByteBuffer directly.
+ /*
+ if ((!writable) || (imode == MAP_RO)) {
+ return Util.newMappedByteBufferR(isize,
+ addr + pagePosition,
+ mfd,
+ um);
+ } else {
+ return Util.newMappedByteBuffer(isize,
+ addr + pagePosition,
+ mfd,
+ um);
+ }
+ */
return new DirectByteBuffer(isize, addr + pagePosition, mfd, um,
(!writable) || (imode == MAP_RO));
} finally {
@@ -1023,8 +1035,38 @@
}
}
+ // Android-removed: Unused method getMappedBufferPool().
+ /*
+ /**
+ * Invoked by sun.management.ManagementFactoryHelper to create the management
+ * interface for mapped buffers.
+ *
+ public static sun.misc.JavaNioAccess.BufferPool getMappedBufferPool() {
+ return new sun.misc.JavaNioAccess.BufferPool() {
+ @Override
+ public String getName() {
+ return "mapped";
+ }
+ @Override
+ public long getCount() {
+ return Unmapper.count;
+ }
+ @Override
+ public long getTotalCapacity() {
+ return Unmapper.totalCapacity;
+ }
+ @Override
+ public long getMemoryUsed() {
+ return Unmapper.totalSize;
+ }
+ };
+ }
+ */
+
// -- Locks --
+
+
// keeps track of locks on this file
private volatile FileLockTable fileLockTable;
@@ -1245,6 +1287,8 @@
private static native long initIDs();
static {
+ // Android-removed: Move clinit code to JNI registration functions.
+ // IOUtil.load();
allocationGranularity = initIDs();
}
diff --git a/ojluni/src/main/java/sun/nio/ch/FileDescriptorHolderSocketImpl.java b/ojluni/src/main/java/sun/nio/ch/FileDescriptorHolderSocketImpl.java
index d7a9fc6..852b738 100644
--- a/ojluni/src/main/java/sun/nio/ch/FileDescriptorHolderSocketImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/FileDescriptorHolderSocketImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
*
* 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
diff --git a/ojluni/src/main/java/sun/nio/ch/PollSelectorImpl.java b/ojluni/src/main/java/sun/nio/ch/PollSelectorImpl.java
index 17c9f03..1911c35 100644
--- a/ojluni/src/main/java/sun/nio/ch/PollSelectorImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/PollSelectorImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -57,9 +57,23 @@
long pipeFds = IOUtil.makePipe(false);
fd0 = (int) (pipeFds >>> 32);
fd1 = (int) pipeFds;
- pollWrapper = new PollArrayWrapper(INIT_CAP);
- pollWrapper.initInterrupt(fd0, fd1);
- channelArray = new SelectionKeyImpl[INIT_CAP];
+ try {
+ pollWrapper = new PollArrayWrapper(INIT_CAP);
+ pollWrapper.initInterrupt(fd0, fd1);
+ channelArray = new SelectionKeyImpl[INIT_CAP];
+ } catch (Throwable t) {
+ try {
+ FileDispatcherImpl.closeIntFD(fd0);
+ } catch (IOException ioe0) {
+ t.addSuppressed(ioe0);
+ }
+ try {
+ FileDispatcherImpl.closeIntFD(fd1);
+ } catch (IOException ioe1) {
+ t.addSuppressed(ioe1);
+ }
+ throw t;
+ }
}
protected int doSelect(long timeout)
diff --git a/ojluni/src/main/java/sun/nio/ch/PollSelectorProvider.java b/ojluni/src/main/java/sun/nio/ch/PollSelectorProvider.java
index 9ea18c9..d4ce6a1 100644
--- a/ojluni/src/main/java/sun/nio/ch/PollSelectorProvider.java
+++ b/ojluni/src/main/java/sun/nio/ch/PollSelectorProvider.java
@@ -36,8 +36,9 @@
return new PollSelectorImpl(this);
}
- // Android-changed: Android never has stdin/stdout connected to a socket.
- // public Channel inheritedChannel() throws IOException {
- // return InheritedChannel.getChannel();
- // }
+ public Channel inheritedChannel() throws IOException {
+ // Android-changed: Android never has stdin/stdout connected to a socket.
+ // return InheritedChannel.getChannel();
+ return null;
+ }
}
diff --git a/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java b/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
index a2aba2d..d07134f 100644
--- a/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
+++ b/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
@@ -27,11 +27,13 @@
package sun.nio.ch;
import java.io.*;
+import java.lang.ref.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
+import java.util.*;
// Make a socket channel look like a socket.
@@ -57,6 +59,7 @@
private volatile int timeout = 0;
private SocketAdaptor(SocketChannelImpl sc) throws SocketException {
+ // Android-changed: Conscrypt compatibility, ensure fd is not null. http://b/25857624
super(new FileDescriptorHolderSocketImpl(sc.getFD()));
this.sc = sc;
}
@@ -92,7 +95,8 @@
try {
if (timeout == 0) {
- // Android-changed: Be consistent
+ // Android-changed: Translate exceptions consistently.
+ // sc.connect(remote);
try {
sc.connect(remote);
} catch (Exception ex) {
@@ -144,8 +148,7 @@
}
public InetAddress getInetAddress() {
- // Use #remoteAddress and do manual isConnected check. #getRemoteAddress() returns
- // non-null result before connection.
+ // Android-changed: remoteAddress() returns non-null before connection. http://b/26140820
if (!isConnected()) {
return null;
}
@@ -168,8 +171,7 @@
}
public int getPort() {
- // Use #remoteAddress and do manual isConnected check. #getRemoteAddress() returns
- // non-null result before connection.
+ // Android-changed: remoteAddress() returns non-null before connection. http://b/26140820
if (!isConnected()) {
return 0;
}
diff --git a/ojluni/src/main/java/sun/nio/ch/SocketOptionRegistry.java b/ojluni/src/main/java/sun/nio/ch/SocketOptionRegistry.java
index f660f9d..6c53b09 100644
--- a/ojluni/src/main/java/sun/nio/ch/SocketOptionRegistry.java
+++ b/ojluni/src/main/java/sun/nio/ch/SocketOptionRegistry.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -57,7 +57,7 @@
static final Map<RegistryKey,OptionKey> options = options();
private static Map<RegistryKey,OptionKey> options() {
Map<RegistryKey,OptionKey> map =
- new HashMap<RegistryKey,OptionKey>();
+ new HashMap<RegistryKey,OptionKey>();
map.put(new RegistryKey(StandardSocketOptions.SO_BROADCAST, Net.UNSPEC), new OptionKey(1, 6));
map.put(new RegistryKey(StandardSocketOptions.SO_KEEPALIVE, Net.UNSPEC), new OptionKey(1, 9));
map.put(new RegistryKey(StandardSocketOptions.SO_LINGER, Net.UNSPEC), new OptionKey(1, 13));
@@ -74,7 +74,7 @@
map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_TTL, StandardProtocolFamily.INET6), new OptionKey(41, 18));
map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_LOOP, StandardProtocolFamily.INET6), new OptionKey(41, 19));
map.put(new RegistryKey(ExtendedSocketOption.SO_OOBINLINE, Net.UNSPEC), new OptionKey(1, 10));
- return map;
+ return map;
}
}
public static OptionKey findOption(SocketOption<?> name, ProtocolFamily family) {
diff --git a/ojluni/src/main/java/sun/nio/ch/SourceChannelImpl.java b/ojluni/src/main/java/sun/nio/ch/SourceChannelImpl.java
index a80b540..759a60b 100644
--- a/ojluni/src/main/java/sun/nio/ch/SourceChannelImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/SourceChannelImpl.java
@@ -156,6 +156,7 @@
}
public int read(ByteBuffer dst) throws IOException {
+ // Android-added: Throw NPE if null ByteBuffer passed to read().
if (dst == null) {
throw new NullPointerException();
}
diff --git a/ojluni/src/main/java/sun/nio/ch/Util.java b/ojluni/src/main/java/sun/nio/ch/Util.java
index 6b82112..fa0b631 100644
--- a/ojluni/src/main/java/sun/nio/ch/Util.java
+++ b/ojluni/src/main/java/sun/nio/ch/Util.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -28,6 +28,7 @@
import java.nio.ByteBuffer;
import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.*;
import sun.misc.Unsafe;
import sun.misc.Cleaner;
@@ -41,6 +42,9 @@
// The number of temp buffers in our pool
private static final int TEMP_BUF_POOL_SIZE = IOUtil.IOV_MAX;
+ // The max size allowed for a cached temp buffer, in bytes
+ private static final long MAX_CACHED_BUFFER_SIZE = getMaxCachedBufferSize();
+
// Per-thread cache of temporary direct buffers
private static ThreadLocal<BufferCache> bufferCache =
new ThreadLocal<BufferCache>()
@@ -52,6 +56,52 @@
};
/**
+ * Returns the max size allowed for a cached temp buffers, in
+ * bytes. It defaults to Long.MAX_VALUE. It can be set with the
+ * jdk.nio.maxCachedBufferSize property. Even though
+ * ByteBuffer.capacity() returns an int, we're using a long here
+ * for potential future-proofing.
+ */
+ private static long getMaxCachedBufferSize() {
+ String s = java.security.AccessController.doPrivileged(
+ new PrivilegedAction<String>() {
+ @Override
+ public String run() {
+ return System.getProperty("jdk.nio.maxCachedBufferSize");
+ }
+ });
+ if (s != null) {
+ try {
+ long m = Long.parseLong(s);
+ if (m >= 0) {
+ return m;
+ } else {
+ // if it's negative, ignore the system property
+ }
+ } catch (NumberFormatException e) {
+ // if the string is not well formed, ignore the system property
+ }
+ }
+ return Long.MAX_VALUE;
+ }
+
+ /**
+ * Returns true if a buffer of this size is too large to be
+ * added to the buffer cache, false otherwise.
+ */
+ private static boolean isBufferTooLarge(int size) {
+ return size > MAX_CACHED_BUFFER_SIZE;
+ }
+
+ /**
+ * Returns true if the buffer is too large to be added to the
+ * buffer cache, false otherwise.
+ */
+ private static boolean isBufferTooLarge(ByteBuffer buf) {
+ return isBufferTooLarge(buf.capacity());
+ }
+
+ /**
* A simple cache of direct buffers.
*/
private static class BufferCache {
@@ -77,6 +127,9 @@
* size (or null if no suitable buffer is found).
*/
ByteBuffer get(int size) {
+ // Don't call this if the buffer would be too large.
+ assert !isBufferTooLarge(size);
+
if (count == 0)
return null; // cache is empty
@@ -114,6 +167,9 @@
}
boolean offerFirst(ByteBuffer buf) {
+ // Don't call this if the buffer is too large.
+ assert !isBufferTooLarge(buf);
+
if (count >= TEMP_BUF_POOL_SIZE) {
return false;
} else {
@@ -125,6 +181,9 @@
}
boolean offerLast(ByteBuffer buf) {
+ // Don't call this if the buffer is too large.
+ assert !isBufferTooLarge(buf);
+
if (count >= TEMP_BUF_POOL_SIZE) {
return false;
} else {
@@ -153,6 +212,15 @@
* Returns a temporary buffer of at least the given size
*/
public static ByteBuffer getTemporaryDirectBuffer(int size) {
+ // If a buffer of this size is too large for the cache, there
+ // should not be a buffer in the cache that is at least as
+ // large. So we'll just create a new one. Also, we don't have
+ // to remove the buffer from the cache (as this method does
+ // below) given that we won't put the new buffer in the cache.
+ if (isBufferTooLarge(size)) {
+ return ByteBuffer.allocateDirect(size);
+ }
+
BufferCache cache = bufferCache.get();
ByteBuffer buf = cache.get(size);
if (buf != null) {
@@ -182,6 +250,13 @@
* likely to be returned by a subsequent call to getTemporaryDirectBuffer.
*/
static void offerFirstTemporaryDirectBuffer(ByteBuffer buf) {
+ // If the buffer is too large for the cache we don't have to
+ // check the cache. We'll just free it.
+ if (isBufferTooLarge(buf)) {
+ free(buf);
+ return;
+ }
+
assert buf != null;
BufferCache cache = bufferCache.get();
if (!cache.offerFirst(buf)) {
@@ -197,6 +272,13 @@
* cache in same order that they were obtained.
*/
static void offerLastTemporaryDirectBuffer(ByteBuffer buf) {
+ // If the buffer is too large for the cache we don't have to
+ // check the cache. We'll just free it.
+ if (isBufferTooLarge(buf)) {
+ free(buf);
+ return;
+ }
+
assert buf != null;
BufferCache cache = bufferCache.get();
if (!cache.offerLast(buf)) {
@@ -209,6 +291,8 @@
* Frees the memory for the given direct buffer
*/
private static void free(ByteBuffer buf) {
+ // Android-changed: Add null check for cleaner. http://b/26040655
+ // ((DirectBuffer)buf).cleaner().clean();
Cleaner cleaner = ((DirectBuffer)buf).cleaner();
if (cleaner != null) {
cleaner.clean();
@@ -284,6 +368,8 @@
return unsafe;
}
+ // BEGIN Android-removed: DirectByteBuffer is @hide public on Android so reflection unneeded.
+ /*
private static int pageSize = -1;
static int pageSize() {
@@ -292,7 +378,100 @@
return pageSize;
}
+ private static volatile Constructor<?> directByteBufferConstructor = null;
+
+ private static void initDBBConstructor() {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ try {
+ Class<?> cl = Class.forName("java.nio.DirectByteBuffer");
+ Constructor<?> ctor = cl.getDeclaredConstructor(
+ new Class<?>[] { int.class,
+ long.class,
+ FileDescriptor.class,
+ Runnable.class });
+ ctor.setAccessible(true);
+ directByteBufferConstructor = ctor;
+ } catch (ClassNotFoundException |
+ NoSuchMethodException |
+ IllegalArgumentException |
+ ClassCastException x) {
+ throw new InternalError(x);
+ }
+ return null;
+ }});
+ }
+
+ static MappedByteBuffer newMappedByteBuffer(int size, long addr,
+ FileDescriptor fd,
+ Runnable unmapper)
+ {
+ MappedByteBuffer dbb;
+ if (directByteBufferConstructor == null)
+ initDBBConstructor();
+ try {
+ dbb = (MappedByteBuffer)directByteBufferConstructor.newInstance(
+ new Object[] { new Integer(size),
+ new Long(addr),
+ fd,
+ unmapper });
+ } catch (InstantiationException |
+ IllegalAccessException |
+ InvocationTargetException e) {
+ throw new InternalError(e);
+ }
+ return dbb;
+ }
+
+ private static volatile Constructor<?> directByteBufferRConstructor = null;
+
+ private static void initDBBRConstructor() {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ try {
+ Class<?> cl = Class.forName("java.nio.DirectByteBufferR");
+ Constructor<?> ctor = cl.getDeclaredConstructor(
+ new Class<?>[] { int.class,
+ long.class,
+ FileDescriptor.class,
+ Runnable.class });
+ ctor.setAccessible(true);
+ directByteBufferRConstructor = ctor;
+ } catch (ClassNotFoundException |
+ NoSuchMethodException |
+ IllegalArgumentException |
+ ClassCastException x) {
+ throw new InternalError(x);
+ }
+ return null;
+ }});
+ }
+
+ static MappedByteBuffer newMappedByteBufferR(int size, long addr,
+ FileDescriptor fd,
+ Runnable unmapper)
+ {
+ MappedByteBuffer dbb;
+ if (directByteBufferRConstructor == null)
+ initDBBRConstructor();
+ try {
+ dbb = (MappedByteBuffer)directByteBufferRConstructor.newInstance(
+ new Object[] { new Integer(size),
+ new Long(addr),
+ fd,
+ unmapper });
+ } catch (InstantiationException |
+ IllegalAccessException |
+ InvocationTargetException e) {
+ throw new InternalError(e);
+ }
+ return dbb;
+ }
+ */
+ // END Android-removed: DirectByteBuffer is @hide public on Android so reflection unneeded.
+
// -- Bug compatibility --
+
private static volatile String bugLevel = null;
static boolean atBugLevel(String bl) { // package-private
diff --git a/ojluni/src/main/java/sun/nio/cs/StreamDecoder.java b/ojluni/src/main/java/sun/nio/cs/StreamDecoder.java
index 3cdf45b..8a2335e 100644
--- a/ojluni/src/main/java/sun/nio/cs/StreamDecoder.java
+++ b/ojluni/src/main/java/sun/nio/cs/StreamDecoder.java
@@ -54,6 +54,7 @@
private boolean haveLeftoverChar = false;
private char leftoverChar;
+ // Android-added: Flush the CharsetDecoder correctly.
private boolean needsFlush = false;
// Factories for java.io.InputStreamReader
@@ -273,9 +274,11 @@
try {
if (ch != null) {
// Read from the channel
- // Android-changed: Use ChannelInputStream.read to make sure we throw
- // the right exception for non-blocking channels.
- int n = sun.nio.ch.ChannelInputStream.read(ch, bb);
+ // Android-changed: Use ChannelInputStream.read which throws on non-blocking channels.
+ // Other implementations of ReadableByteChannel.read do not, and Channels.newReader
+ // is documented to throw on non-blocking.
+ // int n = ch.read(bb);
+ int n = sun.nio.ch.ChannelInputStream.read(ch, bb, true);
if (n < 0)
return n;
} else {
@@ -317,7 +320,7 @@
// Ensure that cb[0] == cbuf[off]
cb = cb.slice();
- // Android-changed: Support flushing the buffer properly.
+ // BEGIN Android-added: Flush the CharsetDecoder correctly.
if (needsFlush) {
CoderResult cr = decoder.flush(cb);
if (cr.isOverflow()) {
@@ -337,6 +340,7 @@
cr.throwException();
// Unreachable.
}
+ // END Android-added: Flush the CharsetDecoder properly.
boolean eof = false;
for (;;) {
@@ -351,10 +355,10 @@
int n = readBytes();
if (n < 0) {
eof = true;
- // Android-changed: We want to go 'round the loop one more time
- // with "eof = true". We also don't want to reset the decoder here
- // because we might potentially need to flush it later.
- //
+ // Android-removed: Flush the CharsetDecoder correctly.
+ // We want to go 'round the loop one more time with "eof = true".
+ // We also don't want to reset the decoder here because we might potentially need
+ // to flush it later.
// if ((cb.position() == 0) && (!bb.hasRemaining()))
// break;
// decoder.reset();
@@ -369,6 +373,9 @@
}
if (eof) {
+ // BEGIN Android-changed: Flush the CharsetDecoder correctly.
+ // // ## Need to flush decoder
+ // decoder.reset();
CoderResult cr = decoder.flush(cb);
if (cr.isOverflow()) {
needsFlush = true;
@@ -379,6 +386,7 @@
if (!cr.isUnderflow()) {
cr.throwException();
}
+ // END Android-changed: Flush the CharsetDecoder correctly.
}
if (cb.position() == 0) {
diff --git a/ojluni/src/main/java/sun/nio/fs/LinuxUserDefinedFileAttributeView.java b/ojluni/src/main/java/sun/nio/fs/LinuxUserDefinedFileAttributeView.java
index 44f7d16..a395370 100644
--- a/ojluni/src/main/java/sun/nio/fs/LinuxUserDefinedFileAttributeView.java
+++ b/ojluni/src/main/java/sun/nio/fs/LinuxUserDefinedFileAttributeView.java
@@ -70,10 +70,9 @@
if (unsafe.getByte(address + pos) == 0) {
int len = pos - start;
byte[] value = new byte[len];
+ // Android-changed: We don't have Unsafe.copyMemory yet, so we use getByte.
// unsafe.copyMemory(null, address+start, value,
// Unsafe.ARRAY_BYTE_BASE_OFFSET, len);
-
- // Android-changed: We don't have Unsafe.copyMemory yet, so we use getByte.
for (int i = 0; i < len; i++) {
value[i] = unsafe.getByte(address + start + i);
}
diff --git a/ojluni/src/main/java/sun/nio/fs/LinuxWatchService.java b/ojluni/src/main/java/sun/nio/fs/LinuxWatchService.java
index 5044045..db61c8d 100644
--- a/ojluni/src/main/java/sun/nio/fs/LinuxWatchService.java
+++ b/ojluni/src/main/java/sun/nio/fs/LinuxWatchService.java
@@ -25,25 +25,18 @@
package sun.nio.fs;
+import java.nio.file.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
import java.io.IOException;
-import java.nio.file.NotDirectoryException;
-import java.nio.file.Path;
-import java.nio.file.StandardWatchEventKinds;
-import java.nio.file.WatchEvent;
-import java.nio.file.WatchKey;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
import dalvik.annotation.optimization.ReachabilitySensitive;
import dalvik.system.CloseGuard;
import sun.misc.Unsafe;
-import static sun.nio.fs.UnixConstants.EAGAIN;
-import static sun.nio.fs.UnixConstants.EMFILE;
-import static sun.nio.fs.UnixConstants.ENOSPC;
-import static sun.nio.fs.UnixNativeDispatcher.read;
-import static sun.nio.fs.UnixNativeDispatcher.write;
+import static sun.nio.fs.UnixNativeDispatcher.*;
+import static sun.nio.fs.UnixConstants.*;
/**
* Linux implementation of WatchService based on inotify.
@@ -388,14 +381,13 @@
}
if (actual > 0) {
byte[] buf = new byte[actual];
+ // BEGIN Android-changed: Use Unsafe.getByte not Unsafe.copyMemory.
// unsafe.copyMemory(null, event + OFFSETOF_NAME,
// buf, Unsafe.ARRAY_BYTE_BASE_OFFSET, actual);
-
- // Android-changed: We don't have Unsafe.copyMemory yet, so we use
- // getByte.
for(int i = 0; i < actual; i++) {
buf[i] = unsafe.getByte(event + OFFSETOF_NAME + i);
}
+ // END Android-changed: Use Unsafe.getByte not Unsafe.copyMemory.
name = new UnixPath(fs, buf);
}
}
diff --git a/ojluni/src/main/java/sun/nio/fs/MimeTypesFileTypeDetector.java b/ojluni/src/main/java/sun/nio/fs/MimeTypesFileTypeDetector.java
index 1815239..1c8f708 100644
--- a/ojluni/src/main/java/sun/nio/fs/MimeTypesFileTypeDetector.java
+++ b/ojluni/src/main/java/sun/nio/fs/MimeTypesFileTypeDetector.java
@@ -25,7 +25,18 @@
package sun.nio.fs;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
import java.nio.file.Path;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import libcore.net.MimeUtils;
/**
@@ -35,6 +46,24 @@
class MimeTypesFileTypeDetector extends AbstractFileTypeDetector {
+ // BEGIN Android-removed: Delegate to libcore.net.MimeUtils.
+ /*
+ // path to mime.types file
+ private final Path mimeTypesFile;
+
+ // map of extension to MIME type
+ private Map<String,String> mimeTypeMap;
+
+ // set to true when file loaded
+ private volatile boolean loaded = false;
+
+ public MimeTypesFileTypeDetector(Path filePath) {
+ mimeTypesFile = filePath;
+ }
+ */
+ // END Android-removed: Delegate to libcore.net.MimeUtils.
+
+
@Override
protected String implProbeContentType(Path path) {
Path fn = path.getFileName();
@@ -45,10 +74,18 @@
if (ext.isEmpty())
return null; // no extension
+ // Android-removed: Delegate to libcore.net.MimeUtils.
+ // loadMimeTypes();
+ // if (mimeTypeMap == null || mimeTypeMap.isEmpty())
+ // return null;
+
// Case-sensitive search
String mimeType;
do {
+ // BEGIN Android-changed: Delegate to libcore.net.MimeUtils.
+ // mimeType = mimeTypeMap.get(ext);
mimeType = MimeUtils.guessMimeTypeFromExtension(ext);
+ // END Android-changed: Delegate to libcore.net.MimeUtils.
if (mimeType == null)
ext = getExtension(ext);
} while (mimeType == null && !ext.isEmpty());
@@ -67,4 +104,119 @@
}
return ext;
}
+
+ // BEGIN Android-removed: Delegate to libcore.net.MimeUtils.
+ /*
+ /**
+ * Parse the mime types file, and store the type-extension mappings into
+ * mimeTypeMap. The mime types file is not loaded until the first probe
+ * to achieve the lazy initialization. It adopts double-checked locking
+ * optimization to reduce the locking overhead.
+ *
+ private void loadMimeTypes() {
+ if (!loaded) {
+ synchronized (this) {
+ if (!loaded) {
+ List<String> lines = AccessController.doPrivileged(
+ new PrivilegedAction<List<String>>() {
+ @Override
+ public List<String> run() {
+ try {
+ return Files.readAllLines(mimeTypesFile,
+ Charset.defaultCharset());
+ } catch (IOException ignore) {
+ return Collections.emptyList();
+ }
+ }
+ });
+
+ mimeTypeMap = new HashMap<>(lines.size());
+ String entry = "";
+ for (String line : lines) {
+ entry += line;
+ if (entry.endsWith("\\")) {
+ entry = entry.substring(0, entry.length() - 1);
+ continue;
+ }
+ parseMimeEntry(entry);
+ entry = "";
+ }
+ if (!entry.isEmpty()) {
+ parseMimeEntry(entry);
+ }
+ loaded = true;
+ }
+ }
+ }
+ }
+
+ /**
+ * Parse a mime-types entry, which can have the following formats.
+ * 1) Simple space-delimited format
+ * image/jpeg jpeg jpg jpe JPG
+ *
+ * 2) Netscape key-value pair format
+ * type=application/x-java-jnlp-file desc="Java Web Start" exts="jnlp"
+ * or
+ * type=text/html exts=htm,html
+ *
+ private void parseMimeEntry(String entry) {
+ entry = entry.trim();
+ if (entry.isEmpty() || entry.charAt(0) == '#')
+ return;
+
+ entry = entry.replaceAll("\\s*#.*", "");
+ int equalIdx = entry.indexOf('=');
+ if (equalIdx > 0) {
+ // Parse a mime-types command having the key-value pair format
+ final String TYPEEQUAL = "type=";
+ String typeRegex = "\\b" + TYPEEQUAL +
+ "(\"\\p{Graph}+?/\\p{Graph}+?\"|\\p{Graph}+/\\p{Graph}+\\b)";
+ Pattern typePattern = Pattern.compile(typeRegex);
+ Matcher typeMatcher = typePattern.matcher(entry);
+
+ if (typeMatcher.find()) {
+ String type = typeMatcher.group().substring(TYPEEQUAL.length());
+ if (type.charAt(0) == '"') {
+ type = type.substring(1, type.length() - 1);
+ }
+
+ final String EXTEQUAL = "exts=";
+ String extRegex = "\\b" + EXTEQUAL +
+ "(\"[\\p{Graph}\\p{Blank}]+?\"|\\p{Graph}+\\b)";
+ Pattern extPattern = Pattern.compile(extRegex);
+ Matcher extMatcher = extPattern.matcher(entry);
+
+ if (extMatcher.find()) {
+ String exts =
+ extMatcher.group().substring(EXTEQUAL.length());
+ if (exts.charAt(0) == '"') {
+ exts = exts.substring(1, exts.length() - 1);
+ }
+ String[] extList = exts.split("[\\p{Blank}\\p{Punct}]+");
+ for (String ext : extList) {
+ putIfAbsent(ext, type);
+ }
+ }
+ }
+ } else {
+ // Parse a mime-types command having the space-delimited format
+ String[] elements = entry.split("\\s+");
+ int i = 1;
+ while (i < elements.length) {
+ putIfAbsent(elements[i++], elements[0]);
+ }
+ }
+ }
+
+ private void putIfAbsent(String key, String value) {
+ if (key != null && !key.isEmpty() &&
+ value != null && !value.isEmpty() &&
+ !mimeTypeMap.containsKey(key))
+ {
+ mimeTypeMap.put(key, value);
+ }
+ }
+ */
+ // END Android-removed: Delegate to libcore.net.MimeUtils.
}
diff --git a/ojluni/src/main/java/sun/nio/fs/NativeBuffers.java b/ojluni/src/main/java/sun/nio/fs/NativeBuffers.java
index ee6969c..dcdfdf2 100644
--- a/ojluni/src/main/java/sun/nio/fs/NativeBuffers.java
+++ b/ojluni/src/main/java/sun/nio/fs/NativeBuffers.java
@@ -121,18 +121,17 @@
* Copies a byte array and zero terminator into a given native buffer.
*/
static void copyCStringToNativeBuffer(byte[] cstr, NativeBuffer buffer) {
+ // Android-removed: We don't have Unsafe.copyMemory yet, so use putByte.
// long offset = Unsafe.ARRAY_BYTE_BASE_OFFSET;
- // long len = cstr.length;
- // assert buffer.size() >= (len + 1);
- // unsafe.copyMemory(cstr, offset, null, buffer.address(), len);
- // unsafe.putByte(buffer.address() + len, (byte)0);
- // Android-changed: We don't have Unsafe.copyMemory yet, so we use putByte.
long len = cstr.length;
assert buffer.size() >= (len + 1);
+ // BEGIN Android-changed: We don't have Unsafe.copyMemory yet, so use putByte.
+ // unsafe.copyMemory(cstr, offset, null, buffer.address(), len);
for (int i = 0; i < len; ++i) {
unsafe.putByte(buffer.address() + i, cstr[i]);
}
+ // END Android-changed: We don't have Unsafe.copyMemory yet, so use putByte.
unsafe.putByte(buffer.address() + len, (byte)0);
}
diff --git a/ojluni/src/main/java/sun/nio/fs/UnixConstants.java b/ojluni/src/main/java/sun/nio/fs/UnixConstants.java
index a6d3bbd..d197ee2 100644
--- a/ojluni/src/main/java/sun/nio/fs/UnixConstants.java
+++ b/ojluni/src/main/java/sun/nio/fs/UnixConstants.java
@@ -27,22 +27,15 @@
// AUTOMATICALLY GENERATED FILE - DO NOT EDIT
package sun.nio.fs;
+// BEGIN Android-changed: Use constants from android.system.OsConstants. http://b/32203242
+// Those constants are initialized by native code to ensure correctness on different architectures.
+// AT_SYMLINK_NOFOLLOW (used by fstatat) and AT_REMOVEDIR (used by unlinkat) as of July 2018 do not
+// have equivalents in android.system.OsConstants so left unchanged.
import android.system.OsConstants;
-import java.io.ObjectStreamClass;
-
class UnixConstants {
+ private UnixConstants() { }
- private UnixConstants() {
- }
-
- // Android-changed (http://b/32203242): Instead of maintaining a separate set of UnixConstants,
- // use the values from android.system.OsConstants. AT_SYMLINK_NOFOLLOW is used by fstatat when
- // a symbolic link is passed. With AT_SYMLINK_NOLLOW, it doesn't dereference and instead return
- // information about the link, and with it, returns the information about the target. There is
- // no suitable alternative for the flag in android.system.OsConstant, therefore, left untouched.
- // With AT_REMOVEDIR, unlinkat works equivalent to rmdir. Again there is no suitable alternative
- // for the flag in android.system.OsConstant, therefore, left unchanged.
static final int O_RDONLY = OsConstants.O_RDONLY;
static final int O_WRONLY = OsConstants.O_WRONLY;
@@ -137,10 +130,6 @@
static final int EMFILE = OsConstants.EMFILE;
- static final int AT_SYMLINK_NOFOLLOW = 0x100;
-
- static final int AT_REMOVEDIR = 0x200;
-
// S_IAMB are access mode bits, therefore, calculated by taking OR of all the read, write and
// execute permissions bits for owner, group and other.
private static int get_S_IAMB() {
@@ -148,4 +137,9 @@
OsConstants.S_IRGRP | OsConstants.S_IWGRP | OsConstants.S_IXGRP |
OsConstants.S_IROTH | OsConstants.S_IWOTH | OsConstants.S_IXOTH);
}
-}
+ // END Android-changed: Use constants from android.system.OsConstants. http://b/32203242
+
+
+ static final int AT_SYMLINK_NOFOLLOW = 0x100;
+ static final int AT_REMOVEDIR = 0x200;
+}
diff --git a/ojluni/src/main/java/sun/nio/fs/UnixFileStore.java b/ojluni/src/main/java/sun/nio/fs/UnixFileStore.java
index 98fc9ab..0532e4d 100644
--- a/ojluni/src/main/java/sun/nio/fs/UnixFileStore.java
+++ b/ojluni/src/main/java/sun/nio/fs/UnixFileStore.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -186,7 +186,8 @@
return false;
UnixFileStore other = (UnixFileStore)ob;
return (this.dev == other.dev) &&
- Arrays.equals(this.entry.dir(), other.entry.dir());
+ Arrays.equals(this.entry.dir(), other.entry.dir()) &&
+ this.entry.name().equals(other.entry.name());
}
@Override
diff --git a/ojluni/src/main/java/sun/nio/fs/Util.java b/ojluni/src/main/java/sun/nio/fs/Util.java
index fdd6ccc..08a3025 100644
--- a/ojluni/src/main/java/sun/nio/fs/Util.java
+++ b/ojluni/src/main/java/sun/nio/fs/Util.java
@@ -38,6 +38,8 @@
class Util {
private Util() { }
+ // Android-changed: Hard-code UTF-8 for jnuEncoding rather than requiring a system property.
+ // The system property sun.jnu.encoding is not set on Android; we just hard-code "UTF-8" here.
// private static final Charset jnuEncoding = Charset.forName(
// AccessController.doPrivileged(new GetPropertyAction("sun.jnu.encoding")));
private static final Charset jnuEncoding = Charset.forName("UTF-8");
diff --git a/ojluni/src/main/java/sun/reflect/Reflection.java b/ojluni/src/main/java/sun/reflect/Reflection.java
index bb82b43..9c6c0cc 100644
--- a/ojluni/src/main/java/sun/reflect/Reflection.java
+++ b/ojluni/src/main/java/sun/reflect/Reflection.java
@@ -30,12 +30,82 @@
import java.util.HashMap;
import java.util.Map;
+import dalvik.system.VMStack;
+
/** Common utility routines used by both java.lang and
java.lang.reflect */
public class Reflection {
- // Android-removed: Dead code: Misc unused fields and methods.
+ // Android-removed: Dead code.
+ /*
+ /** Used to filter out fields and methods from certain classes from public
+ view, where they are sensitive or they may contain VM-internal objects.
+ These Maps are updated very rarely. Rather than synchronize on
+ each access, we use copy-on-write *
+ private static volatile Map<Class<?>,String[]> fieldFilterMap;
+ private static volatile Map<Class<?>,String[]> methodFilterMap;
+
+ static {
+ Map<Class<?>,String[]> map = new HashMap<Class<?>,String[]>();
+ map.put(Reflection.class,
+ new String[] {"fieldFilterMap", "methodFilterMap"});
+ map.put(System.class, new String[] {"security"});
+ map.put(Class.class, new String[] {"classLoader"});
+ fieldFilterMap = map;
+
+ methodFilterMap = new HashMap<>();
+ }
+ */
+
+ // BEGIN Android-changed: getCallerClass() reimplementation.
+ // As of 2018-07 this implementation does not ignore frames
+ // associated with java.lang.reflect.Method.invoke() but this
+ // may change in future, see http://b/111800372 .
+ // Only code that expects or can handle the RI behavior (eg.
+ // code inherited from the RI) should call this method.
+ /*
+ /** Returns the class of the caller of the method calling this method,
+ ignoring frames associated with java.lang.reflect.Method.invoke()
+ and its implementation. *
+ @CallerSensitive
+ public static native Class<?> getCallerClass();
+ */
+ public static Class<?> getCallerClass() {
+ // This method (getCallerClass()) constitutes another stack frame,
+ // so we need to call getStackClass2() rather than getStackClass1().
+ return VMStack.getStackClass2();
+ }
+ // END Android-changed: getCallerClass() reimplementation.
+
+ // Android-removed: Dead code.
+ /*
+ /**
+ * @deprecated This method will be removed in JDK 9.
+ * This method is a private JDK API and retained temporarily for
+ * existing code to run until a replacement API is defined.
+ *
+ @Deprecated
+ public static native Class<?> getCallerClass(int depth);
+
+ /** Retrieves the access flags written to the class file. For
+ inner classes these flags may differ from those returned by
+ Class.getModifiers(), which searches the InnerClasses
+ attribute to find the source-level access flags. This is used
+ instead of Class.getModifiers() for run-time access checks due
+ to compatibility reasons; see 4471811. Only the values of the
+ low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be
+ valid. *
+ public static native int getClassAccessFlags(Class<?> c);
+
+ /** A quick "fast-path" check to try to avoid getCallerClass()
+ calls. *
+ public static boolean quickCheckMemberAccess(Class<?> memberClass,
+ int modifiers)
+ {
+ return Modifier.isPublic(getClassAccessFlags(memberClass) & modifiers);
+ }
+ */
public static void ensureMemberAccess(Class<?> currentClass,
Class<?> memberClass,
@@ -77,7 +147,10 @@
return true;
}
- // Android-changed
+ // Android-changed: verifyMemberAccess() consistent with class.getAccessFlags(T).
+ // The RI carries a separate getClassAccessFlags(Class) utility method
+ // with slightly different behavior for backwards compatibility. This
+ // does not apply on Android since the RI code was never adopted.
// if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
if (!Modifier.isPublic(memberClass.getAccessFlags())) {
isSameClassPackage = isSameClassPackage(currentClass, memberClass);
@@ -204,6 +277,6 @@
return false;
}
- // Android-removed: Dead code: Misc unused methods.
+ // Android-removed: Dead code.
}
diff --git a/ojluni/src/main/java/sun/reflect/misc/ReflectUtil.java b/ojluni/src/main/java/sun/reflect/misc/ReflectUtil.java
index 5896f15..b4fdf70 100644
--- a/ojluni/src/main/java/sun/reflect/misc/ReflectUtil.java
+++ b/ojluni/src/main/java/sun/reflect/misc/ReflectUtil.java
@@ -26,7 +26,10 @@
package sun.reflect.misc;
+
+import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
+import sun.reflect.Reflection;
public final class ReflectUtil {
@@ -45,7 +48,61 @@
return cls.newInstance();
}
- // Android-removed: Dead code: Unused method ensureMemberAccess()
+ /*
+ * Reflection.ensureMemberAccess is overly-restrictive
+ * due to a bug. We awkwardly work around it for now.
+ */
+ public static void ensureMemberAccess(Class<?> currentClass,
+ Class<?> memberClass,
+ Object target,
+ int modifiers)
+ throws IllegalAccessException
+ {
+ if (target == null && Modifier.isProtected(modifiers)) {
+ int mods = modifiers;
+ mods = mods & (~Modifier.PROTECTED);
+ mods = mods | Modifier.PUBLIC;
+
+ /*
+ * See if we fail because of class modifiers
+ */
+ Reflection.ensureMemberAccess(currentClass,
+ memberClass,
+ target,
+ mods);
+ try {
+ /*
+ * We're still here so class access was ok.
+ * Now try with default field access.
+ */
+ mods = mods & (~Modifier.PUBLIC);
+ Reflection.ensureMemberAccess(currentClass,
+ memberClass,
+ target,
+ mods);
+ /*
+ * We're still here so access is ok without
+ * checking for protected.
+ */
+ return;
+ } catch (IllegalAccessException e) {
+ /*
+ * Access failed but we're 'protected' so
+ * if the test below succeeds then we're ok.
+ */
+ if (isSubclassOf(currentClass, memberClass)) {
+ return;
+ } else {
+ throw e;
+ }
+ }
+ } else {
+ Reflection.ensureMemberAccess(currentClass,
+ memberClass,
+ target,
+ modifiers);
+ }
+ }
private static boolean isSubclassOf(Class<?> queryClass,
Class<?> ofClass)
diff --git a/ojluni/src/main/java/sun/security/jca/Providers.java b/ojluni/src/main/java/sun/security/jca/Providers.java
index fd8d9c8..a9634f0 100644
--- a/ojluni/src/main/java/sun/security/jca/Providers.java
+++ b/ojluni/src/main/java/sun/security/jca/Providers.java
@@ -567,5 +567,6 @@
}
}
}
+ // END Android-added: Check for requests of deprecated Bouncy Castle algorithms.
}
diff --git a/ojluni/src/main/native/Android.bp b/ojluni/src/main/native/Android.bp
index 71546ca..7c77ee9 100644
--- a/ojluni/src/main/native/Android.bp
+++ b/ojluni/src/main/native/Android.bp
@@ -1,10 +1,10 @@
filegroup {
name: "libopenjdk_native_srcs",
srcs: [
- "java_util_zip_ZipFile.c",
- "java_util_zip_Inflater.c",
- "java_util_zip_Deflater.c",
- "java_util_zip_CRC32.c",
+ "ZipFile.c",
+ "Inflater.c",
+ "Deflater.c",
+ "CRC32.c",
"Adler32.c",
"zip_util.c",
"jni_util.c",
@@ -57,9 +57,8 @@
"System.c",
"Runtime.c",
"UNIXProcess_md.c",
- "Bits.c",
"Character.cpp",
- "Register.cpp",
"socket_tagger_util.cpp",
+ "OnLoad.cpp",
],
}
diff --git a/ojluni/src/main/native/Bits.c b/ojluni/src/main/native/Bits.c
deleted file mode 100644
index 50caf36..0000000
--- a/ojluni/src/main/native/Bits.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (c) 2002, 2010, 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.
- */
-
-/*
- */
-
-#include "jni.h"
-#include "jni_util.h"
-#include "jlong.h"
-#include <string.h>
-
-#include <nativehelper/JNIHelp.h>
-
-/*
- * WARNING:
- *
- * Do not replace instances of:
- *
- * if (length > MBYTE)
- * size = MBYTE;
- * else
- * size = length;
- *
- * with
- *
- * size = (length > MBYTE ? MBYTE : length);
- *
- * This expression causes a c compiler assertion failure when compiling on
- * 32-bit sparc.
- */
-
-#define MBYTE 1048576
-
-#define GETCRITICAL(bytes, env, obj) { \
- (bytes) = (*(env))->GetPrimitiveArrayCritical(env, obj, NULL); \
- if ((bytes) == NULL) \
- JNU_ThrowInternalError(env, "Unable to get array"); \
-}
-
-#define RELEASECRITICAL(bytes, env, obj, mode) { \
- (*(env))->ReleasePrimitiveArrayCritical(env, obj, bytes, mode); \
-}
-
-#define SWAPSHORT(x) ((jshort)(((x) << 8) | (((x) >> 8) & 0xff)))
-#define SWAPINT(x) ((jint)((SWAPSHORT((jshort)(x)) << 16) | \
- (SWAPSHORT((jshort)((x) >> 16)) & 0xffff)))
-#define SWAPLONG(x) ((jlong)(((jlong)SWAPINT((jint)(x)) << 32) | \
- ((jlong)SWAPINT((jint)((x) >> 32)) & 0xffffffff)))
-
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(Java_java_nio_ ## className ## _ ## functionName) }
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jobject this, jobject src,
- jlong srcPos, jlong dstAddr, jlong length)
-{
- jbyte *bytes;
- size_t size;
- jshort *srcShort, *dstShort, *endShort;
- jshort tmpShort;
-
- dstShort = (jshort *)jlong_to_ptr(dstAddr);
-
- while (length > 0) {
- /* do not change this if-else statement, see WARNING above */
- if (length > MBYTE)
- size = MBYTE;
- else
- size = (size_t)length;
-
- GETCRITICAL(bytes, env, src);
-
- srcShort = (jshort *)(bytes + srcPos);
- endShort = srcShort + (size / sizeof(jshort));
- while (srcShort < endShort) {
- tmpShort = *srcShort++;
- *dstShort++ = SWAPSHORT(tmpShort);
- }
-
- RELEASECRITICAL(bytes, env, src, JNI_ABORT);
-
- length -= size;
- dstAddr += size;
- srcPos += size;
- }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jobject this, jlong srcAddr,
- jobject dst, jlong dstPos, jlong length)
-{
- jbyte *bytes;
- size_t size;
- jshort *srcShort, *dstShort, *endShort;
- jshort tmpShort;
-
- srcShort = (jshort *)jlong_to_ptr(srcAddr);
-
- while (length > 0) {
- /* do not change this if-else statement, see WARNING above */
- if (length > MBYTE)
- size = MBYTE;
- else
- size = (size_t)length;
-
- GETCRITICAL(bytes, env, dst);
-
- dstShort = (jshort *)(bytes + dstPos);
- endShort = srcShort + (size / sizeof(jshort));
- while (srcShort < endShort) {
- tmpShort = *srcShort++;
- *dstShort++ = SWAPSHORT(tmpShort);
- }
-
- RELEASECRITICAL(bytes, env, dst, 0);
-
- length -= size;
- srcAddr += size;
- dstPos += size;
- }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jobject this, jobject src,
- jlong srcPos, jlong dstAddr, jlong length)
-{
- jbyte *bytes;
- size_t size;
- jint *srcInt, *dstInt, *endInt;
- jint tmpInt;
-
- dstInt = (jint *)jlong_to_ptr(dstAddr);
-
- while (length > 0) {
- /* do not change this code, see WARNING above */
- if (length > MBYTE)
- size = MBYTE;
- else
- size = (size_t)length;
-
- GETCRITICAL(bytes, env, src);
-
- srcInt = (jint *)(bytes + srcPos);
- endInt = srcInt + (size / sizeof(jint));
- while (srcInt < endInt) {
- tmpInt = *srcInt++;
- *dstInt++ = SWAPINT(tmpInt);
- }
-
- RELEASECRITICAL(bytes, env, src, JNI_ABORT);
-
- length -= size;
- dstAddr += size;
- srcPos += size;
- }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jobject this, jlong srcAddr,
- jobject dst, jlong dstPos, jlong length)
-{
- jbyte *bytes;
- size_t size;
- jint *srcInt, *dstInt, *endInt;
- jint tmpInt;
-
- srcInt = (jint *)jlong_to_ptr(srcAddr);
-
- while (length > 0) {
- /* do not change this code, see WARNING above */
- if (length > MBYTE)
- size = MBYTE;
- else
- size = (size_t)length;
-
- GETCRITICAL(bytes, env, dst);
-
- dstInt = (jint *)(bytes + dstPos);
- endInt = srcInt + (size / sizeof(jint));
- while (srcInt < endInt) {
- tmpInt = *srcInt++;
- *dstInt++ = SWAPINT(tmpInt);
- }
-
- RELEASECRITICAL(bytes, env, dst, 0);
-
- length -= size;
- srcAddr += size;
- dstPos += size;
- }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jobject this, jobject src,
- jlong srcPos, jlong dstAddr, jlong length)
-{
- jbyte *bytes;
- size_t size;
- jlong *srcLong, *dstLong, *endLong;
- jlong tmpLong;
-
- dstLong = (jlong *)jlong_to_ptr(dstAddr);
-
- while (length > 0) {
- /* do not change this code, see WARNING above */
- if (length > MBYTE)
- size = MBYTE;
- else
- size = (size_t)length;
-
- GETCRITICAL(bytes, env, src);
-
- srcLong = (jlong *)(bytes + srcPos);
- endLong = srcLong + (size / sizeof(jlong));
- while (srcLong < endLong) {
- tmpLong = *srcLong++;
- *dstLong++ = SWAPLONG(tmpLong);
- }
-
- RELEASECRITICAL(bytes, env, src, JNI_ABORT);
-
- length -= size;
- dstAddr += size;
- srcPos += size;
- }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jobject this, jlong srcAddr,
- jobject dst, jlong dstPos, jlong length)
-{
- jbyte *bytes;
- size_t size;
- jlong *srcLong, *dstLong, *endLong;
- jlong tmpLong;
-
- srcLong = (jlong *)jlong_to_ptr(srcAddr);
-
- while (length > 0) {
- /* do not change this code, see WARNING above */
- if (length > MBYTE)
- size = MBYTE;
- else
- size = (size_t)length;
-
- GETCRITICAL(bytes, env, dst);
-
- dstLong = (jlong *)(bytes + dstPos);
- endLong = srcLong + (size / sizeof(jlong));
- while (srcLong < endLong) {
- tmpLong = *srcLong++;
- *dstLong++ = SWAPLONG(tmpLong);
- }
-
- RELEASECRITICAL(bytes, env, dst, 0);
-
- length -= size;
- srcAddr += size;
- dstPos += size;
- }
-}
-
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(Bits, copyFromShortArray, "(Ljava/lang/Object;JJJ)V"),
- NATIVE_METHOD(Bits, copyToShortArray, "(JLjava/lang/Object;JJ)V"),
- NATIVE_METHOD(Bits, copyFromIntArray, "(Ljava/lang/Object;JJJ)V"),
- NATIVE_METHOD(Bits, copyToIntArray, "(JLjava/lang/Object;JJ)V"),
- NATIVE_METHOD(Bits, copyFromLongArray, "(Ljava/lang/Object;JJJ)V"),
- NATIVE_METHOD(Bits, copyToLongArray, "(JLjava/lang/Object;JJ)V"),
-};
-
-void register_java_nio_Bits(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/nio/Bits", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/src/main/native/java_util_zip_CRC32.c b/ojluni/src/main/native/CRC32.c
similarity index 100%
rename from ojluni/src/main/native/java_util_zip_CRC32.c
rename to ojluni/src/main/native/CRC32.c
diff --git a/ojluni/src/main/native/Character.cpp b/ojluni/src/main/native/Character.cpp
index 666184f..9fb24c3 100644
--- a/ojluni/src/main/native/Character.cpp
+++ b/ojluni/src/main/native/Character.cpp
@@ -1,11 +1,12 @@
/*
- * Copyright 2015 Google Inc.
+ * Copyright (C) 2015 The Android Open Source Project
*
* 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. Google designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Google in the LICENSE file that accompanied this code.
+ * published by the Free Software Foundation. The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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
diff --git a/ojluni/src/main/native/java_util_zip_Deflater.c b/ojluni/src/main/native/Deflater.c
similarity index 100%
rename from ojluni/src/main/native/java_util_zip_Deflater.c
rename to ojluni/src/main/native/Deflater.c
diff --git a/ojluni/src/main/native/java_util_zip_Inflater.c b/ojluni/src/main/native/Inflater.c
similarity index 100%
rename from ojluni/src/main/native/java_util_zip_Inflater.c
rename to ojluni/src/main/native/Inflater.c
diff --git a/ojluni/src/main/native/Math.c b/ojluni/src/main/native/Math.c
index 64f361a..4bbcd1d 100644
--- a/ojluni/src/main/native/Math.c
+++ b/ojluni/src/main/native/Math.c
@@ -1,11 +1,12 @@
/*
- * Copyright 2015 Google Inc.
+ * Copyright (C) 2015 The Android Open Source Project
*
* 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. Google designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Google in the LICENSE file that accompanied this code.
+ * published by the Free Software Foundation. The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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
diff --git a/ojluni/src/main/native/OnLoad.cpp b/ojluni/src/main/native/OnLoad.cpp
new file mode 100644
index 0000000..ab13939
--- /dev/null
+++ b/ojluni/src/main/native/OnLoad.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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. The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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.
+ */
+
+#include <jni.h>
+#include <android-base/logging.h>
+
+extern "C" void register_java_util_zip_ZipFile(JNIEnv* env);
+extern "C" void register_java_util_zip_Inflater(JNIEnv* env);
+extern "C" void register_java_util_zip_Deflater(JNIEnv* env);
+extern "C" void register_java_util_zip_CRC32(JNIEnv* env);
+extern "C" void register_java_util_zip_Adler32(JNIEnv* env);
+extern "C" void register_java_io_FileDescriptor(JNIEnv* env);
+extern "C" void register_sun_nio_ch_DatagramChannelImpl(JNIEnv* env);
+extern "C" void register_sun_nio_ch_DatagramDispatcher(JNIEnv* env);
+extern "C" void register_java_io_Console(JNIEnv* env);
+extern "C" void register_sun_nio_ch_IOUtil(JNIEnv* env);
+extern "C" void register_sun_nio_ch_SocketChannelImpl(JNIEnv* env);
+extern "C" void register_sun_nio_ch_FileChannelImpl(JNIEnv* env);
+extern "C" void register_sun_nio_ch_FileDispatcherImpl(JNIEnv* env);
+extern "C" void register_java_io_FileOutputStream(JNIEnv* env);
+extern "C" void register_java_io_FileInputStream(JNIEnv* env);
+extern "C" void register_java_util_prefs_FileSystemPreferences(JNIEnv* env);
+extern "C" void register_sun_nio_ch_NativeThread(JNIEnv* env);
+extern "C" void register_sun_nio_ch_FileKey(JNIEnv* env);
+extern "C" void register_java_io_UnixFileSystem(JNIEnv* env);
+extern "C" void register_java_io_ObjectStreamClass(JNIEnv* env);
+extern "C" void register_java_io_ObjectOutputStream(JNIEnv* env);
+extern "C" void register_java_io_ObjectInputStream(JNIEnv* env);
+extern "C" void register_java_net_InetAddress(JNIEnv* env);
+extern "C" jint net_JNI_OnLoad(JavaVM *vm, void* ignored);
+extern "C" void register_sun_nio_ch_Net(JNIEnv* env);
+extern "C" void register_java_nio_MappedByteBuffer(JNIEnv* env);
+extern "C" void register_java_net_Inet6Address(JNIEnv* env);
+extern "C" void register_java_net_Inet4Address(JNIEnv* env);
+extern "C" void register_sun_nio_ch_ServerSocketChannelImpl(JNIEnv* env);
+extern "C" void register_java_net_SocketInputStream(JNIEnv* env);
+extern "C" void register_java_net_SocketOutputStream(JNIEnv* env);
+extern "C" void register_java_lang_Float(JNIEnv* env);
+extern "C" void register_java_lang_Double(JNIEnv* env);
+extern "C" void register_java_lang_StrictMath(JNIEnv* env);
+extern "C" void register_java_lang_Math(JNIEnv* env);
+extern "C" void register_java_lang_ProcessEnvironment(JNIEnv* env);
+extern "C" void register_java_lang_System(JNIEnv* env);
+extern "C" void register_java_lang_Runtime(JNIEnv* env);
+extern "C" void register_java_lang_UNIXProcess(JNIEnv* env);
+void register_java_lang_Character(JNIEnv* env);
+
+extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
+ jint version = JNI_VERSION_1_6;
+ void* raw_env;
+ jint result = vm->GetEnv(&raw_env, version);
+ CHECK_EQ(result, JNI_OK);
+ CHECK(raw_env != nullptr);
+ JNIEnv* env = static_cast<JNIEnv*>(raw_env);
+
+ // Some registration functions also do some extra local initialization,
+ // creating local references in the process. ART does not expect JNI_OnLoad()
+ // to leave any local references in the current frame, so create a new one.
+ // Request space for 256 local references (increase if necessary).
+ result = env->PushLocalFrame(256);
+ CHECK_EQ(result, 0);
+
+ // Some registration functions also record field ids retrieved using
+ // GetFieldID(), forcing the initialization of the searched class. As some
+ // class initializers (notably Inet*Address) directly or indirectly use
+ // the StringBuilder, we need to start by registering native methods needed
+ // for resizing its internal buffer. That's done through Arrays.copyOf()
+ // which uses System.arraycopy() and Math.min(), forcing the initialization
+ // of System and Main. The former uses System's own native methods while the
+ // latter uses native methods of Float and Double but not Math's own.
+ register_java_lang_Float(env);
+ register_java_lang_Double(env);
+ register_java_lang_System(env);
+
+ // Initialize the rest in the order in which they appear in Android.bp .
+ register_java_util_zip_ZipFile(env);
+ register_java_util_zip_Inflater(env);
+ register_java_util_zip_Deflater(env);
+ register_java_util_zip_CRC32(env);
+ register_java_util_zip_Adler32(env);
+ register_java_io_FileDescriptor(env);
+ register_sun_nio_ch_DatagramChannelImpl(env);
+ register_sun_nio_ch_DatagramDispatcher(env);
+ register_java_io_Console(env);
+ register_sun_nio_ch_IOUtil(env);
+ register_sun_nio_ch_SocketChannelImpl(env);
+ register_sun_nio_ch_FileChannelImpl(env);
+ register_sun_nio_ch_FileDispatcherImpl(env);
+ register_java_io_FileOutputStream(env);
+ register_java_io_FileInputStream(env);
+ register_java_util_prefs_FileSystemPreferences(env);
+ register_sun_nio_ch_NativeThread(env);
+ register_sun_nio_ch_FileKey(env);
+ register_java_io_UnixFileSystem(env);
+ register_java_io_ObjectStreamClass(env);
+ register_java_io_ObjectOutputStream(env);
+ register_java_io_ObjectInputStream(env);
+ register_java_net_InetAddress(env);
+
+ jint net_jni_version = net_JNI_OnLoad(vm, /* ignored */ nullptr);
+ CHECK(net_jni_version == JNI_VERSION_1_2 ||
+ net_jni_version == JNI_VERSION_1_4 ||
+ net_jni_version == JNI_VERSION_1_6);
+
+ register_sun_nio_ch_Net(env);
+ register_java_nio_MappedByteBuffer(env);
+ register_java_net_Inet6Address(env);
+ register_java_net_Inet4Address(env);
+ register_sun_nio_ch_ServerSocketChannelImpl(env);
+ register_java_net_SocketInputStream(env);
+ register_java_net_SocketOutputStream(env);
+ register_java_lang_StrictMath(env);
+ register_java_lang_Math(env);
+ register_java_lang_ProcessEnvironment(env);
+ register_java_lang_Runtime(env);
+ register_java_lang_UNIXProcess(env);
+ register_java_lang_Character(env);
+
+ env->PopLocalFrame(/* result */ nullptr); // Pop the local frame.
+ return version;
+}
diff --git a/ojluni/src/main/native/Register.cpp b/ojluni/src/main/native/Register.cpp
index 15ac1e4..6294981 100644
--- a/ojluni/src/main/native/Register.cpp
+++ b/ojluni/src/main/native/Register.cpp
@@ -58,7 +58,6 @@
extern void register_java_net_PlainDatagramSocketImpl(JNIEnv*);
extern void register_java_net_SocketInputStream(JNIEnv*);
extern void register_java_net_SocketOutputStream(JNIEnv*);
-extern void register_java_nio_Bits(JNIEnv* env);
extern void register_java_nio_MappedByteBuffer(JNIEnv* env);
extern void register_java_util_zip_Adler32(JNIEnv* env);
extern void register_java_util_zip_CRC32(JNIEnv*);
@@ -126,7 +125,6 @@
register_java_net_Inet6Address(env);
register_java_net_SocketInputStream(env);
register_java_net_SocketOutputStream(env);
- register_java_nio_Bits(env);
register_java_util_prefs_FileSystemPreferences(env);
register_sun_nio_ch_ServerSocketChannelImpl(env);
register_sun_nio_ch_SocketChannelImpl(env);
diff --git a/ojluni/src/main/native/Runtime.c b/ojluni/src/main/native/Runtime.c
index 4c023b5..ad734fd 100644
--- a/ojluni/src/main/native/Runtime.c
+++ b/ojluni/src/main/native/Runtime.c
@@ -62,7 +62,7 @@
}
JNIEXPORT void JNICALL
-Runtime_gc(JNIEnv *env, jobject this)
+Runtime_nativeGc(JNIEnv *env, jobject this)
{
JVM_GC();
}
@@ -84,7 +84,7 @@
FAST_NATIVE_METHOD(Runtime, freeMemory, "()J"),
FAST_NATIVE_METHOD(Runtime, totalMemory, "()J"),
FAST_NATIVE_METHOD(Runtime, maxMemory, "()J"),
- NATIVE_METHOD(Runtime, gc, "()V"),
+ NATIVE_METHOD(Runtime, nativeGc, "()V"),
NATIVE_METHOD(Runtime, nativeExit, "(I)V"),
NATIVE_METHOD(Runtime, nativeLoad,
"(Ljava/lang/String;Ljava/lang/ClassLoader;)"
diff --git a/ojluni/src/main/native/Thread.c b/ojluni/src/main/native/Thread.c
deleted file mode 100644
index 83b448f..0000000
--- a/ojluni/src/main/native/Thread.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 1994, 2003, 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.
- */
-
-/*-
- * Stuff for dealing with threads.
- * originally in threadruntime.c, Sun Sep 22 12:09:39 1991
- */
-
-#include "jni.h"
-#include "jvm.h"
-
-
-#define THD "Ljava/lang/Thread;"
-#define OBJ "Ljava/lang/Object;"
-#define STE "Ljava/lang/StackTraceElement;"
-#define STR "Ljava/lang/String;"
-#include <nativehelper/JNIHelp.h>
-
-#define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0]))
-
-static JNINativeMethod methods[] = {
- {"start0", "(JZ)V", (void *)&JVM_StartThread},
- {"setPriority0", "(I)V", (void *)&JVM_SetThreadPriority},
- {"yield", "()V", (void *)&JVM_Yield},
- {"sleep", "(Ljava/lang/Object;J)V", (void *)&JVM_Sleep},
- {"currentThread", "()" THD, (void *)&JVM_CurrentThread},
- {"interrupt0", "()V", (void *)&JVM_Interrupt},
- {"isInterrupted", "(Z)Z", (void *)&JVM_IsInterrupted},
- {"holdsLock", "(" OBJ ")Z", (void *)&JVM_HoldsLock},
- {"setNativeName", "(" STR ")V", (void *)&JVM_SetNativeThreadName},
-};
-
-#undef THD
-#undef OBJ
-#undef STE
-#undef STR
-
-void register_java_lang_Thread(JNIEnv* env) {
- jclass cls = (*env)->FindClass(env, "java/lang/Thread");
- (*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(methods));
-}
diff --git a/ojluni/src/main/native/Throwable.c b/ojluni/src/main/native/Throwable.c
deleted file mode 100644
index 805c80a..0000000
--- a/ojluni/src/main/native/Throwable.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 1994, 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
- * 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.
- */
-
-/*
- * Implementation of class Throwable
- *
- * former classruntime.c, Wed Jun 26 18:43:20 1991
- */
-
-#include <stdio.h>
-#include <signal.h>
-
-#include "jni.h"
-#include "jvm.h"
-
-#include <nativehelper/JNIHelp.h>
-
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
-
-/*
- * Fill in the current stack trace in this exception. This is
- * usually called automatically when the exception is created but it
- * may also be called explicitly by the user. This routine returns
- * `this' so you can write 'throw e.fillInStackTrace();'
- */
-JNIEXPORT jobject JNICALL
-Throwable_fillInStackTrace(JNIEnv *env, jobject throwable, int dummy)
-{
- JVM_FillInStackTrace(env, throwable);
- return throwable;
-}
-
-JNIEXPORT jint JNICALL
-Throwable_getStackTraceDepth(JNIEnv *env, jobject throwable)
-{
- return JVM_GetStackTraceDepth(env, throwable);
-}
-
-JNIEXPORT jobject JNICALL
-Throwable_getStackTraceElement(JNIEnv *env,
- jobject throwable, jint index)
-{
- return JVM_GetStackTraceElement(env, throwable, index);
-}
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(Throwable, fillInStackTrace, "(I)Ljava/lang/Throwable;"),
- NATIVE_METHOD(Throwable, getStackTraceDepth, "()I"),
- NATIVE_METHOD(Throwable, getStackTraceElement, "(I)Ljava/lang/StackTraceElement;"),
-};
-
-void register_java_lang_Throwable(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/lang/Throwable", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/src/main/native/UNIXProcess_md.c b/ojluni/src/main/native/UNIXProcess_md.c
index 550a5c5..b289f1a 100644
--- a/ojluni/src/main/native/UNIXProcess_md.c
+++ b/ojluni/src/main/native/UNIXProcess_md.c
@@ -117,7 +117,8 @@
#ifndef START_CHILD_USE_VFORK
// Android-changed: disable vfork under AddressSanitizer.
// #ifdef __linux__
- #if defined(__linux__) && !__has_feature(address_sanitizer)
+ #if defined(__linux__) && !__has_feature(address_sanitizer) && \
+ !__has_feature(hwaddress_sanitizer)
#define START_CHILD_USE_VFORK 1
#else
#define START_CHILD_USE_VFORK 0
diff --git a/ojluni/src/main/native/java_util_zip_ZipFile.c b/ojluni/src/main/native/ZipFile.c
similarity index 100%
rename from ojluni/src/main/native/java_util_zip_ZipFile.c
rename to ojluni/src/main/native/ZipFile.c
diff --git a/ojluni/src/main/native/java_props_md.c b/ojluni/src/main/native/java_props_md.c
deleted file mode 100644
index a9fe5ba..0000000
--- a/ojluni/src/main/native/java_props_md.c
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * Copyright (c) 1998, 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
- * 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.
- */
-
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
-#include <stdio.h>
-#include <ctype.h>
-#endif
-#include <pwd.h>
-#include <locale.h>
-#ifndef ARCHPROPNAME
-#error "The macro ARCHPROPNAME has not been defined"
-#endif
-#include <sys/utsname.h> /* For os_name and os_version */
-#include <langinfo.h> /* For nl_langinfo */
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/param.h>
-#include <time.h>
-#include <errno.h>
-
-#ifdef MACOSX
-#endif
-
-#if defined(_ALLBSD_SOURCE)
-#if !defined(P_tmpdir)
-#include <paths.h>
-#define P_tmpdir _PATH_VARTMP
-#endif
-#endif
-
-#include "locale_str.h"
-
-#if !defined(_ALLBSD_SOURCE)
-#ifdef __linux__
- #ifndef CODESET
- #define CODESET _NL_CTYPE_CODESET_NAME
- #endif
-#else
-#ifdef ALT_CODESET_KEY
-#define CODESET ALT_CODESET_KEY
-#endif
-#endif
-#endif /* !_ALLBSD_SOURCE */
-
-#ifdef JAVASE_EMBEDDED
-#include <dlfcn.h>
-#include <sys/stat.h>
-#endif
-
-/* Take an array of string pairs (map of key->value) and a string (key).
- * Examine each pair in the map to see if the first string (key) matches the
- * string. If so, store the second string of the pair (value) in the value and
- * return 1. Otherwise do nothing and return 0. The end of the map is
- * indicated by an empty string at the start of a pair (key of "").
- */
-static int
-mapLookup(char* map[], const char* key, char** value) {
- int i;
- for (i = 0; strcmp(map[i], ""); i += 2){
- if (!strcmp(key, map[i])){
- *value = map[i + 1];
- return 1;
- }
- }
- return 0;
-}
-
-/* This function sets an environment variable using envstring.
- * The format of envstring is "name=value".
- * If the name has already existed, it will append value to the name.
- */
-static void
-setPathEnvironment(char *envstring)
-{
- char name[20], *value, *current;
-
- value = strchr(envstring, '='); /* locate name and value separator */
-
- if (! value)
- return; /* not a valid environment setting */
-
- /* copy first part as environment name */
- strncpy(name, envstring, value - envstring);
- name[value-envstring] = '\0';
-
- value++; /* set value point to value of the envstring */
-
- current = getenv(name);
- if (current) {
- if (! strstr(current, value)) {
- /* value is not found in current environment, append it */
- char *temp = malloc(strlen(envstring) + strlen(current) + 2);
- strcpy(temp, name);
- strcat(temp, "=");
- strcat(temp, current);
- strcat(temp, ":");
- strcat(temp, value);
- putenv(temp);
- }
- /* else the value has already been set, do nothing */
- }
- else {
- /* environment variable is not found */
- putenv(envstring);
- }
-}
-
-#ifndef P_tmpdir
-#define P_tmpdir "/var/tmp"
-#endif
-
-static int ParseLocale(int cat, char ** std_language, char ** std_script,
- char ** std_country, char ** std_variant, char ** std_encoding) {
- char temp[64];
- char *language = NULL, *country = NULL, *variant = NULL,
- *encoding = NULL;
- char *p, encoding_variant[64];
- char *lc;
-
- /* Query the locale set for the category */
-
-#ifdef MACOSX
- lc = setupMacOSXLocale(cat); // malloc'd memory, need to free
-#else
- lc = setlocale(cat, NULL);
-#endif
-
-#ifndef __linux__
- if (lc == NULL) {
- return 0;
- }
-
- if (cat == LC_CTYPE) {
- /*
- * Workaround for Solaris bug 4201684: Xlib doesn't like @euro
- * locales. Since we don't depend on the libc @euro behavior,
- * we just remove the qualifier.
- * On Linux, the bug doesn't occur; on the other hand, @euro
- * is needed there because it's a shortcut that also determines
- * the encoding - without it, we wouldn't get ISO-8859-15.
- * Therefore, this code section is Solaris-specific.
- */
- lc = strdup(lc); /* keep a copy, setlocale trashes original. */
- strcpy(temp, lc);
- p = strstr(temp, "@euro");
- if (p != NULL) {
- *p = '\0';
- setlocale(LC_ALL, temp);
- }
- }
-#else
- if (lc == NULL || !strcmp(lc, "C") || !strcmp(lc, "POSIX")) {
- lc = "en_US";
- }
-#endif
-
- /*
- * locale string format in Solaris is
- * <language name>_<country name>.<encoding name>@<variant name>
- * <country name>, <encoding name>, and <variant name> are optional.
- */
-
- strcpy(temp, lc);
-#ifdef MACOSX
- free(lc); // malloced memory
-#endif
- /* Parse the language, country, encoding, and variant from the
- * locale. Any of the elements may be missing, but they must occur
- * in the order language_country.encoding@variant, and must be
- * preceded by their delimiter (except for language).
- *
- * If the locale name (without .encoding@variant, if any) matches
- * any of the names in the locale_aliases list, map it to the
- * corresponding full locale name. Most of the entries in the
- * locale_aliases list are locales that include a language name but
- * no country name, and this facility is used to map each language
- * to a default country if that's possible. It's also used to map
- * the Solaris locale aliases to their proper Java locale IDs.
- */
- if ((p = strchr(temp, '.')) != NULL) {
- strcpy(encoding_variant, p); /* Copy the leading '.' */
- *p = '\0';
- } else if ((p = strchr(temp, '@')) != NULL) {
- strcpy(encoding_variant, p); /* Copy the leading '@' */
- *p = '\0';
- } else {
- *encoding_variant = '\0';
- }
-
- if (mapLookup(locale_aliases, temp, &p)) {
- strcpy(temp, p);
- // check the "encoding_variant" again, if any.
- if ((p = strchr(temp, '.')) != NULL) {
- strcpy(encoding_variant, p); /* Copy the leading '.' */
- *p = '\0';
- } else if ((p = strchr(temp, '@')) != NULL) {
- strcpy(encoding_variant, p); /* Copy the leading '@' */
- *p = '\0';
- }
- }
-
- language = temp;
- if ((country = strchr(temp, '_')) != NULL) {
- *country++ = '\0';
- }
-
- p = encoding_variant;
- if ((encoding = strchr(p, '.')) != NULL) {
- p[encoding++ - p] = '\0';
- p = encoding;
- }
- if ((variant = strchr(p, '@')) != NULL) {
- p[variant++ - p] = '\0';
- }
-
- /* Normalize the language name */
- if (std_language != NULL) {
- *std_language = "en";
- if (language != NULL && mapLookup(language_names, language, std_language) == 0) {
- *std_language = malloc(strlen(language)+1);
- strcpy(*std_language, language);
- }
- }
-
- /* Normalize the country name */
- if (std_country != NULL && country != NULL) {
- if (mapLookup(country_names, country, std_country) == 0) {
- *std_country = malloc(strlen(country)+1);
- strcpy(*std_country, country);
- }
- }
-
- /* Normalize the script and variant name. Note that we only use
- * variants listed in the mapping array; others are ignored.
- */
- if (variant != NULL) {
- if (std_script != NULL) {
- mapLookup(script_names, variant, std_script);
- }
-
- if (std_variant != NULL) {
- mapLookup(variant_names, variant, std_variant);
- }
- }
-
- /* Normalize the encoding name. Note that we IGNORE the string
- * 'encoding' extracted from the locale name above. Instead, we use the
- * more reliable method of calling nl_langinfo(CODESET). This function
- * returns an empty string if no encoding is set for the given locale
- * (e.g., the C or POSIX locales); we use the default ISO 8859-1
- * converter for such locales.
- */
- if (std_encoding != NULL) {
- /* OK, not so reliable - nl_langinfo() gives wrong answers on
- * Euro locales, in particular. */
- if (strcmp(p, "ISO8859-15") == 0)
- p = "ISO8859-15";
- else
- p = nl_langinfo(CODESET);
-
- /* Convert the bare "646" used on Solaris to a proper IANA name */
- if (strcmp(p, "646") == 0)
- p = "ISO646-US";
-
- /* return same result nl_langinfo would return for en_UK,
- * in order to use optimizations. */
- *std_encoding = (*p != '\0') ? p : "ISO8859-1";
-
-#ifdef __linux__
- /*
- * Remap the encoding string to a different value for japanese
- * locales on linux so that customized converters are used instead
- * of the default converter for "EUC-JP". The customized converters
- * omit support for the JIS0212 encoding which is not supported by
- * the variant of "EUC-JP" encoding used on linux
- */
- if (strcmp(p, "EUC-JP") == 0) {
- *std_encoding = "EUC-JP-LINUX";
- }
-#else
- if (strcmp(p,"eucJP") == 0) {
- /* For Solaris use customized vendor defined character
- * customized EUC-JP converter
- */
- *std_encoding = "eucJP-open";
- } else if (strcmp(p, "Big5") == 0 || strcmp(p, "BIG5") == 0) {
- /*
- * Remap the encoding string to Big5_Solaris which augments
- * the default converter for Solaris Big5 locales to include
- * seven additional ideographic characters beyond those included
- * in the Java "Big5" converter.
- */
- *std_encoding = "Big5_Solaris";
- } else if (strcmp(p, "Big5-HKSCS") == 0) {
- /*
- * Solaris uses HKSCS2001
- */
- *std_encoding = "Big5-HKSCS-2001";
- }
-#endif
- }
-
- return 1;
-}
-
-#ifdef JAVASE_EMBEDDED
-/* Determine the default embedded toolkit based on whether lib/xawt/
- * exists in the JRE. This can still be overridden by -Dawt.toolkit=XXX
- */
-static char* getEmbeddedToolkit() {
- Dl_info dlinfo;
- char buf[MAXPATHLEN];
- int32_t len;
- char *p;
- struct stat statbuf;
-
- /* Get address of this library and the directory containing it. */
- dladdr((void *)getEmbeddedToolkit, &dlinfo);
- realpath((char *)dlinfo.dli_fname, buf);
- len = strlen(buf);
- p = strrchr(buf, '/');
- /* Default AWT Toolkit on Linux and Solaris is XAWT. */
- strncpy(p, "/xawt/", MAXPATHLEN-len-1);
- /* Check if it exists */
- if (stat(buf, &statbuf) == -1 && errno == ENOENT) {
- /* No - this is a reduced-headless-jre so use special HToolkit */
- return "sun.awt.HToolkit";
- }
- else {
- /* Yes - this is a headful JRE so fallback to SE defaults */
- return NULL;
- }
-}
-#endif
-
-/* This function gets called very early, before VM_CALLS are setup.
- * Do not use any of the VM_CALLS entries!!!
- */
-java_props_t *
-GetJavaProperties(JNIEnv *env)
-{
- static java_props_t sprops;
- char *v; /* tmp var */
-
- if (sprops.user_dir) {
- return &sprops;
- }
-
- /* tmp dir */
- sprops.tmp_dir = P_tmpdir;
-#ifdef MACOSX
- /* darwin has a per-user temp dir */
- static char tmp_path[PATH_MAX];
- int pathSize = confstr(_CS_DARWIN_USER_TEMP_DIR, tmp_path, PATH_MAX);
- if (pathSize > 0 && pathSize <= PATH_MAX) {
- sprops.tmp_dir = tmp_path;
- }
-#endif /* MACOSX */
-
- /* Printing properties */
-#ifdef MACOSX
- sprops.printerJob = "sun.lwawt.macosx.CPrinterJob";
-#else
- sprops.printerJob = "sun.print.PSPrinterJob";
-#endif
-
- /* patches/service packs installed */
- sprops.patch_level = "unknown";
-
- /* Java 2D properties */
-#ifdef MACOSX
- PreferredToolkit prefToolkit = getPreferredToolkit();
- switch (prefToolkit) {
- case CToolkit:
- case HToolkit:
- sprops.graphics_env = "sun.awt.CGraphicsEnvironment";
- break;
- case XToolkit:
-#endif
- sprops.graphics_env = "sun.awt.X11GraphicsEnvironment";
-#ifdef MACOSX
- break;
- }
-#endif
- /* AWT properties */
-#ifdef JAVASE_EMBEDDED
- sprops.awt_toolkit = getEmbeddedToolkit();
- if (sprops.awt_toolkit == NULL) // default as below
-#endif
-#ifdef MACOSX
- switch (prefToolkit) {
- case CToolkit:
- sprops.awt_toolkit = "sun.lwawt.macosx.LWCToolkit";
- break;
- case XToolkit:
-#endif
- sprops.awt_toolkit = "sun.awt.X11.XToolkit";
-#ifdef MACOSX
- break;
- default:
- sprops.awt_toolkit = "sun.awt.HToolkit";
- break;
- }
-#endif
-
- /* This is used only for debugging of font problems. */
- v = getenv("JAVA2D_FONTPATH");
- sprops.font_dir = v ? v : NULL;
-
-#ifdef SI_ISALIST
- /* supported instruction sets */
- {
- char list[258];
- sysinfo(SI_ISALIST, list, sizeof(list));
- sprops.cpu_isalist = strdup(list);
- }
-#else
- sprops.cpu_isalist = NULL;
-#endif
-
- /* endianness of platform */
- {
- unsigned int endianTest = 0xff000000;
- if (((char*)(&endianTest))[0] != 0)
- sprops.cpu_endian = "big";
- else
- sprops.cpu_endian = "little";
- }
-
- /* os properties */
- {
-#ifdef MACOSX
- setOSNameAndVersion(&sprops);
-#else
- struct utsname name;
- uname(&name);
- sprops.os_name = strdup(name.sysname);
- sprops.os_version = strdup(name.release);
-#endif
-
- sprops.os_arch = ARCHPROPNAME;
-
- if (getenv("GNOME_DESKTOP_SESSION_ID") != NULL) {
- sprops.desktop = "gnome";
- }
- else {
- sprops.desktop = NULL;
- }
- }
-
- /* Determine the language, country, variant, and encoding from the host,
- * and store these in the user.language, user.country, user.variant and
- * file.encoding system properties. */
- setlocale(LC_ALL, "");
- if (ParseLocale(LC_CTYPE,
- &(sprops.format_language),
- &(sprops.format_script),
- &(sprops.format_country),
- &(sprops.format_variant),
- &(sprops.encoding))) {
- ParseLocale(LC_MESSAGES,
- &(sprops.language),
- &(sprops.script),
- &(sprops.country),
- &(sprops.variant),
- NULL);
- } else {
- sprops.language = "en";
- sprops.encoding = "ISO8859-1";
- }
- sprops.display_language = sprops.language;
- sprops.display_script = sprops.script;
- sprops.display_country = sprops.country;
- sprops.display_variant = sprops.variant;
-
-#ifdef MACOSX
- sprops.sun_jnu_encoding = "UTF-8";
-#else
- sprops.sun_jnu_encoding = sprops.encoding;
-#endif
-
-#ifdef _ALLBSD_SOURCE
-#if BYTE_ORDER == _LITTLE_ENDIAN
- sprops.unicode_encoding = "UnicodeLittle";
- #else
- sprops.unicode_encoding = "UnicodeBig";
- #endif
-#else /* !_ALLBSD_SOURCE */
-#ifdef __linux__
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- sprops.unicode_encoding = "UnicodeLittle";
-#else
- sprops.unicode_encoding = "UnicodeBig";
-#endif
-#else
- sprops.unicode_encoding = "UnicodeBig";
-#endif
-#endif /* _ALLBSD_SOURCE */
-
- /* user properties */
- {
- struct passwd *pwent = getpwuid(getuid());
- sprops.user_name = pwent ? strdup(pwent->pw_name) : "?";
- sprops.user_home = pwent ? strdup(pwent->pw_dir) : "?";
- }
-
- /* User TIMEZONE */
- {
- /*
- * We defer setting up timezone until it's actually necessary.
- * Refer to TimeZone.getDefault(). However, the system
- * property is necessary to be able to be set by the command
- * line interface -D. Here temporarily set a null string to
- * timezone.
- */
- tzset(); /* for compatibility */
- sprops.timezone = "";
- }
-
- /* Current directory */
- {
- char buf[MAXPATHLEN];
- errno = 0;
- if (getcwd(buf, sizeof(buf)) == NULL)
- JNU_ThrowByName(env, "java/lang/Error",
- "Properties init: Could not determine current working directory.");
- else
- sprops.user_dir = strdup(buf);
- }
-
- sprops.file_separator = "/";
- sprops.path_separator = ":";
- sprops.line_separator = "\n";
-
-#if !defined(_ALLBSD_SOURCE)
- /* Append CDE message and resource search path to NLSPATH and
- * XFILESEARCHPATH, in order to pick localized message for
- * FileSelectionDialog window (Bug 4173641).
- */
- setPathEnvironment("NLSPATH=/usr/dt/lib/nls/msg/%L/%N.cat");
- setPathEnvironment("XFILESEARCHPATH=/usr/dt/app-defaults/%L/Dt");
-#endif
-
-
-#ifdef MACOSX
- setProxyProperties(&sprops);
-#endif
-
- return &sprops;
-}
-
-jstring
-GetStringPlatform(JNIEnv *env, nchar* cstr)
-{
- return JNU_NewStringPlatform(env, cstr);
-}
diff --git a/ojluni/src/main/native/socket_tagger_util.cpp b/ojluni/src/main/native/socket_tagger_util.cpp
index b62898f..2f91f6d 100644
--- a/ojluni/src/main/native/socket_tagger_util.cpp
+++ b/ojluni/src/main/native/socket_tagger_util.cpp
@@ -1,11 +1,12 @@
/*
- * Copyright 2016 Google Inc.
+ * Copyright (C) 2016 The Android Open Source Project
*
* 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. Google designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Google in the LICENSE file that accompanied this code.
+ * published by the Free Software Foundation. The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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
diff --git a/ojluni/src/test/artrun b/ojluni/src/test/artrun
index e9afd78..d56753d 100755
--- a/ojluni/src/test/artrun
+++ b/ojluni/src/test/artrun
@@ -103,6 +103,7 @@
conscrypt-hostdex.jar
core-ojtests-hostdex.jar # This is the *one* addition that makes our OJ tests actually run. The rest of these are standard jars on the bootclasspath.
core-oj-hostdex.jar
+core-simple-hostdex.jar
okhttp-hostdex.jar)
BOOT_DEXJAR_PREFIX="$ANDROID_ROOT/framework"
diff --git a/openjdk_java_files.bp b/openjdk_java_files.bp
index c574f2d..3307923 100644
--- a/openjdk_java_files.bp
+++ b/openjdk_java_files.bp
@@ -249,6 +249,7 @@
"ojluni/src/main/java/java/lang/invoke/MethodHandles.java",
"ojluni/src/main/java/java/lang/invoke/MethodHandleImpl.java",
"ojluni/src/main/java/java/lang/invoke/MethodHandleInfo.java",
+ "ojluni/src/main/java/java/lang/invoke/MethodHandleNatives.java",
"ojluni/src/main/java/java/lang/invoke/MethodHandleStatics.java",
"ojluni/src/main/java/java/lang/invoke/MethodType.java",
"ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java",
diff --git a/run-libcore-tests b/run-libcore-tests
deleted file mode 100755
index 996030a..0000000
--- a/run-libcore-tests
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-# Make sure there's a vogar on the path, but prefer the user's one.
-export PATH=$PATH:~dalvik-prebuild/vogar/bin
-
-VOGAR="vogar $VOGAR_FLAGS"
-
-# We enumerate the test packages for vogar rather than just giving it the classes.jar
-# so hundreds of packages can be tested in parallel, rather than one big jar file serially.
-all_test_packages=$(find `dirname $0`/*/src/test -name "*.java" | \
- fgrep -v junit | \
- fgrep -v org/w3c/domts | \
- xargs grep -h '^package ' | sed 's/^package //' | sed 's/;$//' | sort | uniq | tr "\n" " ")
-all_test_packages="$all_test_packages tests.api.org.w3c.dom"
-
-# Use the list of packages supplied on the command-line, if any.
-test_packages=${*:-$all_test_packages}
-
-echo "Running tests for following test packages:"
-echo $test_packages | tr " " "\n"
-
-$VOGAR \
- --vm-arg -Xmx32M \
- --classpath out/target/common/obj/JAVA_LIBRARIES/core-tests_intermediates/classes.jack \
- --classpath out/target/common/obj/JAVA_LIBRARIES/sqlite-jdbc_intermediates/classes.jack \
- --classpath out/target/common/obj/JAVA_LIBRARIES/bouncycastle_intermediates/classes.jack \
- --classpath out/target/common/obj/JAVA_LIBRARIES/okhttp_intermediates/classes.jack \
- $test_packages \
- || true
diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java
index a9d60da..3ca3501 100644
--- a/support/src/test/java/libcore/java/security/StandardNames.java
+++ b/support/src/test/java/libcore/java/security/StandardNames.java
@@ -264,6 +264,7 @@
provide("SSLContext", "TLSv1");
provide("SSLContext", "TLSv1.1");
provide("SSLContext", "TLSv1.2");
+ provide("SSLContext", "TLSv1.3");
provide("SecretKeyFactory", "DES");
provide("SecretKeyFactory", "DESede");
provide("SecretKeyFactory", "PBEWithMD5AndDES");
@@ -683,7 +684,8 @@
public static final Set<String> SSL_SOCKET_PROTOCOLS = new HashSet<String>(Arrays.asList(
"TLSv1",
"TLSv1.1",
- "TLSv1.2"));
+ "TLSv1.2",
+ "TLSv1.3"));
public static final Set<String> SSL_SOCKET_PROTOCOLS_CLIENT_DEFAULT =
new HashSet<String>(Arrays.asList(
"TLSv1",
@@ -710,11 +712,13 @@
}
}
- private static enum TLSVersion {
+ private enum TLSVersion {
SSLv3("SSLv3"),
TLSv1("TLSv1"),
TLSv11("TLSv1.1"),
- TLSv12("TLSv1.2");
+ TLSv12("TLSv1.2"),
+ TLSv13("TLSv1.3"),
+ ;
private final String name;
@@ -735,8 +739,9 @@
/**
* Valid values for X509TrustManager.checkServerTrusted authType,
- * either key exchange algorithm part of the cipher suite
- * or UNKNOWN.
+ * either key exchange algorithm part of the cipher suite, UNKNOWN,
+ * or GENERIC (for TLS 1.3 cipher suites that don't imply a specific
+ * key exchange method).
*/
public static final Set<String> SERVER_AUTH_TYPES = new HashSet<String>(Arrays.asList(
"DHE_DSS",
@@ -756,7 +761,8 @@
"ECDH_RSA",
"ECDHE_ECDSA",
"ECDHE_RSA",
- "UNKNOWN"));
+ "UNKNOWN",
+ "GENERIC"));
public static final String CIPHER_SUITE_INVALID = "SSL_NULL_WITH_NULL_NULL";
@@ -796,21 +802,26 @@
addBoth( "SSL_RSA_WITH_3DES_EDE_CBC_SHA");
// TLSv1.2 cipher suites
- addBoth( "TLS_RSA_WITH_AES_128_CBC_SHA256");
- addBoth( "TLS_RSA_WITH_AES_256_CBC_SHA256");
+ addRi( "TLS_RSA_WITH_AES_128_CBC_SHA256");
+ addRi( "TLS_RSA_WITH_AES_256_CBC_SHA256");
addOpenSsl("TLS_RSA_WITH_AES_128_GCM_SHA256");
addOpenSsl("TLS_RSA_WITH_AES_256_GCM_SHA384");
- addBoth( "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256");
- addBoth( "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384");
+ addRi( "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256");
+ addRi( "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384");
addOpenSsl("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
addOpenSsl("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384");
- addBoth( "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256");
- addBoth( "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384");
+ addRi( "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256");
+ addRi( "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384");
addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256");
addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384");
addOpenSsl("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256");
addOpenSsl("TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256");
+ // TLSv1.3 cipher suites
+ addOpenSsl("TLS_AES_128_GCM_SHA256");
+ addOpenSsl("TLS_AES_256_GCM_SHA384");
+ addOpenSsl("TLS_CHACHA20_POLY1305_SHA256");
+
// Pre-Shared Key (PSK) cipher suites
addOpenSsl("TLS_PSK_WITH_AES_128_CBC_SHA");
addOpenSsl("TLS_PSK_WITH_AES_256_CBC_SHA");
@@ -943,6 +954,14 @@
"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"
);
+ /**
+ * Cipher suites that are only supported with TLS 1.3.
+ */
+ public static final List<String> CIPHER_SUITES_TLS13 = Arrays.asList(
+ "TLS_AES_128_GCM_SHA256",
+ "TLS_AES_256_GCM_SHA384",
+ "TLS_CHACHA20_POLY1305_SHA256");
+
// NOTE: This list needs to be kept in sync with Javadoc of javax.net.ssl.SSLSocket and
// javax.net.ssl.SSLEngine.
private static final List<String> CIPHER_SUITES_ANDROID_AES_HARDWARE = Arrays.asList(
diff --git a/support/src/test/java/libcore/java/security/TestKeyStore.java b/support/src/test/java/libcore/java/security/TestKeyStore.java
index be9874f..691bdf3 100644
--- a/support/src/test/java/libcore/java/security/TestKeyStore.java
+++ b/support/src/test/java/libcore/java/security/TestKeyStore.java
@@ -693,13 +693,13 @@
String keyAlgorithm = privateKey.getAlgorithm();
String signatureAlgorithm;
if (keyAlgorithm.equals("RSA")) {
- signatureAlgorithm = "sha1WithRSA";
+ signatureAlgorithm = "sha256WithRSA";
} else if (keyAlgorithm.equals("DSA")) {
- signatureAlgorithm = "sha1WithDSA";
+ signatureAlgorithm = "sha256WithDSA";
} else if (keyAlgorithm.equals("EC")) {
- signatureAlgorithm = "sha1WithECDSA";
+ signatureAlgorithm = "sha256WithECDSA";
} else if (keyAlgorithm.equals("EC_RSA")) {
- signatureAlgorithm = "sha1WithRSA";
+ signatureAlgorithm = "sha256WithRSA";
} else {
throw new IllegalArgumentException("Unknown key algorithm " + keyAlgorithm);
}
diff --git a/tools/upstream/src/main/java/libcore/CompareUpstreams.java b/tools/upstream/src/main/java/libcore/CompareUpstreams.java
index fa6bd4f..e3504ae 100644
--- a/tools/upstream/src/main/java/libcore/CompareUpstreams.java
+++ b/tools/upstream/src/main/java/libcore/CompareUpstreams.java
@@ -16,7 +16,8 @@
package libcore;
-import java.io.*;
+import java.io.IOException;
+import java.io.PrintStream;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
@@ -119,45 +120,6 @@
return escapeTsv(String.join("\n", result));
}
- /**
- * Computes the edit distance of two lists, i.e. the smallest number of list items to delete,
- * insert or replace that would transform the content of one list into the other.
- */
- private <T> int editDistance(List<T> a, List<T> b) {
- int numB = b.size();
- int[] prevCost = new int[numB + 1];
- for (int i = 0; i <= numB; i++) {
- prevCost[i] = i;
- }
- int[] curCost = new int[numB + 1];
- for (int endA = 1; endA <= a.size(); endA++) {
- // For each valid index i, prevCost[i] is the edit distance between
- // a.subList(0, endA-1) and b.sublist(0, i).
- // We now calculate curCost[end_b] as the edit distance between
- // a.subList(0, endA) and b.subList(0, endB)
- curCost[0] = endA;
- for (int endB = 1; endB <= numB; endB++) {
- boolean endsMatch = a.get(endA - 1).equals(b.get(endB - 1));
- curCost[endB] = min(
- curCost[endB - 1] + 1, // append item from b
- prevCost[endB] + 1, // append item from a
- prevCost[endB - 1] + (endsMatch ? 0 : 1)); // match or replace item
- }
- int[] tmp = curCost;
- curCost = prevCost;
- prevCost = tmp;
- }
- return prevCost[numB];
- }
-
- private static int min(int a, int b, int c) {
- if (a < b) {
- return a < c ? a : c;
- } else {
- return b < c ? b : c;
- }
- }
-
private static String escapeTsv(String value) {
if (value.contains("\t")) {
throw new IllegalArgumentException(value); // tsv doesn't support escaping tabs
@@ -190,7 +152,8 @@
headers.add("diff");
printTsv(out, headers);
for (Path relPath : relPaths) {
- Repository expectedUpstream = standardRepositories.currentUpstream(relPath);
+ Repository expectedUpstream = standardRepositories.referenceUpstreamAsOfAndroidP(
+ relPath);
out.print(relPath + "\t");
Path ojluniFile = standardRepositories.ojluni().absolutePath(relPath);
List<String> linesB = Util.readLines(ojluniFile);
@@ -207,7 +170,7 @@
comparison = "missing";
} else {
List<String> linesA = Util.readLines(upstreamFile);
- int distance = editDistance(linesA, linesB);
+ int distance = Util.editDistance(linesA, linesB);
if (distance == 0) {
comparison = "identical";
} else {
@@ -230,7 +193,8 @@
if (!comparisons.get(0).equals("identical")) {
Path expectedUpstreamPath = expectedUpstream.pathFromRepository(relPath);
if (expectedUpstreamPath != null) {
- diffCommand = "${ANDROID_BUILD_TOP}/libcore/tools/upstream/upstream-diff " + relPath;
+ diffCommand = "${ANDROID_BUILD_TOP}/libcore/tools/upstream/upstream-diff "
+ + "-r ojluni," + expectedUpstream.name() + " " + relPath;
} else {
diffCommand = "FILE MISSING";
}
@@ -246,7 +210,7 @@
}
public void run() throws IOException {
- List<Path> relPaths = standardRepositories.ojluni().loadRelPathsFromMakefile();
+ List<Path> relPaths = standardRepositories.ojluni().loadRelPathsFromBlueprint();
run(System.out, relPaths);
}
diff --git a/tools/upstream/src/main/java/libcore/CopyUpstreamFiles.java b/tools/upstream/src/main/java/libcore/CopyUpstreamFiles.java
index 007914f..7137861 100644
--- a/tools/upstream/src/main/java/libcore/CopyUpstreamFiles.java
+++ b/tools/upstream/src/main/java/libcore/CopyUpstreamFiles.java
@@ -20,7 +20,6 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -36,7 +35,7 @@
}
public void run() throws IOException {
- List<Path> relPaths = standardRepositories.ojluni().loadRelPathsFromMakefile();
+ List<Path> relPaths = standardRepositories.ojluni().loadRelPathsFromBlueprint();
if (outputDir.toFile().exists()) {
throw new IOException(outputDir + " already exists");
} else {
@@ -46,7 +45,8 @@
}
}
for (Path relPath : relPaths) {
- Repository expectedUpstream = standardRepositories.currentUpstream(relPath);
+ Repository expectedUpstream = standardRepositories.referenceUpstreamAsOfAndroidP(
+ relPath);
for (Repository upstream : standardRepositories.upstreams()) {
Path upstreamFile = upstream.absolutePath(relPath);
if (upstreamFile != null) {
diff --git a/tools/upstream/src/main/java/libcore/Lines.java b/tools/upstream/src/main/java/libcore/Lines.java
new file mode 100644
index 0000000..c60fd0b
--- /dev/null
+++ b/tools/upstream/src/main/java/libcore/Lines.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 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;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.RandomAccess;
+
+/**
+ * A List of lines (eg. from a text file or a command's output).
+ */
+public class Lines extends AbstractList<String> implements RandomAccess {
+ public static Lines EMPTY = new Lines(Collections.emptyList());
+
+ private final List<String> delegate;
+ private volatile int hashCode = 0;
+
+ public Lines(Collection<String> collection) {
+ this.delegate = new ArrayList<>(collection);
+ }
+
+ @Override
+ public int hashCode() {
+ if (hashCode == 0) {
+ hashCode = super.hashCode();
+ }
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o.hashCode() != this.hashCode()) {
+ return false;
+ }
+ return super.equals(o);
+ }
+
+ @Override
+ public Iterator<String> iterator() {
+ return Collections.unmodifiableList(delegate).iterator();
+ }
+
+ @Override
+ public String get(int index) {
+ return delegate.get(index);
+ }
+
+ @Override
+ public int size() {
+ return delegate.size();
+ }
+}
diff --git a/tools/upstream/src/main/java/libcore/Repository.java b/tools/upstream/src/main/java/libcore/Repository.java
index 9a4eee6..89f64f0 100644
--- a/tools/upstream/src/main/java/libcore/Repository.java
+++ b/tools/upstream/src/main/java/libcore/Repository.java
@@ -23,7 +23,9 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -33,12 +35,50 @@
*/
abstract class Repository {
+ /**
+ * Maps from a file's (current) relPath to the corresponding OpenJDK relPath from
+ * which it has been, and still remains, renamed.
+ */
+ static final Map<Path, Path> OPENJDK_REL_PATH = historicRenames();
+
+ static Map<Path, Path> historicRenames() {
+ Map<Path, Path> result = new HashMap<>();
+ // renamed in libcore commit 583eb0e4738456f0547014a4857a14456be267ee
+ result.put(Paths.get("native/linux_close.cpp"), Paths.get("native/linux_close.c"));
+ // Map ByteBufferAs*Buffer.java to an upstream file, even though there is
+ // not a 1:1 correspondence. This isn't perfect, but allows some rough
+ // comparison. See http://b/111583940
+ //
+ // More detail:
+ // The RI has four different generated files ...Buffer{B,L,RB,RL}.java
+ // for each of these six files specializing on big endian, little endian,
+ // read-only big endian, and read-only little endian, respectively. Those
+ // 6 x 4 files are generated from a single template:
+ // java/nio/ByteBufferAs-X-Buffer.java.template
+ //
+ // On Android, the four variants {B,L,RB,RL} for each of the six types
+ // are folded into a single class with behavior configured via additional
+ // constructor arguments.
+ //
+ // For now, we map to upstream's "B" variant; "B" is more similar to
+ // Android's files than "RB" or "RL"; the choice of "B" vs. "L" is arbitrary.
+ for (String s : Arrays.asList("Char", "Double", "Float", "Int", "Long", "Short")) {
+ Path ojluniPath = Paths.get("java/nio/ByteBufferAs" + s + "Buffer.java");
+ Path upstreamPath =
+ Paths.get("java/nio/ByteBufferAs" + s + "BufferB.java");
+ result.put(ojluniPath, upstreamPath);
+ }
+ return Collections.unmodifiableMap(result);
+ }
+
protected final Path rootPath;
protected final String name;
+ protected final List<String> sourceDirs;
- protected Repository(Path rootPath, String name) {
+ protected Repository(Path rootPath, String name, List<String> sourceDirs) {
this.rootPath = Objects.requireNonNull(rootPath);
this.name = Objects.requireNonNull(name);
+ this.sourceDirs = Objects.requireNonNull(sourceDirs);
if (!rootPath.toFile().isDirectory()) {
throw new IllegalArgumentException("Missing or not a directory: " + rootPath);
}
@@ -55,7 +95,31 @@
return p == null ? null : rootPath.resolve(p).toAbsolutePath();
}
- public abstract Path pathFromRepository(Path relPath);
+ public Path pathFromRepository(Path relPath) {
+ // Search across all sourceDirs for the indicated file.
+ for (String sourceDir : sourceDirs) {
+ Path repositoryRelativePath = Paths.get(sourceDir).resolve(relPath);
+ File file = rootPath.resolve(repositoryRelativePath).toFile();
+ if (file.exists()) {
+ return repositoryRelativePath;
+ }
+ }
+ return null;
+ }
+
+ public final Path rootPath() {
+ return rootPath;
+ }
+
+ @Override
+ public int hashCode() {
+ return rootPath.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return (obj instanceof Repository) && rootPath.equals(((Repository) obj).rootPath);
+ }
/**
* @return A human readable name to identify this repository, suitable for use as a
@@ -76,18 +140,26 @@
*/
public static Repository openJdk9(Path upstreamRoot, String upstreamName) {
List<String> sourceDirs = Arrays.asList(
- "jdk/src/java.base/share/classes",
- "jdk/src/java.logging/share/classes",
- "jdk/src/java.prefs/share/classes",
- "jdk/src/java.sql/share/classes",
- "jdk/src/java.desktop/share/classes",
- "jdk/src/java.base/solaris/classes",
- "jdk/src/java.base/unix/classes",
- "jdk/src/java.prefs/unix/classes",
- "jdk/src/jdk.unsupported/share/classes",
- "jdk/src/jdk.net/share/classes",
- "jdk/src/java.base/linux/classes",
- "build/linux-x86_64-normal-server-release/support/gensrc/java.base"
+ "jdk/src/java.base/share/classes",
+ "jdk/src/java.logging/share/classes",
+ "jdk/src/java.prefs/share/classes",
+ "jdk/src/java.sql/share/classes",
+ "jdk/src/java.desktop/share/classes",
+ "jdk/src/java.base/solaris/classes",
+ "jdk/src/java.base/unix/classes",
+ "jdk/src/java.prefs/unix/classes",
+ "jdk/src/jdk.unsupported/share/classes",
+ "jdk/src/jdk.net/share/classes",
+ "jdk/src/java.base/linux/classes",
+ "build/linux-x86_64-normal-server-release/support/gensrc/java.base",
+
+ // Native (.c) files
+ "jdk/src/java.base/unix/native/libjava",
+ "jdk/src/java.base/share/native/libjava",
+ "jdk/src/java.base/unix/native/libnio",
+ "jdk/src/java.base/unix/native/libnio/ch",
+ "jdk/src/java.base/unix/native/libnio/fs",
+ "jdk/src/java.base/unix/native/libnet"
);
return new OpenJdkRepository(upstreamRoot, upstreamName, sourceDirs);
}
@@ -97,11 +169,27 @@
* subdirectory {@code upstreamName} under the directory {@code upstreamRoot}.
*/
public static Repository openJdkLegacy(Path upstreamRoot, String upstreamName) {
- List<String> sourceDirs = Arrays.asList(
- "jdk/src/share/classes",
- "jdk/src/solaris/classes",
- "build/linux-x86_64-normal-server-release/jdk/gensrc"
- );
+ List<String> sourceDirs = new ArrayList<>();
+ sourceDirs.addAll(Arrays.asList(
+ "jdk/src/share/classes",
+ "jdk/src/solaris/classes",
+ "build/linux-x86_64-normal-server-release/jdk/gensrc"
+ ));
+
+ // In legacy OpenJDK versions, the source files are organized into a subfolder
+ // hierarchy based on package name, whereas in Android and OpenJDK 9+ they're in
+ // a flat folder. We work around this by just searching through all of the
+ // applicable folders (from which we have sources) in legacy OpenJDK versions.
+ List<String> nativeSourceDirs = new ArrayList<>();
+ List<String> pkgPaths = Arrays.asList("", "java/io", "java/lang", "java/net", "java/nio",
+ "java/util", "java/util/zip", "sun/nio/ch", "sun/nio/fs");
+ for (String pkgPath : pkgPaths) {
+ nativeSourceDirs.add("jdk/src/solaris/native/" + pkgPath);
+ nativeSourceDirs.add("jdk/src/share/native/" + pkgPath);
+ nativeSourceDirs.add("jdk/src/solaris/native/common/" + pkgPath);
+ nativeSourceDirs.add("jdk/src/share/native/common/" + pkgPath);
+ }
+ sourceDirs.addAll(nativeSourceDirs);
return new OpenJdkRepository(upstreamRoot, upstreamName, sourceDirs);
}
@@ -120,7 +208,6 @@
}
static class OjluniRepository extends Repository {
-
/**
* The repository of ojluni java files belonging to the Android sources under
* {@code buildTop}.
@@ -129,29 +216,42 @@
* {@quote ANDROID_BUILD_TOP} environment variable.
*/
public OjluniRepository(Path buildTop) {
- super(buildTop.resolve("libcore"), "ojluni");
+ super(buildTop.resolve("libcore"), "ojluni",
+ /* sourceDirs */ Arrays.asList("ojluni/src/main/java", "ojluni/src/main/native"));
}
@Override
public Path pathFromRepository(Path relPath) {
- return Paths.get("ojluni/src/main/java").resolve(relPath);
+ // Enforce that the file exists in ojluni
+ return Objects.requireNonNull(super.pathFromRepository(relPath));
}
/**
- * Returns the list of relative paths to .java files parsed from openjdk_java_files.mk
+ * Returns the list of relative paths to files parsed from blueprint files.
*/
- public List<Path> loadRelPathsFromMakefile() throws IOException {
+ public List<Path> loadRelPathsFromBlueprint() throws IOException {
List<Path> result = new ArrayList<>();
- Path makefile = rootPath.resolve("openjdk_java_files.bp");
- Pattern pattern = Pattern.compile("\"ojluni/src/main/java/(.+\\.java)\"");
- for (String line : Util.readLines(makefile)) {
+ result.addAll(loadRelPathsFromBlueprint(
+ "openjdk_java_files.bp", "\"ojluni/src/main/java/(.+\\.java)\""));
+ result.addAll(loadRelPathsFromBlueprint(
+ "ojluni/src/main/native/Android.bp", "\\s+\"(.+\\.(?:c|cpp))\","));
+ return result;
+ }
+
+ private List<Path> loadRelPathsFromBlueprint(
+ String blueprintPathString, String patternString) throws IOException {
+ Path blueprintPath = rootPath.resolve(blueprintPathString);
+ Pattern pattern = Pattern.compile(patternString);
+ List<Path> result = new ArrayList<>();
+ for (String line : Util.readLines(blueprintPath)) {
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
- Path path = new File(matcher.group(1)).toPath();
- result.add(path);
+ Path relPath = Paths.get(matcher.group(1));
+ result.add(relPath);
}
}
+ Collections.sort(result);
return result;
}
@@ -162,23 +262,17 @@
}
static class OpenJdkRepository extends Repository {
- private final List<String> sourceDirs;
public OpenJdkRepository(Path upstreamRoot, String name, List<String> sourceDirs) {
- super(upstreamRoot.resolve(name), name);
- this.sourceDirs = Objects.requireNonNull(sourceDirs);
+ super(upstreamRoot.resolve(name), name, sourceDirs);
}
@Override
public Path pathFromRepository(Path relPath) {
- for (String sourceDir : sourceDirs) {
- Path repositoryRelativePath = Paths.get(sourceDir).resolve(relPath);
- Path file = rootPath.resolve(repositoryRelativePath);
- if (file.toFile().exists()) {
- return repositoryRelativePath;
- }
+ if (OPENJDK_REL_PATH.containsKey(relPath)) {
+ relPath = OPENJDK_REL_PATH.get(relPath);
}
- return null;
+ return super.pathFromRepository(relPath);
}
@Override
@@ -187,5 +281,4 @@
}
}
-
}
diff --git a/tools/upstream/src/main/java/libcore/StandardRepositories.java b/tools/upstream/src/main/java/libcore/StandardRepositories.java
index 36478dd..3bdbebf 100644
--- a/tools/upstream/src/main/java/libcore/StandardRepositories.java
+++ b/tools/upstream/src/main/java/libcore/StandardRepositories.java
@@ -22,6 +22,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import libcore.Repository.OjluniRepository;
@@ -31,18 +32,34 @@
public class StandardRepositories {
+ private final List<Repository> allUpstreams;
+ // upstreams older than what is currently the default
private final List<Repository> historicUpstreams;
- private final Repository defaultUpstream;
- private final Repository jsr166Upstream;
+ private final Repository openJdk8u121;
+ private final Repository openJdk9b113;
+ private final Repository openJdk7u40;
private final OjluniRepository ojluni;
private StandardRepositories(Path buildTop, Path upstreamRoot) {
- this.historicUpstreams = openJdkLegacy(upstreamRoot, Arrays.asList("8u60", "7u40"));
- this.defaultUpstream = openJdkLegacy(upstreamRoot, "8u121-b13");
- this.jsr166Upstream = openJdk9(upstreamRoot, "9b113+");
+ // allUpstreams is ordered from latest to earliest
+ Set<Repository> allUpstreams = new LinkedHashSet<>();
+ allUpstreams.add(openJdk9(upstreamRoot, "9+181"));
+ this.openJdk9b113 = addAndReturn(allUpstreams, openJdk9(upstreamRoot, "9b113+"));
+ this.openJdk8u121 = addAndReturn(allUpstreams, openJdkLegacy(upstreamRoot, "8u121-b13"));
+ Repository openJdk8u60 = addAndReturn(allUpstreams, openJdkLegacy(upstreamRoot, "8u60"));
+ this.openJdk7u40 = addAndReturn(allUpstreams, openJdkLegacy(upstreamRoot, "7u40"));
+ this.allUpstreams = Collections.unmodifiableList(new ArrayList<>(allUpstreams));
+ this.historicUpstreams = Collections.unmodifiableList(new ArrayList<>(
+ Arrays.asList(openJdk8u60, openJdk7u40)
+ ));
this.ojluni = new OjluniRepository(buildTop);
}
+ private static Repository addAndReturn(Set<Repository> repositories, Repository repository) {
+ repositories.add(repository);
+ return repository;
+ }
+
public List<Repository> historicUpstreams() {
return historicUpstreams;
}
@@ -55,10 +72,7 @@
* Returns all upstream repository snapshots, in order from latest to earliest.
*/
public List<Repository> upstreams() {
- List<Repository> upstreams = new ArrayList<>(Arrays.asList(
- jsr166Upstream, defaultUpstream));
- upstreams.addAll(historicUpstreams);
- return Collections.unmodifiableList(upstreams);
+ return allUpstreams;
}
public static StandardRepositories fromEnv() {
@@ -89,18 +103,29 @@
"SplittableRandom"
)));
- public Repository currentUpstream(Path relPath) {
- boolean isJsr166 = relPath.toString().startsWith("java/util/concurrent");
+ public boolean isJsr166(Path relPath) {
+ boolean result = relPath.startsWith("java/util/concurrent/");
String ju = "java/util/";
String suffix = ".java";
- if (!isJsr166 && relPath.startsWith(ju)) {
+ if (!result && relPath.startsWith(ju)) {
String name = relPath.toString().substring(ju.length());
if (name.endsWith(suffix)) {
name = name.substring(0, name.length() - suffix.length());
- isJsr166 = juFilesFromJsr166.contains(name);
+ result = juFilesFromJsr166.contains(name);
}
}
- return isJsr166 ? jsr166Upstream : defaultUpstream;
+ return result;
+ }
+
+ public Repository referenceUpstreamAsOfAndroidP(Path relPath) {
+ boolean isJsr166 = isJsr166(relPath);
+ if (isJsr166) {
+ return openJdk9b113;
+ } else if (relPath.startsWith("java/sql/") || relPath.startsWith("javax/sql/")) {
+ return openJdk7u40;
+ } else {
+ return openJdk8u121;
+ }
}
}
diff --git a/tools/upstream/src/main/java/libcore/Util.java b/tools/upstream/src/main/java/libcore/Util.java
index d213080..c50e990 100644
--- a/tools/upstream/src/main/java/libcore/Util.java
+++ b/tools/upstream/src/main/java/libcore/Util.java
@@ -17,25 +17,90 @@
package libcore;
import java.io.BufferedReader;
+import java.io.BufferedWriter;
import java.io.FileReader;
+import java.io.FileWriter;
import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
+/**
+ * Utilities for dealing with text file contents.
+ */
class Util {
private Util() {
}
- public static List<String> readLines(Path path) throws IOException {
+ public static Lines readLines(Reader reader) throws IOException {
List<String> result = new ArrayList<>();
- try (BufferedReader reader = new BufferedReader(new FileReader(path.toFile()))) {
- String line;
- while ((line = reader.readLine()) != null) {
- result.add(line);
+ BufferedReader br = (reader instanceof BufferedReader)
+ ? (BufferedReader) reader : new BufferedReader(reader);
+ String line;
+ while ((line = br.readLine()) != null) {
+ result.add(line);
+ }
+ return new Lines(result);
+ }
+
+ public static Lines readLines(Path path) throws IOException {
+ try (Reader reader = new FileReader(path.toFile())) {
+ return readLines(reader);
+ }
+ }
+
+ public static void writeLines(Path path, Lines lines) throws IOException {
+ try (PrintStream printStream = new PrintStream(path.toFile())) {
+ for (String line : lines) {
+ printStream.println(line);
}
}
- return result;
+ }
+
+ /**
+ * Computes the edit distance of two lists, i.e. the smallest number of list items to delete,
+ * insert or replace that would transform the content of one list into the other.
+ */
+ public static <T> int editDistance(List<T> a, List<T> b) {
+ if (a.equals(b)) {
+ return 0;
+ }
+ int numB = b.size();
+ int[] prevCost = new int[numB + 1];
+ for (int i = 0; i <= numB; i++) {
+ prevCost[i] = i;
+ }
+ int[] curCost = new int[numB + 1];
+ for (int endA = 1; endA <= a.size(); endA++) {
+ // For each valid index i, prevCost[i] is the edit distance between
+ // a.subList(0, endA-1) and b.sublist(0, i).
+ // We now calculate curCost[end_b] as the edit distance between
+ // a.subList(0, endA) and b.subList(0, endB)
+ curCost[0] = endA;
+ for (int endB = 1; endB <= numB; endB++) {
+ boolean endsMatch = a.get(endA - 1).equals(b.get(endB - 1));
+ curCost[endB] = min(
+ curCost[endB - 1] + 1, // append item from b
+ prevCost[endB] + 1, // append item from a
+ prevCost[endB - 1] + (endsMatch ? 0 : 1)); // match or replace item
+ }
+ int[] tmp = curCost;
+ curCost = prevCost;
+ prevCost = tmp;
+ }
+ return prevCost[numB];
+ }
+
+ private static int min(int a, int b, int c) {
+ if (a < b) {
+ return a < c ? a : c;
+ } else {
+ return b < c ? b : c;
+ }
}
}
diff --git a/tools/upstream/upstream-diff b/tools/upstream/upstream-diff
index f52fdb5..b689b33 100755
--- a/tools/upstream/upstream-diff
+++ b/tools/upstream/upstream-diff
@@ -51,6 +51,8 @@
import argparse
import os
+import os.path
+import re
import subprocess
import sys
@@ -60,27 +62,39 @@
# Root of repository snapshots. See go/libcore-o-verify for how you'd want to set this.
ojluni_upstreams = os.environ['OJLUNI_UPSTREAMS']
for rel_path in rel_paths:
- if not rel_path.endswith('.java'):
- # Might be a fully qualified class name
+ # Paths end with a dot and lowercase file extension (.c, .java, ...) but
+ # fully qualified class names do not.
+ if ('/' not in rel_path) and (not re.match('.+\\.[a-z]{1,4}$', rel_path)):
+ # Assume a fully qualified class name
rel_path = rel_path.replace('.', '/') + '.java'
paths = []
for repository in repositories:
- if repository == "ojluni":
- paths.append('%s/libcore/ojluni/src/main/java/%s' % (android_build_top, rel_path))
+ if repository == 'ojluni':
+ file_group = 'java/' if rel_path.endswith('.java') else 'native/'
+ paths.append('%s/libcore/ojluni/src/main/%s/%s'
+ % (android_build_top, file_group, rel_path))
else:
paths.append('%s/%s/%s' % (ojluni_upstreams, repository, rel_path))
subprocess.call([diff] + paths)
def main():
parser = argparse.ArgumentParser(
- description='Compare files between libcore/ojluni and ${OJLUNI_UPSTREAMS}.')
+ description='Compare files between libcore/ojluni and ${OJLUNI_UPSTREAMS}.',
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter, # include default values in help
+ )
+ upstreams = os.environ['OJLUNI_UPSTREAMS']
+ # natsort.natsorted() would be a nicer sort order, but I'd rather avoid the dependency
+ repositories = ['ojluni'] + sorted(
+ [d for d in os.listdir(upstreams) if os.path.isdir(os.path.join(upstreams, d))]
+ )
parser.add_argument('-r', '--repositories', default='ojluni,expected',
- help='Comma-separated list of >= 2 repositories to compare.')
+ help='Comma-separated list of 2-3 repositories, to compare, in order; '
+ 'available repositories: ' + ' '.join(repositories) + '.')
parser.add_argument('-d', '--diff', default='meld',
help='Application to use for diffing.')
parser.add_argument('rel_path', nargs="+",
- help='File to compare: either a relative path below '
- 'libcore/ojluni/src/main/java, or a fully qualified class name.')
+ help='File to compare: either a relative path below libcore/ojluni/'
+ 'src/main/{java,native}, or a fully qualified class name.')
args = parser.parse_args()
repositories = args.repositories.split(',')
if (len(repositories) < 2):
diff --git a/xml/src/main/java/org/kxml2/io/KXmlParser.java b/xml/src/main/java/com/android/org/kxml2/io/KXmlParser.java
similarity index 99%
rename from xml/src/main/java/org/kxml2/io/KXmlParser.java
rename to xml/src/main/java/com/android/org/kxml2/io/KXmlParser.java
index e010f1d..3814e63 100644
--- a/xml/src/main/java/org/kxml2/io/KXmlParser.java
+++ b/xml/src/main/java/com/android/org/kxml2/io/KXmlParser.java
@@ -20,7 +20,7 @@
// Contributors: Paul Hackenberger (unterminated entity handling in relaxed mode)
-package org.kxml2.io;
+package com.android.org.kxml2.io;
import java.io.Closeable;
import java.io.IOException;
diff --git a/xml/src/main/java/org/kxml2/io/KXmlSerializer.java b/xml/src/main/java/com/android/org/kxml2/io/KXmlSerializer.java
similarity index 99%
rename from xml/src/main/java/org/kxml2/io/KXmlSerializer.java
rename to xml/src/main/java/com/android/org/kxml2/io/KXmlSerializer.java
index 25f0924..795448d 100644
--- a/xml/src/main/java/org/kxml2/io/KXmlSerializer.java
+++ b/xml/src/main/java/com/android/org/kxml2/io/KXmlSerializer.java
@@ -19,7 +19,7 @@
* IN THE SOFTWARE. */
-package org.kxml2.io;
+package com.android.org.kxml2.io;
import java.io.*;
import java.util.Locale;
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java b/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
index 7215b3e..6190777 100644
--- a/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
+++ b/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
@@ -37,8 +37,8 @@
serializerClasses = new ArrayList<String>();
try {
- parserClasses.add(Class.forName("org.kxml2.io.KXmlParser"));
- serializerClasses.add(Class.forName("org.kxml2.io.KXmlSerializer"));
+ parserClasses.add(Class.forName("com.android.org.kxml2.io.KXmlParser"));
+ serializerClasses.add(Class.forName("com.android.org.kxml2.io.KXmlSerializer"));
} catch (ClassNotFoundException e) {
throw new AssertionError();
}