From e31994ac771794ddcb22aa4b23e893321acbcfc9 Mon Sep 17 00:00:00 2001 From: Jake McGinty Date: Thu, 20 Nov 2014 03:16:18 -0800 Subject: [PATCH] proguard has guarded its last pro // FREEBIE --- build.gradle | 7 +-- proguard.cfg | 52 ------------------ strip_play_services.gradle | 109 +++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 56 deletions(-) delete mode 100644 proguard.cfg create mode 100644 strip_play_services.gradle diff --git a/build.gradle b/build.gradle index 8150564701..97ea38aec4 100644 --- a/build.gradle +++ b/build.gradle @@ -11,6 +11,7 @@ buildscript { } apply plugin: 'com.android.application' +apply from: 'strip_play_services.gradle' apply plugin: 'witness' repositories { @@ -90,12 +91,10 @@ android { android { buildTypes { debug { - runProguard true - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg' + minifyEnabled false } release { - runProguard true - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg' + minifyEnabled false } } diff --git a/proguard.cfg b/proguard.cfg deleted file mode 100644 index aa6d32d2f4..0000000000 --- a/proguard.cfg +++ /dev/null @@ -1,52 +0,0 @@ --dontobfuscate - -## Tests --dontwarn org.mockito.** --dontwarn org.fest.** --dontwarn sun.reflect.** --dontwarn android.test.** --dontwarn org.thoughtcrime.securesms.**.*Test - -## Support - --keep class android.support.v4.app.** { *; } --keep interface android.support.v4.app.** { *; } - --keep class android.support.v7.internal.** { *; } --keep interface android.support.v7.internal.** { *; } --keep class android.support.v7.** { *; } --keep interface android.support.v7.** { *; } --keep public class * extends android.support.v7.app.ActionBarActivity { *; } --keep class android.support.v7.widget.** { *; } --keepattributes *Annotation* - -## Protobuf - --keep class com.google.protobuf.** { *; } - -## Dagger - --dontwarn dagger.internal.codegen.** --keepclassmembers class * { - @javax.inject.* *; - @dagger.* *; - (); -} --keep class dagger.* { *; } --keep class javax.inject.* { *; } --keep class * extends dagger.internal.Binding --keep class * extends dagger.internal.ModuleAdapter --keep class * extends dagger.internal.StaticInjection - -## GSON - -# removes such information by default, so configure it to keep all of it. --keepattributes Signature - -# For using GSON @Expose annotation --keepattributes *Annotation* - -# Gson specific classes --keep class sun.misc.Unsafe { *; } -#-keep class com.google.gson.stream.** { *; } - diff --git a/strip_play_services.gradle b/strip_play_services.gradle new file mode 100644 index 0000000000..03c9b73188 --- /dev/null +++ b/strip_play_services.gradle @@ -0,0 +1,109 @@ +// adapted from https://gist.github.com/CedricGatay/4e21ce855bd2562f9257 +// which was adapted from https://gist.github.com/dmarcato/d7c91b94214acd936e42 + +def toCamelCase(String string) { + String result = "" + string.findAll("[^\\W]+") { String word -> + result += word.capitalize() + } + return result +} + +afterEvaluate { project -> + Configuration runtimeConfiguration = project.configurations.getByName('compile') + println runtimeConfiguration + ResolutionResult resolution = runtimeConfiguration.incoming.resolutionResult + // Forces resolve of configuration + ModuleVersionIdentifier module = resolution.getAllComponents().find { + it.moduleVersion.name.equals("play-services") + }.moduleVersion + + + def playServicesLibName = toCamelCase("${module.group} ${module.name} ${module.version}") + String prepareTaskName = "prepare${playServicesLibName}Library" + File playServiceRootFolder = project.tasks.find { it.name.equals(prepareTaskName) }.explodedDir + + + def tmpDir = new File(project.buildDir, 'intermediates/tmp') + tmpDir.mkdirs() + def libFile = new File(tmpDir, "${playServicesLibName}.marker") + + def strippedClassFileName = "${playServicesLibName}.jar" + def classesStrippedJar = new File(tmpDir, strippedClassFileName) + + def packageToExclude = [ + "com/google/ads/**", + //"com/google/android/gms/actions/**", + "com/google/android/gms/ads/**", + "com/google/android/gms/analytics/**", + //"com/google/android/gms/appindexing/**", + //"com/google/android/gms/appstate/**", + //"com/google/android/gms/auth/**", + //"com/google/android/gms/cast/**", + "com/google/android/gms/drive/**", + "com/google/android/gms/fitness/**", + "com/google/android/gms/games/**", + //"com/google/android/gms/gcm/**", + //"com/google/android/gms/identity/**", + "com/google/android/gms/location/**", + "com/google/android/gms/maps/**", + "com/google/android/gms/panorama/**", + "com/google/android/gms/plus/**", + //"com/google/android/gms/security/**", + //"com/google/android/gms/tagmanager/**", + "com/google/android/gms/wallet/**", + "com/google/android/gms/wearable/**" + ] + + Task stripPlayServices = project.tasks.create(name: 'stripPlayServices', group: "Strip") { + inputs.files new File(playServiceRootFolder, "classes.jar") + outputs.dir playServiceRootFolder + description 'Strip useless packages from Google Play Services library to avoid reaching dex limit' + + doLast { + def packageExcludesAsString = packageToExclude.join(",") + if (libFile.exists() + && libFile.text == packageExcludesAsString + && classesStrippedJar.exists()){ + println "Play services already stripped" + copy { + from(file(classesStrippedJar)) + into(file(playServiceRootFolder)) + rename { fileName -> + fileName = "classes.jar" + } + } + }else { + copy { + from(file(new File(playServiceRootFolder, "classes.jar"))) + into(file(playServiceRootFolder)) + rename { fileName -> + fileName = "classes_orig.jar" + } + } + tasks.create(name: "stripPlayServices" + module.version, type: Jar) { + destinationDir = playServiceRootFolder + archiveName = "classes.jar" + from(zipTree(new File(playServiceRootFolder, "classes_orig.jar"))) { + exclude packageToExclude + } + }.execute() + delete file(new File(playServiceRootFolder, "classes_orig.jar")) + copy { + from(file(new File(playServiceRootFolder, "classes.jar"))) + into(file(tmpDir)) + rename { fileName -> + fileName = strippedClassFileName + } + } + libFile.text = packageExcludesAsString + } + } + } + + project.tasks.findAll { + it.name.startsWith('prepare') && it.name.endsWith('Dependencies') + }.each { Task task -> + task.dependsOn stripPlayServices + } +} \ No newline at end of file