Add icu4j to core-libart.jar.

The first approach of building icu4j against the SDK and adding that
to the boot classpath won't work out too well. Besides being a bit
of a hack, there's no way to express that relationship for hostdex
builds.

We now compile icu4j sources along with core-libart. This is the most
direct way of expressing this relationship and allows us to include
exactly what we need.

Note that we exclude the locale SPIs, transliterators and charset code
by default.

Change-Id: Idd305e77480bc681ed5b47e740dfec20d3bc7b26
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index 99b4232..553cbbb 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -69,14 +69,40 @@
 local_javac_flags+=-Xmaxwarns 9999999
 
 #
+# ICU4J related rules.
+#
+# We compile icu4j along with core-libart because we're implementing parts of core-libart
+# in terms of icu4j.
+icu4j_root := ../external/icu/icu4j/
+icu4j_src_files := $(call all-java-files-under,$(icu4j_root)/main/classes))
+
+# Filter out bits of ICU4J we don't use yet : the SPIs (which we have limited support for),
+# the charset encoders and the translitertors.
+icu4j_src_files := $(filter-out $(icu4j_root)/main/classes/localespi/%, $(icu4j_src_files))
+icu4j_src_files := $(filter-out $(icu4j_root)/main/classes/charset/%, $(icu4j_src_files))
+icu4j_src_files := $(filter-out $(icu4j_root)/main/classes/translit/%, $(icu4j_src_files))
+
+# Not all src dirs contain resources, some instead contain other random files
+# that should not be included as resources. The ones that should be included
+# can be identifed by the fact that they contain particular subdir trees.
+#
+define all-icu-subdir-with-subdir
+$(patsubst $(LOCAL_PATH)/%/$(2),%,$(wildcard $(LOCAL_PATH)/$(1)/$(2)))
+endef
+
+icu4j_resource_dirs := \
+    $(filter-out $(icu4j_root)/main/classes/localespi/%, \
+    $(call all-icu-subdir-with-subdir,$(icu4j_root)/main/classes/*/src,com/ibm/icu))
+
+#
 # Build for the target (device).
 #
 
 # Definitions to make the core library.
 
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(libart_core_src_files)
-LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
+LOCAL_SRC_FILES := $(libart_core_src_files) $(icu4j_src_files)
+LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs) $(icu4j_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
 LOCAL_JAVACFLAGS := $(local_javac_flags)
 LOCAL_DX_FLAGS := --core-library
@@ -84,8 +110,19 @@
 LOCAL_MODULE := core-libart
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
 LOCAL_REQUIRED_MODULES := tzdata
+LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt
 include $(BUILD_JAVA_LIBRARY)
 
+# Path to the ICU4C data files in the Android device file system:
+icu4c_data := /system/usr/icu
+# TODO: It's quite hideous that this double-slash between icu4j and main is required.
+# It's because we provide a variable substition of the make-rule generated jar command
+# to substitute a processed ICUProperties.config file in place of the original.
+#
+# We can avoid this by filtering out ICUConfig.properties from our list of resources.
+icu4j_config_root := $(LOCAL_PATH)/../external/icu/icu4j//main/classes/core/src
+include external/icu/icu4j/adjust_icudt_path.mk
+
 ifeq ($(LIBCORE_SKIP_TESTS),)
 # Make the core-tests library.
 include $(CLEAR_VARS)
@@ -140,8 +177,8 @@
 
 # Definitions to make the core library.
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(libart_core_src_files)
-LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
+LOCAL_SRC_FILES := $(libart_core_src_files) $(icu4j_src_files)
+LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs) $(icu4j_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
 LOCAL_JAVACFLAGS := $(local_javac_flags)
 LOCAL_DX_FLAGS := --core-library
@@ -149,6 +186,7 @@
 LOCAL_MODULE := core-libart-hostdex
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
 LOCAL_REQUIRED_MODULES := tzdata-host
+LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt
 include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
 
 # Make the core-tests library.
diff --git a/benchmarks/Android.mk b/benchmarks/Android.mk
index e396766..9e650918 100644
--- a/benchmarks/Android.mk
+++ b/benchmarks/Android.mk
@@ -21,8 +21,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := benchmarks
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
-# TODO: Remove icu4j from this deps list once it's in the boot classpath.
-LOCAL_STATIC_JAVA_LIBRARIES := caliper-prebuilt mockwebserver core-tests-support icu4j
+LOCAL_STATIC_JAVA_LIBRARIES := caliper-prebuilt mockwebserver core-tests-support
 LOCAL_NO_STANDARD_LIBRARIES := true
 LOCAL_JAVA_LIBRARIES := core-libart conscrypt core-junit bouncycastle framework
 LOCAL_MODULE_TAGS := tests
diff --git a/benchmarks/src/benchmarks/regression/BreakIteratorBenchmark.java b/benchmarks/src/benchmarks/regression/BreakIteratorBenchmark.java
index 1dcafa6..b58077d 100644
--- a/benchmarks/src/benchmarks/regression/BreakIteratorBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/BreakIteratorBenchmark.java
@@ -61,10 +61,11 @@
 
     public void timeIcuBreakIterator(int nreps) {
         for (int i = 0; i < nreps; ++i) {
-            com.ibm.icu.text.BreakIterator it = com.ibm.icu.text.BreakIterator.getLineInstance(text.locale);
+            com.android.ibm.icu.text.BreakIterator it =
+                com.android.ibm.icu.text.BreakIterator.getLineInstance(text.locale);
             it.setText(text.text);
 
-            while (it.next() != com.ibm.icu.text.BreakIterator.DONE) {
+            while (it.next() != com.android.ibm.icu.text.BreakIterator.DONE) {
             }
         }
     }
diff --git a/jarjar-rules.txt b/jarjar-rules.txt
new file mode 100644
index 0000000..4f0e036
--- /dev/null
+++ b/jarjar-rules.txt
@@ -0,0 +1 @@
+rule com.ibm.icu.** com.android.ibm.icu.@1