Bug 709230 - Part 5: activate Proguard. r=gbrown,rnewman
authorChris Kitching <ckitching@mozilla.com>
Mon, 18 Nov 2013 17:30:00 -0800
changeset 173100 56161051f7fcc5ea80027bfca7b6dbe48a1e408c
parent 173099 43b8117acefc07161378b637226c3811330a431b
child 173101 63f2a21f15fa330995b63b28a0ce8d950e3bb9ca
push id3224
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:06:49 +0000
treeherdermozilla-beta@60c04d0987f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgbrown, rnewman
bugs709230
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 709230 - Part 5: activate Proguard. r=gbrown,rnewman
build/autoconf/android.m4
js/src/build/autoconf/android.m4
mobile/android/base/Makefile.in
mobile/android/config/proguard.cfg
widget/android/AndroidBridge.cpp
--- a/build/autoconf/android.m4
+++ b/build/autoconf/android.m4
@@ -254,16 +254,18 @@ AC_SUBST([STLPORT_LIBS])
 AC_DEFUN([MOZ_ANDROID_SDK],
 [
 
 MOZ_ARG_WITH_STRING(android-sdk,
 [  --with-android-sdk=DIR
                           location where the Android SDK can be found (base directory, e.g. .../android/platforms/android-6)],
     android_sdk=$withval)
 
+android_sdk_root=$withval/../../
+
 case "$target" in
 *-android*|*-linuxandroid*)
     if test -z "$android_sdk" ; then
         AC_MSG_ERROR([You must specify --with-android-sdk=/path/to/sdk when targeting Android.])
     else
         if ! test -e "$android_sdk"/source.properties ; then
             AC_MSG_ERROR([The path in --with-android-sdk isn't valid (source.properties hasn't been found).])
         fi
