Fix and enable proguard on packages.
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 8598e7e..a2acb01 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -351,7 +351,8 @@
   link_instr_intermediates_dir.COMMON := $(call intermediates-dir-for, \
       APPS,$(LOCAL_INSTRUMENTATION_FOR),,COMMON)
 
-  full_java_libs += $(link_instr_intermediates_dir.COMMON)/classes.jar
+  # link against the jar with full original names (before proguard processing).
+  full_java_libs += $(link_instr_intermediates_dir.COMMON)/classes-full-names.jar
 
   # We can't depend on the .jar file, so we depend on something that
   # depends on the jar file; the final built package file.
diff --git a/core/definitions.mk b/core/definitions.mk
index e8d05ac..b9845f8 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -1579,7 +1579,6 @@
 $(copy-file-to-target-strip-comments)
 endef
 
-
 ###########################################################
 ## On some platforms (MacOS), after copying a static
 ## library, ranlib must be run to update an internal
@@ -1608,6 +1607,37 @@
 
 
 ###########################################################
+## Commands to call Proguard
+###########################################################
+
+# Command to copy the file with acp, if proguard is disabled.
+define proguard-disabled-commands
+@echo Copying: $@
+$(hide) $(ACP) $< $@
+endef
+
+# Command to call Proguard
+# $(1): extra flags for instrumentation.
+define proguard-enabled-commands
+@echo Proguard: $@
+$(hide) $(PROGUARD) -injars $< -outjars $@ $(PRIVATE_PROGUARD_FLAGS) $(1)
+endef
+
+# Figure out the proguard dictionary file of the module that is instrumentationed for.
+define get-instrumentation-proguard-flags
+$(if $(PRIVATE_INSTRUMENTATION_FOR),$(if $(ALL_MODULES.$(PRIVATE_INSTRUMENTATION_FOR).PROGUARD_ENABLED),-applymapping $(call intermediates-dir-for,APPS,$(PRIVATE_INSTRUMENTATION_FOR),,COMMON)/proguard_dictionary))
+endef
+
+define transform-jar-to-proguard
+$(eval _instrumentation_proguard_flags:=$(call get-instrumentation-proguard-flags))
+$(eval _enable_proguard:=$(PRIVATE_PROGUARD_ENABLED)$(_instrumentation_proguard_flags))
+$(if $(_enable_proguard),$(call proguard-enabled-commands,$(_instrumentation_proguard_flags)),$(call proguard-disabled-commands))
+$(eval _instrumentation_proguard_flags:=)
+$(eval _enable_proguard:=)
+endef
+
+
+###########################################################
 ## Stuff source generated from one-off tools
 ###########################################################
 
diff --git a/core/java.mk b/core/java.mk
index 65c4c8a..d57ffca 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -70,6 +70,7 @@
 full_classes_emma_jar := $(emma_intermediates_dir)/lib/$(full_classes_compiled_jar_leaf)
 full_classes_stubs_jar := $(intermediates.COMMON)/stubs.jar
 full_classes_jarjar_jar := $(intermediates.COMMON)/classes-jarjar.jar
+full_classes_full_names_jar := $(intermediates.COMMON)/classes-full-names.jar
 full_classes_proguard_jar := $(full_classes_jar)
 built_dex := $(intermediates.COMMON)/classes.dex
 
@@ -193,39 +194,52 @@
 	$(hide) $(ACP) $< $@
 endif
 
+# Keep a copy of the jar just before proguard processing.
+$(full_classes_full_names_jar): $(full_classes_emma_jar) | $(ACP)
+	@echo Copying: $@
+	$(hide) $(ACP) $< $@
+
 # Run proguard if necessary, otherwise just copy the file.  This is the last
 # part of this step, so the output of this command is full_classes_jar.
-ifneq ($(strip $(LOCAL_PROGUARD_ENABLED)),)
 proguard_dictionary := $(intermediates.COMMON)/proguard_dictionary
-proguard_flags := $(addprefix -libraryjars ,$(full_java_libs)) \
+# Proguard doesn't like a class in both library and the jar to be processed.
+proguard_full_java_libs := $(filter-out $(full_static_java_libs),$(full_java_libs))
+proguard_flags := $(addprefix -libraryjars ,$(proguard_full_java_libs)) \
                   -include $(BUILD_SYSTEM)/proguard.flags \
                   -forceprocessing \
                   -printmapping $(proguard_dictionary)
-ifeq ($(strip $(LOCAL_PROGUARD_ENABLED)),full)
+# If this is a test package, add proguard keep flags for tests.
+ifneq ($(strip $(LOCAL_INSTRUMENTATION_FOR)$(filter tests,$(LOCAL_MODULE_TAGS))$(filter android.test.runner,$(LOCAL_JAVA_LIBRARIES))),)
+proguard_flags := $(proguard_flags) -include $(BUILD_SYSTEM)/proguard_tests.flags
+endif # test package
+
+LOCAL_PROGUARD_ENABLED:=$(strip $(LOCAL_PROGUARD_ENABLED))
+ifneq ($(LOCAL_PROGUARD_ENABLED),)
+ifeq ($(LOCAL_PROGUARD_ENABLED),full)
     # full
 else
-ifeq ($(strip $(LOCAL_PROGUARD_ENABLED)),optonly)
+ifeq ($(LOCAL_PROGUARD_ENABLED),optonly)
     # optonly
     proguard_flags += -dontobfuscate
 else
-ifeq ($(strip $(LOCAL_PROGUARD_ENABLED)),custom)
+ifeq ($(LOCAL_PROGUARD_ENABLED),custom)
     # custom
 else
     $(warning while processing: $(LOCAL_MODULE))
     $(error invalid value for LOCAL_PROGUARD_ENABLED: $(LOCAL_PROGUARD_ENABLED))