@@ -279,43 +281,45 @@ case "$target" in
             AC_MSG_ERROR([Unexpected error: the found android api value isn't a number! (found $android_api_level)])
         fi
 
         if test $android_api_level -lt $1 ; then
             AC_MSG_ERROR([The given Android SDK provides API level $android_api_level ($1 or higher required).])
         fi
     fi
 
-    android_tools="$android_sdk"/../../tools
-    android_platform_tools="$android_sdk"/../../platform-tools
+    android_tools="$android_sdk_root"/tools
+    android_platform_tools="$android_sdk_root"/platform-tools
     if test ! -d "$android_platform_tools" ; then
         android_platform_tools="$android_sdk"/tools # SDK Tools < r8
     fi
     # The build tools got moved around to different directories in
     # SDK Tools r22.  Try to locate them.
     android_build_tools=""
     for suffix in android-4.3 19.0.0 18.1.0 18.0.1 18.0.0 17.0.0 android-4.2.2; do
-        tools_directory="$android_sdk/../../build-tools/$suffix"
+        tools_directory="$android_sdk_root/build-tools/$suffix"
         if test -d "$tools_directory" ; then
             android_build_tools="$tools_directory"
             break
         fi
     done
     if test -z "$android_build_tools" ; then
         android_build_tools="$android_platform_tools" # SDK Tools < r22
     fi
     ANDROID_SDK="${android_sdk}"
-    if test -e "${android_sdk}/../../extras/android/compatibility/v4/android-support-v4.jar" ; then
-        ANDROID_COMPAT_LIB="${android_sdk}/../../extras/android/compatibility/v4/android-support-v4.jar"
+    ANDROID_SDK_ROOT="${android_sdk_root}"
+    if test -e "${ANDROID_SDK_ROOT}/extras/android/compatibility/v4/android-support-v4.jar" ; then
+        ANDROID_COMPAT_LIB="${ANDROID_SDK_ROOT}/extras/android/compatibility/v4/android-support-v4.jar"
     else
-        ANDROID_COMPAT_LIB="${android_sdk}/../../extras/android/support/v4/android-support-v4.jar";
+        ANDROID_COMPAT_LIB="${ANDROID_SDK_ROOT}/extras/android/support/v4/android-support-v4.jar";
     fi
     ANDROID_TOOLS="${android_tools}"
     ANDROID_PLATFORM_TOOLS="${android_platform_tools}"
     ANDROID_BUILD_TOOLS="${android_build_tools}"
+    AC_SUBST(ANDROID_SDK_ROOT)
     AC_SUBST(ANDROID_SDK)
     AC_SUBST(ANDROID_COMPAT_LIB)
     if ! test -e $ANDROID_COMPAT_LIB ; then
         AC_MSG_ERROR([You must download the Android support library when targeting Android.   Run the Android SDK tool and install Android Support Library under Extras.  See https://developer.android.com/tools/extras/support-library.html for more info. (looked for $ANDROID_COMPAT_LIB)])
     fi
 
     MOZ_PATH_PROG(ZIPALIGN, zipalign, :, [$ANDROID_TOOLS])
     MOZ_PATH_PROG(DX, dx, :, [$ANDROID_BUILD_TOOLS])
--- a/js/src/build/autoconf/android.m4
+++ b/js/src/build/autoconf/android.m4
@@ -254,16 +254,18 @@ AC_SUBST([STLPORT_LIBS])
 AC_DEFUN([MOZ_ANDROID_SDK],
 [
 
 MOZ_ARG_WITH_STRING(android-sdk,
 [  --with-android-sdk=DIR
                           location where the Android SDK can be found (base directory, e.g. .../android/platforms/android-6)],
     android_sdk=$withval)
 
+android_sdk_root=$withval/../../
+
 case "$target" in
 *-android*|*-linuxandroid*)
     if test -z "$android_sdk" ; then
         AC_MSG_ERROR([You must specify --with-android-sdk=/path/to/sdk when targeting Android.])
     else
         if ! test -e "$android_sdk"/source.properties ; then
             AC_MSG_ERROR([The path in --with-android-sdk isn't valid (source.properties hasn't been found).])
         fi
@@ -279,43 +281,45 @@ case "$target" in
             AC_MSG_ERROR([Unexpected error: the found android api value isn't a number! (found $android_api_level)])
         fi
 
         if test $android_api_level -lt $1 ; then
             AC_MSG_ERROR([The given Android SDK provides API level $android_api_level ($1 or higher required).])
         fi
     fi
 
-    android_tools="$android_sdk"/../../tools
-    android_platform_tools="$android_sdk"/../../platform-tools
+    android_tools="$android_sdk_root"/tools
+    android_platform_tools="$android_sdk_root"/platform-tools
     if test ! -d "$android_platform_tools" ; then
         android_platform_tools="$android_sdk"/tools # SDK Tools < r8
     fi
     # The build tools got moved around to different directories in
     # SDK Tools r22.  Try to locate them.
     android_build_tools=""
     for suffix in android-4.3 19.0.0 18.1.0 18.0.1 18.0.0 17.0.0 android-4.2.2; do
-        tools_directory="$android_sdk/../../build-tools/$suffix"
+        tools_directory="$android_sdk_root/build-tools/$suffix"
         if test -d "$tools_directory" ; then
             android_build_tools="$tools_directory"
             break
         fi
     done
     if test -z "$android_build_tools" ; then
         android_build_tools="$android_platform_tools" # SDK Tools < r22
     fi
     ANDROID_SDK="${android_sdk}"
-    if test -e "${android_sdk}/../../extras/android/compatibility/v4/android-support-v4.jar" ; then
-        ANDROID_COMPAT_LIB="${android_sdk}/../../extras/android/compatibility/v4/android-support-v4.jar"
+    ANDROID_SDK_ROOT="${android_sdk_root}"
+    if test -e "${ANDROID_SDK_ROOT}/extras/android/compatibility/v4/android-support-v4.jar" ; then
+        ANDROID_COMPAT_LIB="${ANDROID_SDK_ROOT}/extras/android/compatibility/v4/android-support-v4.jar"
     else
-        ANDROID_COMPAT_LIB="${android_sdk}/../../extras/android/support/v4/android-support-v4.jar";
+        ANDROID_COMPAT_LIB="${ANDROID_SDK_ROOT}/extras/android/support/v4/android-support-v4.jar";
     fi
     ANDROID_TOOLS="${android_tools}"
     ANDROID_PLATFORM_TOOLS="${android_platform_tools}"
     ANDROID_BUILD_TOOLS="${android_build_tools}"
+    AC_SUBST(ANDROID_SDK_ROOT)
     AC_SUBST(ANDROID_SDK)
     AC_SUBST(ANDROID_COMPAT_LIB)
     if ! test -e $ANDROID_COMPAT_LIB ; then
         AC_MSG_ERROR([You must download the Android support library when targeting Android.   Run the Android SDK tool and install Android Support Library under Extras.  See https://developer.android.com/tools/extras/support-library.html for more info. (looked for $ANDROID_COMPAT_LIB)])
     fi
 
     MOZ_PATH_PROG(ZIPALIGN, zipalign, :, [$ANDROID_TOOLS])
     MOZ_PATH_PROG(DX, dx, :, [$ANDROID_BUILD_TOOLS])
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -81,19 +81,28 @@ endif
 
 include $(topsrcdir)/config/config.mk
 
 # Note that we're going to set up a dependency directly between embed_android.dex and the java files
 # Instead of on the .class files, since more than one .class file might be produced per .java file
 # Sync dependencies are provided in a single jar. Sync classes themselves are delivered as source,
 # because Android resource classes must be compiled together in order to avoid overlapping resource
 # indices.
-classes.dex: $(ALL_JARS)
+classes.dex: proguard-jars
 	@echo "DX classes.dex"
-	$(DX) --dex --output=classes.dex $(ALL_JARS) $(ANDROID_COMPAT_LIB)
+	$(DX) --dex --output=classes.dex jars-proguarded $(ANDROID_COMPAT_LIB)
+
+ifdef MOZ_DEBUG
+PROGUARD_PASSES=1
+else
+PROGUARD_PASSES=6
+endif
+
+proguard-jars: $(ALL_JARS)
+	java -jar $(ANDROID_SDK_ROOT)/tools/proguard/lib/proguard.jar @$(topsrcdir)/mobile/android/config/proguard.cfg -optimizationpasses $(PROGUARD_PASSES) -injars $(subst ::,:,$(subst $(NULL) ,:,$(ALL_JARS))) -outjars jars-proguarded -libraryjars $(ANDROID_SDK)/android.jar:$(ANDROID_COMPAT_LIB)
 
 CLASSES_WITH_JNI= \
     org.mozilla.gecko.GeckoAppShell \
     org.mozilla.gecko.GeckoJavaSampler \
     org.mozilla.gecko.gfx.NativePanZoomController \
     org.mozilla.gecko.ANRReporter \
     $(NULL)
 
new file mode 100644
--- /dev/null
+++ b/mobile/android/config/proguard.cfg
@@ -0,0 +1,201 @@
+# Dalvik renders preverification unuseful (Would just slightly bloat the file).
+-dontpreverify
+
+# Uncomment to have Proguard list dead code detected during the run - useful for cleaning up the codebase.
+# -printusage
+
+-dontskipnonpubliclibraryclassmembers
+-verbose
+-allowaccessmodification
+
+# Preserve all fundamental application classes.
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.preference.Preference
+-keep public class * extends org.mozilla.gecko.sync.syncadapter.SyncAdapter
+-keep class org.mozilla.gecko.sync.syncadapter.SyncAdapter
+
+# Preserve all native method names and the names of their classes.
+-keepclasseswithmembernames class * {
+    native <methods>;
+}
+
+-keepclasseswithmembers class * {
+    public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * extends android.app.Activity {
+   public void *(android.view.View);
+}
+
+# Preserve enums. (For awful reasons, the runtime accesses them using introspection...)
+-keepclassmembers enum * {
+     *;
+}
+
+#
+# Rules from ProGuard's Android example:
+# http://proguard.sourceforge.net/manual/examples.html#androidapplication
+#
+
+# Switch off some optimizations that trip older versions of the Dalvik VM.
+
+-optimizations !code/simplification/arithmetic
+
+# Keep a fixed source file attribute and all line number tables to get line
+# numbers in the stack traces.
+# You can comment this out if you're not interested in stack traces.
+
+-renamesourcefileattribute SourceFile
+-keepattributes SourceFile,LineNumberTable
+
+# RemoteViews might need annotations.
+
+-keepattributes *Annotation*
+
+# Preserve all View implementations, their special context constructors, and
+# their setters.
+
+-keep public class * extends android.view.View {
+    public <init>(android.content.Context);
+    public <init>(android.content.Context, android.util.AttributeSet);
+    public <init>(android.content.Context, android.util.AttributeSet, int);
+    public void set*(...);
+}
+
+# Preserve all classes that have special context constructors, and the
+# constructors themselves.
+
+-keepclasseswithmembers class * {
+    public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+# Preserve the special fields of all Parcelable implementations.
+
+-keepclassmembers class * implements android.os.Parcelable {
+    static android.os.Parcelable$Creator CREATOR;
+}
+
+# Preserve static fields of inner classes of R classes that might be accessed
+# through introspection.
+
+-keepclassmembers class **.R$* {
+  public static <fields>;
+}
+
+# Preserve the required interface from the License Verification Library
+# (but don't nag the developer if the library is not used at all).
+
+-keep public interface com.android.vending.licensing.ILicensingService
+
+-dontnote com.android.vending.licensing.ILicensingService
+
+# The Android Compatibility library references some classes that may not be
+# present in all versions of the API, but we know that's ok.
+
+-dontwarn android.support.**
+
+# Preserve all native method names and the names of their classes.
+
+-keepclasseswithmembernames class * {
+    native <methods>;
+}
+
+#
+# Mozilla-specific rules
+#
+# Merging classes can generate dex warnings about anonymous inner classes.
+-optimizations !class/merging/horizontal
+-optimizations !class/merging/vertical
+
+# Keep miscellaneous targets.
+
+# Keep the annotation.
+-keep @interface org.mozilla.gecko.mozglue.JNITarget
+
+# Keep classes tagged with the annotation.
+-keep @org.mozilla.gecko.mozglue.JNITarget class *
+
+# Keep all members of an annotated class.
+-keepclassmembers @org.mozilla.gecko.mozglue.JNITarget class * {
+    *;
+}
+
+# Keep annotated members of any class.
+-keepclassmembers class * {
+    @org.mozilla.gecko.mozglue.JNITarget *;
+}
+
+# Keep classes which contain at least one annotated element. Split over two directives
+# because, according to the developer of ProGuard, "the option -keepclasseswithmembers
+# doesn't combine well with the '*' wildcard" (And, indeed, using it causes things to
+# be deleted that we want to keep.)
+-keepclasseswithmembers class * {
+    @org.mozilla.gecko.mozglue.JNITarget <methods>;
+}
+-keepclasseswithmembers class * {
+    @org.mozilla.gecko.mozglue.JNITarget <fields>;
+}
+
+# Keep Robocop targets. TODO: Can omit these from release builds. Also, Bug 916507.
+
+# Same formula as above...
+-keep @interface org.mozilla.gecko.mozglue.RobocopTarget
+-keep @org.mozilla.gecko.mozglue.RobocopTarget class *
+-keepclassmembers class * {
+    @org.mozilla.gecko.mozglue.RobocopTarget *;
+}
+-keepclassmembers @org.mozilla.gecko.mozglue.RobocopTarget class * {
+    *;
+}
+-keepclasseswithmembers class * {
+    @org.mozilla.gecko.mozglue.RobocopTarget <methods>;
+}
+-keepclasseswithmembers class * {
+    @org.mozilla.gecko.mozglue.RobocopTarget <fields>;
+}
+
+# Keep WebRTC targets.
+-keep @interface org.mozilla.gecko.mozglue.WebRTCJNITarget
+-keep @org.mozilla.gecko.mozglue.WebRTCJNITarget class *
+-keepclassmembers class * {
+    @org.mozilla.gecko.mozglue.WebRTCJNITarget *;
+}
+-keepclassmembers @org.mozilla.gecko.mozglue.WebRTCJNITarget class * {
+    *;
+}
+-keepclasseswithmembers class * {
+    @org.mozilla.gecko.mozglue.WebRTCJNITarget <methods>;
+}
+-keepclasseswithmembers class * {
+    @org.mozilla.gecko.mozglue.WebRTCJNITarget <fields>;
+}
+
+# Keep generator-targeted entry points.
+-keep @interface org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI
+-keep @org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI class *
+-keepclassmembers class * {
+    @org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI *;
+}
+-keepclasseswithmembers class * {
+    @org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI <methods>;
+}
+-keepclasseswithmembers class * {
+    @org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI <fields>;
+}
+
+-keep @interface org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI
+-keep @org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI class *
+-keepclassmembers @org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI class * {
+    *;
+}
+
+# Disable obfuscation because it makes exception stack traces more difficult to read.
+-dontobfuscate
+
+# Suppress warnings about missing descriptor classes.
+#-dontnote **,!ch.boye.**,!org.mozilla.gecko.sync.**
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -58,18 +58,18 @@ class AndroidRefable {
 
 // This isn't in AndroidBridge.h because including StrongPointer.h there is gross
 static android::sp<AndroidRefable> (*android_SurfaceTexture_getNativeWindow)(JNIEnv* env, jobject surfaceTexture) = nullptr;
 
 jclass AndroidBridge::GetClassGlobalRef(JNIEnv* env, const char* className)
 {
     jobject classLocalRef = env->FindClass(className);
     if (!classLocalRef) {
-        ALOG(">>> FATAL JNI ERROR! FindClass(className=\"%s\") failed. Did "
-             "ProGuard optimize away a non-public class?", className);
+        ALOG(">>> FATAL JNI ERROR! FindClass(className=\"%s\") failed. Did ProGuard optimize away something it shouldn't have?",
+             className);
         env->ExceptionDescribe();
         MOZ_CRASH();
     }
     jobject classGlobalRef = env->NewGlobalRef(classLocalRef);
     if (!classGlobalRef) {
         env->ExceptionDescribe();
         MOZ_CRASH();
     }
@@ -80,60 +80,60 @@ jclass AndroidBridge::GetClassGlobalRef(
 }
 
 jmethodID AndroidBridge::GetMethodID(JNIEnv* env, jclass jClass,
                               const char* methodName, const char* methodType)
 {
    jmethodID methodID = env->GetMethodID(jClass, methodName, methodType);
    if (!methodID) {
        ALOG(">>> FATAL JNI ERROR! GetMethodID(methodName=\"%s\", "
-            "methodType=\"%s\") failed. Did ProGuard optimize away a non-"
-            "public method?", methodName, methodType);
+            "methodType=\"%s\") failed. Did ProGuard optimize away something it shouldn't have?",
+            methodName, methodType);
        env->ExceptionDescribe();
        MOZ_CRASH();
    }
    return methodID;
 }
 
 jmethodID AndroidBridge::GetStaticMethodID(JNIEnv* env, jclass jClass,
                                const char* methodName, const char* methodType)
 {
   jmethodID methodID = env->GetStaticMethodID(jClass, methodName, methodType);
   if (!methodID) {
       ALOG(">>> FATAL JNI ERROR! GetStaticMethodID(methodName=\"%s\", "
-           "methodType=\"%s\") failed. Did ProGuard optimize away a non-"
-           "public method?", methodName, methodType);
+           "methodType=\"%s\") failed. Did ProGuard optimize away something it shouldn't have?",
+           methodName, methodType);
       env->ExceptionDescribe();
       MOZ_CRASH();
   }
   return methodID;
 }
 
 jfieldID AndroidBridge::GetFieldID(JNIEnv* env, jclass jClass,
                            const char* fieldName, const char* fieldType)
 {
     jfieldID fieldID = env->GetFieldID(jClass, fieldName, fieldType);
     if (!fieldID) {
         ALOG(">>> FATAL JNI ERROR! GetFieldID(fieldName=\"%s\", "
-             "fieldType=\"%s\") failed. Did ProGuard optimize away a non-"
-             "public field?", fieldName, fieldType);
+             "fieldType=\"%s\") failed. Did ProGuard optimize away something it shouldn't have?",
+             fieldName, fieldType);
         env->ExceptionDescribe();
         MOZ_CRASH();
     }
     return fieldID;
 }
 
 jfieldID AndroidBridge::GetStaticFieldID(JNIEnv* env, jclass jClass,
                            const char* fieldName, const char* fieldType)
 {
     jfieldID fieldID = env->GetStaticFieldID(jClass, fieldName, fieldType);
     if (!fieldID) {
         ALOG(">>> FATAL JNI ERROR! GetStaticFieldID(fieldName=\"%s\", "
-             "fieldType=\"%s\") failed. Did ProGuard optimize away a non-"
-             "public field?", fieldName, fieldType);
+             "fieldType=\"%s\") failed. Did ProGuard optimize away something it shouldn't have?",
+             fieldName, fieldType);
         env->ExceptionDescribe();
         MOZ_CRASH();
     }
     return fieldID;
 }
 
 void
 AndroidBridge::ConstructBridge(JNIEnv *jEnv)