-endif
-endif
-endif
+endif # custom
+endif # optonly
+endif # full
+endif # LOCAL_PROGUARD_ENABLED
 
+$(full_classes_proguard_jar): PRIVATE_PROGUARD_ENABLED:=$(LOCAL_PROGUARD_ENABLED)
 $(full_classes_proguard_jar): PRIVATE_PROGUARD_FLAGS := $(proguard_flags) $(LOCAL_PROGUARD_FLAGS)
-$(full_classes_proguard_jar): $(full_classes_emma_jar) | $(PROGUARD)
-	@echo Proguard: $@
-	$(hide) $(PROGUARD) -injars $< -outjars $@ $(PRIVATE_PROGUARD_FLAGS)
-else
-$(full_classes_proguard_jar): $(full_classes_emma_jar) | $(ACP)
-	@echo Copying: $@
-	$(hide) $(ACP) $< $@
-endif
+$(full_classes_proguard_jar): PRIVATE_INSTRUMENTATION_FOR:=$(strip $(LOCAL_INSTRUMENTATION_FOR))
+
+$(full_classes_proguard_jar): $(full_classes_full_names_jar) | $(ACP) $(PROGUARD)
+	$(call transform-jar-to-proguard)
+
+ALL_MODULES.$(LOCAL_MODULE).PROGUARD_ENABLED:=$(LOCAL_PROGUARD_ENABLED)
 
 # Override PRIVATE_INTERMEDIATES_DIR so that install-dex-debug
 # will work even when intermediates != intermediates.COMMON.
diff --git a/core/package.mk b/core/package.mk
index 388435a..07bb3f9 100644
--- a/core/package.mk
+++ b/core/package.mk
@@ -126,10 +126,15 @@
 
 LOCAL_BUILT_MODULE_STEM := package.apk
 
-proguard_options_file := $(package_expected_intermediates_COMMON)/proguard_options
-ifneq ($(strip $(LOCAL_PROGUARD_ENABLED)),custom)
-    LOCAL_PROGUARD_FLAGS := -include $(proguard_options_file) $(LOCAL_PROGUARD_FLAGS)
-endif
+LOCAL_PROGUARD_ENABLED:=$(strip $(LOCAL_PROGUARD_ENABLED))
+
+proguard_options_file :=
+ifneq ($(LOCAL_PROGUARD_ENABLED),custom)
+ifneq ($(all_resources),)
+    proguard_options_file := -include $(package_expected_intermediates_COMMON)/proguard_options
+endif # all_resources
+endif # !custom
+LOCAL_PROGUARD_FLAGS := $(proguard_options_file) $(LOCAL_PROGUARD_FLAGS)
 
 # The dex files go in the package, so we don't
 # want to install them separately for this module.
diff --git a/core/proguard.flags b/core/proguard.flags
index afd1548..3544b90 100644
--- a/core/proguard.flags
+++ b/core/proguard.flags
@@ -1,7 +1,54 @@
 # see http://sourceforge.net/tracker/?func=detail&aid=2787465&group_id=54750&atid=474707
 -optimizations !code/simplification/arithmetic
+-optimizations !code/simplification/cast
 -allowaccessmodification
 
+# To prevent name conflict in incremental obfuscation.
+-useuniqueclassmembernames
+
+# dex does not like code run through proguard optimize and preverify steps.
+-dontoptimize
+-dontpreverify
+
+# Don't obfuscate. We only need dead code striping.
+-dontobfuscate
+
+# Add this flag in your package's own configuration if it's needed.
+#-flattenpackagehierarchy
+
 # Some classes in the libraries extend package private classes to chare common functionality
 # that isn't explicitly part of the API
--dontskipnonpubliclibraryclasses
+-dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers
+
+# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
+-keepclassmembers enum * {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+
+# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
+-keepclasseswithmembernames class * {
+    native <methods>;
+}
+
+# class$ methods are inserted by some compilers to implement .class construct,
+# see http://proguard.sourceforge.net/manual/examples.html#library
+-keepclassmembernames class * {
+    java.lang.Class class$(java.lang.String);
+    java.lang.Class class$(java.lang.String, boolean);
+}
+
+# Please specify classes to be kept explicitly in your package's configuration.
+# -keep class * extends android.app.Activity
+# -keep class * extends android.view.View
+# -keep class * extends android.app.Service
+# -keep class * extends android.content.BroadcastReceiver
+# -keep class * extends android.content.ContentProvider
+# -keep class * extends android.preference.Preference
+# -keep class * extends android.app.BackupAgent
+
+#-keep class * implements android.os.Parcelable {
+#  public static final android.os.Parcelable$Creator *;
+#}
+
+
diff --git a/core/proguard_tests.flags b/core/proguard_tests.flags
new file mode 100644
index 0000000..f4063d6
--- /dev/null
+++ b/core/proguard_tests.flags
@@ -0,0 +1,21 @@
+# Keep everything for tests
+-dontshrink -dontobfuscate
+
+#-keep class * extends junit.framework.TestCase {
+#  public void test*();
+#}
+
+#-keepclasseswithmembers class * {
+#  public static void run();
+#  public static junit.framework.Test suite();
+#}
+
+# some AllTests don't include run().
+#-keepclasseswithmembers class * {
+#  public static junit.framework.Test suite();
+#}
+
+#-keep class * extends junit.framework.TestSuite
+#-keep class * extends android.app.Instrumentation
+#-keep class * extends android.test.TestSuiteProvider
+