/*
* Copyright (C) 2014 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.build.gradle.tasks;
import static com.android.build.gradle.tasks.ResourceUsageAnalyzer.NO_MATCH;
import static com.android.build.gradle.tasks.ResourceUsageAnalyzer.Resource;
import static com.android.build.gradle.tasks.ResourceUsageAnalyzer.convertFormatStringToRegexp;
import static java.io.File.separatorChar;
import com.android.annotations.NonNull;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import junit.framework.TestCase;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/** TODO: Test Resources#getIdentifier() handling */
@SuppressWarnings("SpellCheckingInspection")
public class ResourceUsageAnalyzerTest extends TestCase {
public void testObfuscatedInPlace() throws Exception {
check(true, true);
}
public void testObfuscatedCopy() throws Exception {
check(true, false);
}
public void testNoProGuardInPlace() throws Exception {
check(false, true);
}
public void testNoProGuardCopy() throws Exception {
check(false, false);
}
private static void check(boolean useProguard, boolean inPlace) throws Exception {
File dir = Files.createTempDir();
File mapping;
File classesJar;
if (useProguard) {
classesJar = createProguardedClasses(dir);
mapping = createMappingFile(dir);
} else {
classesJar = createUnproguardedClasses(dir);
mapping = null;
}
File rDir = createResourceClassFolder(dir);
File mergedManifest = createMergedManifest(dir);
File resources = createResourceFolder(dir);
ResourceUsageAnalyzer analyzer = new ResourceUsageAnalyzer(rDir, classesJar,
mergedManifest, mapping, resources);
analyzer.analyze();
checkState(analyzer);
assertEquals(""
+ "@attr/myAttr1 : reachable=false\n"
+ "@attr/myAttr2 : reachable=false\n"
+ "@dimen/activity_horizontal_margin : reachable=true\n"
+ "@dimen/activity_vertical_margin : reachable=true\n"
+ "@drawable/ic_launcher : reachable=true\n"
+ "@drawable/unused : reachable=false\n"
+ "@id/action_settings : reachable=true\n"
+ "@layout/activity_main : reachable=true\n"
+ " @dimen/activity_vertical_margin\n"
+ " @dimen/activity_horizontal_margin\n"
+ " @string/hello_world\n"
+ " @style/MyStyle_Child\n"
+ "@menu/main : reachable=true\n"
+ " @id/action_settings\n"
+ " @string/action_settings\n"
+ "@raw/android_wear_micro_apk : reachable=true\n"
+ "@raw/index1 : reachable=false\n"
+ "@raw/my_js : reachable=false\n"
+ "@raw/my_used_raw_drawable : reachable=true\n"
+ "@raw/styles2 : reachable=false\n"
+ "@string/action_settings : reachable=true\n"
+ "@string/alias : reachable=false\n"
+ " @string/app_name\n"
+ "@string/app_name : reachable=true\n"
+ "@string/hello_world : reachable=true\n"
+ "@style/AppTheme : reachable=false\n"
+ "@style/MyStyle : reachable=true\n"
+ "@style/MyStyle_Child : reachable=true\n"
+ " @style/MyStyle\n"
+ "@xml/android_wear_micro_apk : reachable=true\n"
+ " @raw/android_wear_micro_apk\n",
analyzer.dumpResourceModel());
File unusedBitmap = new File(resources, "drawable-xxhdpi" + separatorChar + "unused.png");
assertTrue(unusedBitmap.exists());
if (ResourceUsageAnalyzer.TWO_PASS_AAPT) {
File destination = inPlace ? null : Files.createTempDir();
analyzer.setDryRun(true);
analyzer.removeUnused(destination);
assertTrue(unusedBitmap.exists());
analyzer.setDryRun(false);
analyzer.removeUnused(destination);
if (inPlace) {
assertFalse(unusedBitmap.exists());
} else {
assertTrue(unusedBitmap.exists());
assertTrue(new File(destination, "values" + separatorChar + "values.xml").exists());
assertFalse(new File(destination, "drawable-xxhdpi" + separatorChar +
"unused.png").exists());
}
File values = new File(inPlace ? resources : destination,
"values" + separatorChar + "values.xml");
assertTrue(values.exists());
assertEquals(""
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<resources>\n"
+ "\n"
+ " <attr name=\"myAttr1\" format=\"integer\" />\n"
+ " <attr name=\"myAttr2\" format=\"boolean\" />\n"
+ "\n"
+ " <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n"
+ " <dimen name=\"activity_vertical_margin\">16dp</dimen>\n"
+ "\n"
+ " <string name=\"action_settings\">Settings</string>\n"
+ " <string name=\"app_name\">ShrinkUnitTest</string>\n"
+ " <string name=\"hello_world\">Hello world!</string>\n"
+ "\n"
+ "</resources>",
Files.toString(values, Charsets.UTF_8));
if (destination != null) {
deleteDir(destination);
}
} else {
List<File> files = Lists.newArrayList();
addFiles(resources, files);
Collections.sort(files, new Comparator<File>() {
@Override
public int compare(File file, File file2) {
return file.getPath().compareTo(file2.getPath());
}
});
// Generate a .zip file from a directory
File uncompressedFile = File.createTempFile("uncompressed", ".ap_");
String prefix = resources.getPath() + File.separatorChar;
FileOutputStream fos = new FileOutputStream(uncompressedFile);
ZipOutputStream zos = new ZipOutputStream(fos);
for (File file : files) {
if (file.equals(resources)) {
continue;
}
assertTrue(file.getPath().startsWith(prefix));
String relative = "res/" + file.getPath().substring(prefix.length())
.replace(File.separatorChar, '/');
boolean isValuesFile = relative.equals("res/values/values.xml");
if (isValuesFile) {
relative = "resources.arsc";
}
ZipEntry ze = new ZipEntry(relative);
zos.putNextEntry(ze);
if (!file.isDirectory() && !isValuesFile) {
byte[] bytes = Files.toByteArray(file);
zos.write(bytes);
}
zos.closeEntry();
}
zos.close();
fos.close();
assertEquals(""
+ "res/drawable-hdpi\n"
+ "res/drawable-hdpi/ic_launcher.png\n"
+ "res/drawable-mdpi\n"
+ "res/drawable-mdpi/ic_launcher.png\n"
+ "res/drawable-xxhdpi\n"
+ "res/drawable-xxhdpi/ic_launcher.png\n"
+ "res/drawable-xxhdpi/unused.png\n"
+ "res/layout\n"
+ "res/layout/activity_main.xml\n"
+ "res/menu\n"
+ "res/menu/main.xml\n"
+ "res/raw\n"
+ "res/raw/android_wear_micro_apk.apk\n"
+ "res/raw/index1.html\n"
+ "res/raw/my_js.js\n"
+ "res/raw/styles2.css\n"
+ "res/values\n"
+ "resources.arsc\n"
+ "res/xml\n"
+ "res/xml/android_wear_micro_apk.xml\n",
dumpZipContents(uncompressedFile));
System.out.println(uncompressedFile);
File compressedFile = File.createTempFile("compressed", ".ap_");
analyzer.rewriteResourceZip(uncompressedFile, compressedFile);
// Check contents
assertEquals(""
+ "res/drawable-hdpi\n"
+ "res/drawable-hdpi/ic_launcher.png\n"
+ "res/drawable-mdpi\n"
+ "res/drawable-mdpi/ic_launcher.png\n"
+ "res/drawable-xxhdpi\n"
+ "res/drawable-xxhdpi/ic_launcher.png\n"
+ "res/layout\n"
+ "res/layout/activity_main.xml\n"
+ "res/menu\n"
+ "res/menu/main.xml\n"
+ "res/raw\n"
+ "res/raw/android_wear_micro_apk.apk\n"
+ "res/values\n"
+ "resources.arsc\n"
+ "res/xml\n"
+ "res/xml/android_wear_micro_apk.xml\n",
dumpZipContents(compressedFile));
uncompressedFile.delete();
compressedFile.delete();
}
deleteDir(dir);
}
private static String dumpZipContents(File zipFile) throws IOException {
StringBuilder sb = new StringBuilder();
FileInputStream fis = new FileInputStream(zipFile);
try {
ZipInputStream zis = new ZipInputStream(fis);
try {
ZipEntry entry = zis.getNextEntry();
while (entry != null) {
sb.append(entry.getName());
sb.append('\n');
entry = zis.getNextEntry();
}
} finally {
zis.close();
}
} finally {
fis.close();
}
return sb.toString();
}
private static void addFiles(File file, List<File> files) {
files.add(file);
if (file.isDirectory()) {
File[] list = file.listFiles();
if (list != null) {
for (File f : list) {
addFiles(f, files);
}
}
}
}
private static File createResourceFolder(File dir) throws IOException {
File resources = new File(dir, "app/build/res/all/release".replace('/', separatorChar));
//noinspection ResultOfMethodCallIgnored
resources.mkdirs();
createFile(resources, "drawable-hdpi/ic_launcher.png", new byte[0]);
createFile(resources, "drawable-mdpi/ic_launcher.png", new byte[0]);
createFile(resources, "drawable-xxhdpi/ic_launcher.png", new byte[0]);
createFile(resources, "drawable-xxhdpi/unused.png", new byte[0]);
createFile(resources, "layout/activity_main.xml", ""
+ "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\"\n"
+ " android:layout_width=\"match_parent\"\n"
+ " android:layout_height=\"match_parent\"\n"
+ " android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n"
+ " android:paddingRight=\"@dimen/activity_horizontal_margin\"\n"
+ " android:paddingTop=\"@dimen/activity_vertical_margin\"\n"
+ " android:paddingBottom=\"@dimen/activity_vertical_margin\"\n"
+ " tools:context=\".MainActivity\">\n"
+ "\n"
+ " <TextView\n"
+ " style=\"@style/MyStyle.Child\"\n"
+ " android:text=\"@string/hello_world\"\n"
+ " android:layout_width=\"wrap_content\"\n"
+ " android:layout_height=\"wrap_content\" />\n"
+ "\n"
+ "</RelativeLayout>");
createFile(resources, "menu/main.xml", ""
+ "<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\"\n"
+ " tools:context=\".MainActivity\" >\n"
+ " <item android:id=\"@+id/action_settings\"\n"
+ " android:title=\"@string/action_settings\"\n"
+ " android:orderInCategory=\"100\"\n"
+ " android:showAsAction=\"never\" />\n"
+ "</menu>");
createFile(resources, "values/values.xml", ""
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<resources>\n"
+ "\n"
+ " <attr name=\"myAttr1\" format=\"integer\" />\n"
+ " <attr name=\"myAttr2\" format=\"boolean\" />\n"
+ "\n"
+ " <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n"
+ " <dimen name=\"activity_vertical_margin\">16dp</dimen>\n"
+ "\n"
+ " <string name=\"action_settings\">Settings</string>\n"
+ " <string name=\"alias\"> @string/app_name </string>\n"
+ " <string name=\"app_name\">ShrinkUnitTest</string>\n"
+ " <string name=\"hello_world\">Hello world!</string>\n"
+ "\n"
+ " <style name=\"AppTheme\" parent=\"android:Theme.Holo\"></style>\n"
+ "\n"
+ " <style name=\"MyStyle\">\n"
+ " <item name=\"myAttr1\">50</item>\n"
+ " </style>\n"
+ "\n"
+ " <style name=\"MyStyle.Child\">\n"
+ " <item name=\"myAttr2\">true</item>\n"
+ " </style>\n"
+ "\n"
+ "</resources>");
createFile(resources, "raw/android_wear_micro_apk.apk",
"<binary data>");
createFile(resources, "xml/android_wear_micro_apk.xml", ""
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<wearableApp package=\"com.example.shrinkunittest.app\">\n"
+ " <versionCode>1</versionCode>\n"
+ " <versionName>1.0' platformBuildVersionName='5.0-1521886</versionName>\n"
+ " <rawPathResId>android_wear_micro_apk</rawPathResId>\n"
+ "</wearableApp>");
// RAW content for HTML/web
createFile(resources, "raw/index1.html", ""
// TODO: Test single quotes, attribute without quotes, spaces around = etc, prologue, xhtml
+ "<!DOCTYPE html>\n"
+ "<html>\n"
+ "<!--\n"
+ " Blah blah\n"
+ "-->\n"
+ "<head>\n"
+ " <meta charset=\"utf-8\">\n"
+ " <link href=\"http://fonts.googleapis.com/css?family=Alegreya:400italic,900italic|Alegreya+Sans:300\" rel=\"stylesheet\">\n"
+ " <link href=\"http://yui.yahooapis.com/2.8.0r4/build/reset/reset-min.css\" rel=\"stylesheet\">\n"
+ " <link href=\"static/landing.css\" rel=\"stylesheet\">\n"
+ " <script src=\"http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js\"></script>\n"
+ " <script src=\"static/modernizr.custom.14469.js\"></script>\n"
+ " <meta name=\"viewport\" content=\"width=690\">\n"
+ " <style type=\"text/css\">\n"
+ "html, body {\n"
+ " margin: 0;\n"
+ " height: 100%;\n"
+ " background-image: url(file:///android_res/raw/my_used_raw_drawable);\n"
+ "}\n"
+ "</style>"
+ "</head>\n"
+ "<body>\n"
+ "\n"
+ "<div id=\"container\">\n"
+ "\n"
+ " <div id=\"logo\"></div>\n"
+ "\n"
+ " <div id=\"text\">\n"
+ " <p>\n"
+ " More ignored text here\n"
+ " </p>\n"
+ " </div>\n"
+ "\n"
+ " <a id=\"playlink\" href=\"file/foo.png\"> </a>\n"
+ "</div>\n"
+ "<script>\n"
+ "\n"
+ "if (Modernizr.cssanimations &&\n"
+ " Modernizr.svg &&\n"
+ " Modernizr.csstransforms3d &&\n"
+ " Modernizr.csstransitions) {\n"
+ "\n"
+ " // progressive enhancement\n"
+ " $('#device-screen').css('display', 'block');\n"
+ " $('#device-frame').css('background-image', 'url( 'drawable-mdpi/tilted.png')' );\n"
+ " $('#opentarget').css('visibility', 'visible');\n"
+ " $('body').addClass('withvignette');\n"
+ "</script>\n"
+ "\n"
+ "</body>\n"
+ "</html>");
createFile(resources, "raw/styles2.css", ""
+ "/**\n"
+ " * Copyright 2014 Google Inc.\n"
+ " */\n"
+ "\n"
+ "html, body {\n"
+ " margin: 0;\n"
+ " height: 100%;\n"
+ " -webkit-font-smoothing: antialiased;\n"
+ "}\n"
+ "#logo {\n"
+ " position: absolute;\n"
+ " left: 0;\n"
+ " top: 60px;\n"
+ " width: 250px;\n"
+ " height: 102px;\n"
+ " background-image: url(img2.png);\n"
+ " background-repeat: no-repeat;\n"
+ " background-size: contain;\n"
+ " opacity: 0.7;\n"
+ " z-index: 100;\n"
+ "}\n"
+ "device-frame {\n"
+ " position: absolute;\n"
+ " right: -70px;\n"
+ " top: 0;\n"
+ " width: 420px;\n"
+ " height: 500px;\n"
+ " background-image: url(tilted_fallback.jpg);\n"
+ " background-size: cover;\n"
+ " -webkit-user-select: none;\n"
+ " -moz-user-select: none;\n"
+ "}");
createFile(resources, "raw/my_js.js", ""
+ "function $(id) {\n"
+ " return document.getElementById(id);\n"
+ "}\n"
+ "\n"
+ "/* Ignored block comment: \"ignore me\" */\n"
+ "function show(id) {\n"
+ " $(id).style.display = \"block\";\n"
+ "}\n"
+ "\n"
+ "function hide(id) {\n"
+ " $(id).style.display = \"none\";\n"
+ "}\n"
+ "// Line comment\n"
+ "function onStatusBoxFocus(elt) {\n"
+ " elt.value = '';\n"
+ " elt.style.color = \"#000\";\n"
+ " show('status_submit');\n"
+ "}\n");
return resources;
}
private static File createMergedManifest(File dir) throws IOException {
return createFile(dir, "app/build/manifests/release/AndroidManifest.xml", ""
+ "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" android:versionCode=\"1\" android:versionName=\"1.0\" package=\"com.example.shrinkunittest.app\">\n"
+ " <uses-sdk android:minSdkVersion=\"20\" android:targetSdkVersion=\"19\"/>\n"
+ "\n"
+ " <application android:allowBackup=\"true\" android:icon=\"@drawable/ic_launcher\" android:label=\"@string/app_name\">\n"
+ " <activity android:label=\"@string/app_name\" android:name=\"com.example.shrinkunittest.app.MainActivity\">\n"
+ " <intent-filter>\n"
+ " <action android:name=\"android.intent.action.MAIN\"/>\n"
+ "\n"
+ " <category android:name=\"android.intent.category.LAUNCHER\"/>\n"
+ " </intent-filter>\n"
+ " </activity>\n"
+ " <meta-data\n"
+ " android:name=\"com.google.android.wearable.beta.app\"\n"
+ " android:resource=\"@xml/android_wear_micro_apk\" />"
+ " </application>\n"
+ "\n"
+ "</manifest>");
}
private static File createResourceClassFolder(File dir) throws IOException {
File rDir = new File(dir, "app/build/source/r/release".replace('/', separatorChar));
//noinspection ResultOfMethodCallIgnored
rDir.mkdirs();
createFile(rDir, "com/example/shrinkunittest/app/R.java", ""
+ "/* AUTO-GENERATED FILE. DO NOT MODIFY.\n"
+ " *\n"
+ " * This class was automatically generated by the\n"
+ " * aapt tool from the resource data it found. It\n"
+ " * should not be modified by hand.\n"
+ " */\n"
+ "\n"
+ "package com.example.shrinkunittest.app;\n"
+ "\n"
+ "public final class R {\n"
+ " public static final class attr {\n"
+ " /** <p>Must be an integer value, such as \"<code>100</code>\".\n"
+ "<p>This may also be a reference to a resource (in the form\n"
+ "\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\") or\n"
+ "theme attribute (in the form\n"
+ "\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\")\n"
+ "containing a value of this type.\n"
+ " */\n"
+ " public static final int myAttr1=0x7f010000;\n"
+ " /** <p>Must be a boolean value, either \"<code>true</code>\" or \"<code>false</code>\".\n"
+ "<p>This may also be a reference to a resource (in the form\n"
+ "\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\") or\n"
+ "theme attribute (in the form\n"
+ "\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\")\n"
+ "containing a value of this type.\n"
+ " */\n"
+ " public static final int myAttr2=0x7f010001;\n"
+ " }\n"
+ " public static final class dimen {\n"
+ " public static final int activity_horizontal_margin=0x7f040000;\n"
+ " public static final int activity_vertical_margin=0x7f040001;\n"
+ " }\n"
+ " public static final class drawable {\n"
+ " public static final int ic_launcher=0x7f020000;\n"
+ " public static final int unused=0x7f020001;\n"
+ " }\n"
+ " public static final class id {\n"
+ " public static final int action_settings=0x7f080000;\n"
+ " }\n"
+ " public static final class layout {\n"
+ " public static final int activity_main=0x7f030000;\n"
+ " }\n"
+ " public static final class menu {\n"
+ " public static final int main=0x7f070000;\n"
+ " }\n"
+ " public static final class raw {\n"
+ " public static final int android_wear_micro_apk=0x7f090000;\n"
+ " public static final int index1=0x7f090001;\n"
+ " public static final int styles2=0x7f090002;\n"
+ " public static final int my_js=0x7f090003;\n"
+ " public static final int my_used_raw_drawable=0x7f090004;\n"
+ " }"
+ " public static final class string {\n"
+ " public static final int action_settings=0x7f050000;\n"
+ " public static final int alias=0x7f050001;\n"
+ " public static final int app_name=0x7f050002;\n"
+ " public static final int hello_world=0x7f050003;\n"
+ " }\n"
+ " public static final class style {\n"
+ " public static final int AppTheme=0x7f060000;\n"
+ " public static final int MyStyle=0x7f060001;\n"
+ " public static final int MyStyle_Child=0x7f060002;\n"
+ " }\n"
+ " public static final class xml {\n"
+ " public static final int android_wear_micro_apk=0x7f0a0000;\n"
+ " }"
+ "}");
return rDir;
}
private static File createProguardedClasses(File dir) throws IOException {
byte[] bytecode = new byte[] {
(byte)80, (byte)75, (byte)3, (byte)4, (byte)20, (byte)0, (byte)8, (byte)0,
(byte)8, (byte)0, (byte)12, (byte)88, (byte)-62, (byte)68, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)49, (byte)0, (byte)0, (byte)0, (byte)99, (byte)111,
(byte)109, (byte)47, (byte)101, (byte)120, (byte)97, (byte)109, (byte)112, (byte)108,
(byte)101, (byte)47, (byte)115, (byte)104, (byte)114, (byte)105, (byte)110, (byte)107,
(byte)117, (byte)110, (byte)105, (byte)116, (byte)116, (byte)101, (byte)115, (byte)116,
(byte)47, (byte)97, (byte)112, (byte)112, (byte)47, (byte)77, (byte)97, (byte)105,
(byte)110, (byte)65, (byte)99, (byte)116, (byte)105, (byte)118, (byte)105, (byte)116,
(byte)121, (byte)46, (byte)99, (byte)108, (byte)97, (byte)115, (byte)115, (byte)117,
(byte)-110, (byte)-53, (byte)78, (byte)-37, (byte)64, (byte)20, (byte)-122, (byte)-1,
(byte)-63, (byte)14, (byte)14, (byte)97, (byte)32, (byte)36, (byte)36, (byte)-31,
(byte)82, (byte)110, (byte)-31, (byte)-46, (byte)58, (byte)-15, (byte)-62, (byte)82,
(byte)-73, (byte)-127, (byte)74, (byte)-112, (byte)-107, (byte)-91, (byte)-94, (byte)46,
(byte)-112, (byte)88, (byte)-80, (byte)-77, (byte)-30, (byte)1, (byte)70, (byte)36,
(byte)-29, (byte)40, (byte)-98, (byte)-92, (byte)101, (byte)-59, (byte)-85, (byte)-16,
(byte)0, (byte)108, (byte)-70, (byte)73, (byte)-44, (byte)46, (byte)-6, (byte)0,
(byte)60, (byte)20, (byte)-22, (byte)-103, (byte)-60, (byte)80, (byte)110, (byte)-99,
(byte)-111, (byte)-50, (byte)57, (byte)-93, (byte)-1, (byte)59, (byte)23, (byte)-23,
(byte)-52, (byte)-3, (byte)-61, (byte)-17, (byte)63, (byte)0, (byte)62, (byte)-61,
(byte)-77, (byte)110, (byte)44, (byte)-64, (byte)-70, (byte)113, (byte)-116, (byte)-55,
(byte)2, (byte)14, (byte)-74, (byte)28, (byte)84, (byte)29, (byte)108, (byte)59,
(byte)-40, (byte)-55, (byte)-63, (byte)70, (byte)-34, (byte)-104, (byte)69, (byte)99,
(byte)74, (byte)57, (byte)100, (byte)80, (byte)-52, (byte)17, (byte)81, (byte)48,
(byte)-90, (byte)60, (byte)-117, (byte)105, (byte)44, (byte)112, (byte)108, (byte)96,
(byte)-103, (byte)99, (byte)23, (byte)21, (byte)-114, (byte)61, (byte)44, (byte)113,
(byte)124, (byte)-60, (byte)42, (byte)-57, (byte)39, (byte)124, (byte)-32, (byte)-88,
(byte)97, (byte)-99, (byte)-93, (byte)-114, (byte)21, (byte)6, (byte)-53, (byte)-83,
(byte)5, (byte)12, (byte)-21, (byte)110, (byte)-19, (byte)107, (byte)-88, (byte)-94,
(byte)94, (byte)44, (byte)35, (byte)127, (byte)32, (byte)-59, (byte)119, (byte)-1,
(byte)88, (byte)-88, (byte)126, (byte)-96, (byte)-50, (byte)-37, (byte)-95, (byte)22,
(byte)-67, (byte)-58, (byte)-104, (byte)58, (byte)101, (byte)-80, (byte)-35, (byte)-64,
(byte)-72, (byte)37, (byte)55, (byte)120, (byte)11, (byte)55, (byte)-116, (byte)82,
(byte)113, (byte)-97, (byte)-124, (byte)56, (byte)-15, (byte)-113, (byte)-6, (byte)42,
(byte)106, (byte)-117, (byte)-41, (byte)-62, (byte)-77, (byte)-116, (byte)51, (byte)-122,
(byte)-43, (byte)119, (byte)-124, (byte)64, (byte)-117, (byte)-50, (byte)88, (byte)-100,
(byte)-34, (byte)-105, (byte)74, (byte)-22, (byte)47, (byte)-44, (byte)-72, (byte)25,
(byte)71, (byte)-126, (byte)-95, (byte)-12, (byte)-120, (byte)-122, (byte)-35, (byte)-82,
(byte)127, (byte)-40, (byte)-46, (byte)114, (byte)32, (byte)-11, (byte)53, (byte)-61,
(byte)-54, (byte)127, (byte)39, (byte)103, (byte)40, (byte)-65, (byte)91, (byte)-99,
(byte)-63, (byte)107, (byte)-59, (byte)29, (byte)95, (byte)-4, (byte)8, (byte)59,
(byte)-35, (byte)-74, (byte)-16, (byte)-109, (byte)-53, (byte)-98, (byte)84, (byte)87,
(byte)125, (byte)-22, (byte)-91, (byte)69, (byte)-94, (byte)-57, (byte)-43, (byte)-113,
(byte)67, (byte)-87, (byte)-2, (byte)117, (byte)-104, (byte)-71, (byte)16, (byte)-38,
(byte)-28, (byte)5, (byte)17, (byte)67, (byte)-98, (byte)-30, (byte)-105, (byte)61,
(byte)28, (byte)57, (byte)9, (byte)25, (byte)-78, (byte)-79, (byte)106, (byte)-10,
(byte)-60, (byte)56, (byte)92, (byte)124, (byte)12, (byte)-65, (byte)117, (byte)-75,
(byte)-116, (byte)85, (byte)98, (byte)82, (byte)104, (byte)-100, (byte)88, (byte)-91,
(byte)111, (byte)83, (byte)-18, (byte)68, (byte)-76, (byte)69, (byte)75, (byte)11,
(byte)42, (byte)58, (byte)-97, (byte)8, (byte)-35, (byte)-116, (byte)-107, (byte)22,
(byte)74, (byte)-97, (byte)-46, (byte)-96, (byte)-88, (byte)-46, (byte)18, (byte)109,
(byte)-104, (byte)99, (byte)-125, (byte)-103, (byte)53, (byte)-110, (byte)-35, (byte)-92,
(byte)87, (byte)-127, (byte)60, (byte)35, (byte)-97, (byte)-87, (byte)-113, (byte)-112,
(byte)-3, (byte)-103, (byte)2, (byte)-76, (byte)-47, (byte)84, (byte)94, (byte)-58,
(byte)20, (byte)93, (byte)-128, (byte)-41, (byte)-67, (byte)17, (byte)102, (byte)-22,
(byte)69, (byte)54, (byte)-60, (byte)-36, (byte)-124, (byte)98, (byte)112, (byte)-79,
(byte)-10, (byte)68, (byte)89, (byte)41, (byte)53, (byte)4, (byte)47, (byte)78,
(byte)121, (byte)67, (byte)-52, (byte)-38, (byte)119, (byte)41, (byte)69, (byte)31,
(byte)35, (byte)-91, (byte)-86, (byte)-60, (byte)-48, (byte)-17, (byte)67, (byte)-39,
(byte)-5, (byte)-123, (byte)121, (byte)-122, (byte)-125, (byte)-75, (byte)-94, (byte)117,
(byte)-117, (byte)-116, (byte)125, (byte)103, (byte)74, (byte)-25, (byte)38, (byte)56,
(byte)-2, (byte)2, (byte)80, (byte)75, (byte)7, (byte)8, (byte)39, (byte)-48,
(byte)-69, (byte)-98, (byte)-101, (byte)1, (byte)0, (byte)0, (byte)-86, (byte)2,
(byte)0, (byte)0, (byte)80, (byte)75, (byte)1, (byte)2, (byte)20, (byte)0,
(byte)20, (byte)0, (byte)8, (byte)0, (byte)8, (byte)0, (byte)12, (byte)88,
(byte)-62, (byte)68, (byte)39, (byte)-48, (byte)-69, (byte)-98, (byte)-101, (byte)1,
(byte)0, (byte)0, (byte)-86, (byte)2, (byte)0, (byte)0, (byte)49, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0,
(byte)99, (byte)111, (byte)109, (byte)47, (byte)101, (byte)120, (byte)97, (byte)109,
(byte)112, (byte)108, (byte)101, (byte)47, (byte)115, (byte)104, (byte)114, (byte)105,
(byte)110, (byte)107, (byte)117, (byte)110, (byte)105, (byte)116, (byte)116, (byte)101,
(byte)115, (byte)116, (byte)47, (byte)97, (byte)112, (byte)112, (byte)47, (byte)77,
(byte)97, (byte)105, (byte)110, (byte)65, (byte)99, (byte)116, (byte)105, (byte)118,
(byte)105, (byte)116, (byte)121, (byte)46, (byte)99, (byte)108, (byte)97, (byte)115,
(byte)115, (byte)80, (byte)75, (byte)5, (byte)6, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)1, (byte)0, (byte)1, (byte)0, (byte)95, (byte)0, (byte)0,
(byte)0, (byte)-6, (byte)1, (byte)0, (byte)0, (byte)0, (byte)0
};
return createFile(dir, "app/build/classes-proguard/release/classes.jar", bytecode);
}
private static File createUnproguardedClasses(File dir) throws IOException {
byte [] bytecode = new byte[] {
(byte)80, (byte)75, (byte)3, (byte)4, (byte)20, (byte)0, (byte)8, (byte)0,
(byte)8, (byte)0, (byte)-11, (byte)-127, (byte)-61, (byte)68, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)9, (byte)0, (byte)4, (byte)0, (byte)77, (byte)69,
(byte)84, (byte)65, (byte)45, (byte)73, (byte)78, (byte)70, (byte)47, (byte)-2,
(byte)-54, (byte)0, (byte)0, (byte)3, (byte)0, (byte)80, (byte)75, (byte)7,
(byte)8, (byte)0, (byte)0, (byte)0, (byte)0, (byte)2, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)80, (byte)75, (byte)3,
(byte)4, (byte)20, (byte)0, (byte)8, (byte)0, (byte)8, (byte)0, (byte)-11,
(byte)-127, (byte)-61, (byte)68, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)20,
(byte)0, (byte)0, (byte)0, (byte)77, (byte)69, (byte)84, (byte)65, (byte)45,
(byte)73, (byte)78, (byte)70, (byte)47, (byte)77, (byte)65, (byte)78, (byte)73,
(byte)70, (byte)69, (byte)83, (byte)84, (byte)46, (byte)77, (byte)70, (byte)-13,
(byte)77, (byte)-52, (byte)-53, (byte)76, (byte)75, (byte)45, (byte)46, (byte)-47,
(byte)13, (byte)75, (byte)45, (byte)42, (byte)-50, (byte)-52, (byte)-49, (byte)-77,
(byte)82, (byte)48, (byte)-44, (byte)51, (byte)-32, (byte)-27, (byte)114, (byte)46,
(byte)74, (byte)77, (byte)44, (byte)73, (byte)77, (byte)-47, (byte)117, (byte)-86,
(byte)4, (byte)9, (byte)-104, (byte)-23, (byte)25, (byte)-60, (byte)-101, (byte)-103,
(byte)42, (byte)104, (byte)56, (byte)22, (byte)20, (byte)-28, (byte)-92, (byte)42,
(byte)120, (byte)-26, (byte)37, (byte)-21, (byte)105, (byte)-14, (byte)114, (byte)-15,
(byte)114, (byte)1, (byte)0, (byte)80, (byte)75, (byte)7, (byte)8, (byte)127,
(byte)71, (byte)56, (byte)-57, (byte)60, (byte)0, (byte)0, (byte)0, (byte)60,
(byte)0, (byte)0, (byte)0, (byte)80, (byte)75, (byte)3, (byte)4, (byte)20,
(byte)0, (byte)8, (byte)0, (byte)8, (byte)0, (byte)-49, (byte)-127, (byte)-61,
(byte)68, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)49, (byte)0, (byte)0,
(byte)0, (byte)99, (byte)111, (byte)109, (byte)47, (byte)101, (byte)120, (byte)97,
(byte)109, (byte)112, (byte)108, (byte)101, (byte)47, (byte)115, (byte)104, (byte)114,
(byte)105, (byte)110, (byte)107, (byte)117, (byte)110, (byte)105, (byte)116, (byte)116,
(byte)101, (byte)115, (byte)116, (byte)47, (byte)97, (byte)112, (byte)112, (byte)47,
(byte)77, (byte)97, (byte)105, (byte)110, (byte)65, (byte)99, (byte)116, (byte)105,
(byte)118, (byte)105, (byte)116, (byte)121, (byte)46, (byte)99, (byte)108, (byte)97,
(byte)115, (byte)115, (byte)-107, (byte)-109, (byte)-51, (byte)82, (byte)19, (byte)65,
(byte)16, (byte)-57, (byte)-1, (byte)-109, (byte)4, (byte)-106, (byte)-124, (byte)13,
(byte)-127, (byte)64, (byte)-126, (byte)32, (byte)72, (byte)16, (byte)-112, (byte)124,
(byte)8, (byte)43, (byte)-8, (byte)45, (byte)-96, (byte)66, (byte)4, (byte)-115,
(byte)5, (byte)90, (byte)37, (byte)22, (byte)7, (byte)47, (byte)-44, (byte)-110,
(byte)-116, (byte)48, (byte)-78, (byte)-103, (byte)77, (byte)101, (byte)39, (byte)81,
(byte)-34, (byte)-58, (byte)7, (byte)-32, (byte)34, (byte)7, (byte)40, (byte)61,
(byte)-8, (byte)0, (byte)62, (byte)-109, (byte)101, (byte)-39, (byte)-77, (byte)89,
(byte)80, (byte)-85, (byte)66, (byte)-91, (byte)-36, (byte)-61, (byte)-12, (byte)108,
(byte)79, (byte)-9, (byte)111, (byte)122, (byte)-2, (byte)-45, (byte)-13, (byte)-29,
(byte)-41, (byte)-73, (byte)-17, (byte)0, (byte)22, (byte)-15, (byte)50, (byte)6,
(byte)19, (byte)51, (byte)122, (byte)-72, (byte)17, (byte)-59, (byte)44, (byte)-78,
(byte)49, (byte)-12, (byte)34, (byte)-89, (byte)-121, (byte)124, (byte)20, (byte)5,
(byte)-36, (byte)-116, (byte)97, (byte)14, (byte)-13, (byte)-67, (byte)-80, (byte)112,
(byte)43, (byte)-118, (byte)5, (byte)44, (byte)-22, (byte)-72, (byte)-37, (byte)6,
(byte)-18, (byte)24, (byte)-72, (byte)-53, (byte)-48, (byte)-67, (byte)44, (byte)-92,
(byte)80, (byte)-113, (byte)25, (byte)-62, (byte)-39, (byte)-36, (byte)14, (byte)67,
(byte)-92, (byte)-24, (byte)86, (byte)56, (byte)67, (byte)98, (byte)83, (byte)72,
(byte)-2, (byte)-86, (byte)81, (byte)-35, (byte)-29, (byte)-11, (byte)-73, (byte)-10,
(byte)-98, (byte)67, (byte)-98, (byte)-28, (byte)-90, (byte)91, (byte)-74, (byte)-99,
(byte)29, (byte)-69, (byte)46, (byte)-12, (byte)127, (byte)-32, (byte)-116, (byte)-88,
(byte)3, (byte)-31, (byte)49, (byte)-52, (byte)109, (byte)-106, (byte)-35, (byte)-86,
(byte)-59, (byte)63, (byte)-39, (byte)-43, (byte)-102, (byte)-61, (byte)45, (byte)-17,
(byte)-96, (byte)46, (byte)-28, (byte)97, (byte)-125, (byte)-88, (byte)-118, (byte)123,
(byte)-54, (byte)-78, (byte)107, (byte)53, (byte)107, (byte)-53, (byte)22, (byte)114,
(byte)-75, (byte)-84, (byte)68, (byte)83, (byte)-88, (byte)-93, (byte)37, (byte)-122,
(byte)30, (byte)87, (byte)22, (byte)-21, (byte)-36, (byte)86, (byte)68, (byte)72,
(byte)103, (byte)55, (byte)109, (byte)89, (byte)-87, (byte)-69, (byte)-94, (byte)98,
(byte)-71, (byte)-98, (byte)-75, (byte)-42, (byte)-112, (byte)21, (byte)-121, (byte)47,
(byte)-23, (byte)66, (byte)-110, (byte)-98, (byte)-35, (byte)-28, (byte)-107, (byte)-110,
(byte)-12, (byte)-108, (byte)45, (byte)-53, (byte)124, (byte)91, (byte)-7, (byte)-47,
(byte)-125, (byte)109, (byte)-126, (byte)-55, (byte)123, (byte)-114, (byte)123, (byte)93,
(byte)83, (byte)-62, (byte)-107, (byte)-34, (byte)22, (byte)-105, (byte)-115, (byte)127,
(byte)-56, (byte)77, (byte)-63, (byte)63, (byte)90, (byte)-38, (byte)-69, (byte)-108,
(byte)123, (byte)71, (byte)69, (byte)87, (byte)-3, (byte)-11, (byte)-63, (byte)54,
(byte)-53, (byte)12, (byte)41, (byte)87, (byte)6, (byte)-108, (byte)-110, (byte)-30,
(byte)-43, (byte)109, (byte)-18, (byte)-16, (byte)-78, (byte)-30, (byte)21, (byte)-122,
(byte)-47, (byte)54, (byte)52, (byte)29, (byte)-47, (byte)34, (byte)10, (byte)-102,
(byte)49, (byte)12, (byte)95, (byte)18, (byte)-62, (byte)16, (byte)18, (byte)-124,
(byte)96, (byte)37, (byte)-122, (byte)56, (byte)29, (byte)-92, (byte)124, (byte)-72,
(byte)101, (byte)-41, (byte)2, (byte)1, (byte)99, (byte)-37, (byte)110, (byte)-93,
(byte)94, (byte)-26, (byte)27, (byte)66, (byte)-1, (byte)12, (byte)-4, (byte)45,
(byte)-45, (byte)-4, (byte)7, (byte)-69, (byte)105, (byte)-101, (byte)-120, (byte)-93,
(byte)-49, (byte)-60, (byte)16, (byte)82, (byte)6, (byte)-18, (byte)-101, (byte)120,
(byte)-124, (byte)73, (byte)19, (byte)75, (byte)88, (byte)54, (byte)-79, (byte)-126,
(byte)-57, (byte)6, (byte)-98, (byte)-104, (byte)120, (byte)-118, (byte)73, (byte)3,
(byte)-85, (byte)38, (byte)-42, (byte)80, (byte)52, (byte)-16, (byte)-52, (byte)-60,
(byte)58, (byte)54, (byte)12, (byte)60, (byte)55, (byte)-15, (byte)66, (byte)71,
(byte)-114, (byte)97, (byte)-100, (byte)-95, (byte)-16, (byte)31, (byte)87, (byte)-61,
(byte)48, (byte)116, (byte)126, (byte)2, (byte)-67, (byte)116, (byte)-18, (byte)54,
(byte)64, (byte)-107, (byte)-49, (byte)118, (byte)-32, (byte)-68, (byte)-103, (byte)118,
(byte)-20, (byte)35, (byte)-73, (byte)-95, (byte)-88, (byte)-93, (byte)-50, (byte)39,
(byte)102, (byte)73, (byte)74, (byte)94, (byte)47, (byte)58, (byte)-74, (byte)-25,
(byte)113, (byte)-22, (byte)-110, (byte)-72, (byte)29, (byte)-16, (byte)118, (byte)-85,
(byte)-76, (byte)39, (byte)67, (byte)-97, (byte)-57, (byte)85, (byte)-47, (byte)-107,
(byte)-118, (byte)75, (byte)-75, (byte)67, (byte)122, (byte)-111, (byte)-116, (byte)-39,
(byte)-110, (byte)-66, (byte)-7, (byte)-60, (byte)62, (byte)87, (byte)-66, (byte)118,
(byte)-14, (byte)-67, (byte)67, (byte)-105, (byte)90, (byte)103, (byte)24, (byte)-49,
(byte)-26, (byte)-38, (byte)72, (byte)27, (byte)44, (byte)-109, (byte)-68, (byte)51,
(byte)29, (byte)107, (byte)107, (byte)93, (byte)121, (byte)-92, (byte)-75, (byte)-15,
(byte)-56, (byte)-91, (byte)44, (byte)6, (byte)67, (byte)-76, (byte)-90, (byte)116,
(byte)-101, (byte)-39, (byte)82, (byte)-69, (byte)6, (byte)-94, (byte)2, (byte)83,
(byte)109, (byte)-81, (byte)-103, (byte)33, (byte)74, (byte)-123, (byte)-21, (byte)89,
(byte)-87, (byte)-30, (byte)-65, (byte)38, (byte)18, (byte)109, (byte)-86, (byte)99,
(byte)97, (byte)-70, (byte)49, (byte)18, (byte)90, (byte)24, (byte)87, (byte)-18,
(byte)-110, (byte)30, (byte)74, (byte)-56, (byte)125, (byte)-110, (byte)42, (byte)-45,
(byte)41, (byte)15, (byte)-109, (byte)-12, (byte)-72, (byte)77, (byte)-24, (byte)47,
(byte)2, (byte)-90, (byte)-69, (byte)-124, (byte)-58, (byte)4, (byte)-3, (byte)89,
(byte)100, (byte)25, (byte)-39, (byte)-82, (byte)-4, (byte)25, (byte)-40, (byte)23,
(byte)-102, (byte)-124, (byte)-48, (byte)79, (byte)99, (byte)-73, (byte)-17, (byte)-116,
(byte)98, (byte)-128, (byte)70, (byte)-77, (byte)21, (byte)-128, (byte)36, (byte)6,
(byte)-3, (byte)116, (byte)-22, (byte)-82, (byte)32, (byte)-71, (byte)68, (byte)-47,
(byte)33, (byte)-78, (byte)-15, (byte)124, (byte)-31, (byte)12, (byte)-95, (byte)-4,
(byte)9, (byte)-62, (byte)-89, (byte)-120, (byte)-4, (byte)-127, (byte)-12, (byte)33,
(byte)-84, (byte)23, (byte)41, (byte)-75, (byte)-113, (byte)32, (byte)9, (byte)31,
(byte)-106, (byte)110, (byte)37, (byte)4, (byte)48, (byte)61, (byte)75, (byte)99,
(byte)-40, (byte)-81, (byte)-31, (byte)10, (byte)70, (byte)2, (byte)-20, (byte)58,
(byte)-27, (byte)-75, (byte)-80, (byte)-89, (byte)-24, (byte)58, (byte)65, (byte)119,
(byte)-31, (byte)20, (byte)70, (byte)-28, (byte)-8, (byte)2, (byte)27, (byte)-13,
(byte)23, (byte)83, (byte)116, (byte)-96, (byte)-12, (byte)37, (byte)-56, (byte)81,
(byte)92, (byte)-11, (byte)-111, (byte)-44, (byte)-48, (byte)1, (byte)-46, (byte)-95,
(byte)24, (byte)93, (byte)76, (byte)-70, (byte)-16, (byte)21, (byte)61, (byte)12,
(byte)43, (byte)99, (byte)39, (byte)-120, (byte)126, (byte)70, (byte)87, (byte)-28,
(byte)88, (byte)87, (byte)30, (byte)-45, (byte)-20, (byte)-80, (byte)-49, (byte)78,
(byte)-46, (byte)-7, (byte)-128, (byte)107, (byte)48, (byte)48, (byte)65, (byte)69,
(byte)103, (byte)-56, (byte)119, (byte)-35, (byte)-33, (byte)35, (byte)-45, (byte)-54,
(byte)-66, (byte)-40, (byte)35, (byte)77, (byte)49, (byte)19, (byte)-60, (byte)54,
(byte)-120, (byte)-98, (byte)33, (byte)113, (byte)67, (byte)20, (byte)-25, (byte)-85,
(byte)-10, (byte)19, (byte)-3, (byte)-12, (byte)124, (byte)49, (byte)-27, (byte)87,
(byte)59, (byte)-115, (byte)-121, (byte)100, (byte)71, (byte)41, (byte)119, (byte)22,
(byte)-9, (byte)-16, (byte)-128, (byte)14, (byte)88, (byte)32, (byte)59, (byte)74,
(byte)118, (byte)-127, (byte)108, (byte)6, (byte)35, (byte)-65, (byte)1, (byte)80,
(byte)75, (byte)7, (byte)8, (byte)-67, (byte)119, (byte)-82, (byte)40, (byte)-35,
(byte)2, (byte)0, (byte)0, (byte)-111, (byte)5, (byte)0, (byte)0, (byte)80,
(byte)75, (byte)3, (byte)4, (byte)20, (byte)0, (byte)8, (byte)0, (byte)8,
(byte)0, (byte)-49, (byte)-127, (byte)-61, (byte)68, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)48, (byte)0, (byte)0, (byte)0, (byte)99, (byte)111, (byte)109,
(byte)47, (byte)101, (byte)120, (byte)97, (byte)109, (byte)112, (byte)108, (byte)101,
(byte)47, (byte)115, (byte)104, (byte)114, (byte)105, (byte)110, (byte)107, (byte)117,
(byte)110, (byte)105, (byte)116, (byte)116, (byte)101, (byte)115, (byte)116, (byte)47,
(byte)97, (byte)112, (byte)112, (byte)47, (byte)66, (byte)117, (byte)105, (byte)108,
(byte)100, (byte)67, (byte)111, (byte)110, (byte)102, (byte)105, (byte)103, (byte)46,
(byte)99, (byte)108, (byte)97, (byte)115, (byte)115, (byte)-115, (byte)81, (byte)-37,
(byte)110, (byte)-45, (byte)64, (byte)16, (byte)61, (byte)-45, (byte)92, (byte)-20,
(byte)4, (byte)-105, (byte)-74, (byte)-127, (byte)2, (byte)-31, (byte)82, (byte)40,
(byte)-41, (byte)36, (byte)20, (byte)-101, (byte)-10, (byte)-107, (byte)10, (byte)41,
(byte)23, (byte)-73, (byte)-118, (byte)72, (byte)-109, (byte)-86, (byte)105, (byte)45,
(byte)-47, (byte)-105, (byte)104, (byte)-29, (byte)44, (byte)-83, (byte)-117, (byte)99,
(byte)71, (byte)-66, (byte)32, (byte)126, (byte)11, (byte)-15, (byte)0, (byte)-22,
(byte)3, (byte)31, (byte)-64, (byte)71, (byte)33, (byte)-58, (byte)38, (byte)74,
(byte)-115, (byte)120, (byte)-31, (byte)97, (byte)103, (byte)-9, (byte)-52, (byte)-50,
(byte)57, (byte)51, (byte)123, (byte)-10, (byte)-25, (byte)-81, (byte)-53, (byte)31,
(byte)0, (byte)118, (byte)-96, (byte)-105, (byte)81, (byte)-60, (byte)35, (byte)21,
(byte)-101, (byte)101, (byte)60, (byte)-58, (byte)-109, (byte)18, (byte)10, (byte)120,
(byte)-86, (byte)-32, (byte)-103, (byte)-126, (byte)-25, (byte)-124, (byte)66, (byte)-57,
(byte)108, (byte)-99, (byte)-20, (byte)19, (byte)-24, (byte)-108, (byte)-96, (byte)29,
(byte)54, (byte)-37, (byte)-17, (byte)-102, (byte)-5, (byte)-26, (byte)-88, (byte)-33,
(byte)60, (byte)48, (byte)9, (byte)-107, (byte)-34, (byte)-123, (byte)-8, (byte)36,
(byte)12, (byte)87, (byte)120, (byte)103, (byte)-58, (byte)48, (byte)10, (byte)28,
(byte)-17, (byte)-20, (byte)13, (byte)97, (byte)-71, (byte)-19, (byte)123, (byte)97,
(byte)36, (byte)-68, (byte)-56, (byte)18, (byte)110, (byte)44, (byte)85, (byte)-68,
(byte)32, (byte)-108, (byte)91, (byte)39, (byte)-35, (byte)94, (byte)103, (byte)116,
(byte)-4, (byte)-2, (byte)-48, (byte)84, (byte)81, (byte)35, (byte)20, (byte)-9,
(byte)122, (byte)77, (byte)107, (byte)112, (byte)-92, (byte)-94, (byte)-50, (byte)-110,
(byte)-106, (byte)121, (byte)52, (byte)-20, (byte)14, (byte)-6, (byte)-93, (byte)-10,
(byte)-96, (byte)-61, (byte)-110, (byte)-44, (byte)-51, (byte)-15, (byte)64, (byte)-108,
(byte)-55, (byte)39, (byte)-83, (byte)84, (byte)52, (byte)-104, (byte)-75, (byte)-21,
(byte)120, (byte)78, (byte)-12, (byte)-106, (byte)-112, (byte)-85, (byte)-43, (byte)45,
(byte)66, (byte)-66, (byte)-19, (byte)79, (byte)36, (byte)97, (byte)-91, (byte)-25,
(byte)120, (byte)-78, (byte)31, (byte)79, (byte)-57, (byte)50, (byte)56, (byte)22,
(byte)99, (byte)87, (byte)38, (byte)83, (byte)-7, (byte)-74, (byte)112, (byte)45,
(byte)17, (byte)56, (byte)9, (byte)-98, (byte)39, (byte)-13, (byte)-47, (byte)-71,
(byte)19, (byte)18, (byte)-74, (byte)122, (byte)-74, (byte)63, (byte)53, (byte)-28,
(byte)103, (byte)49, (byte)-99, (byte)-71, (byte)-46, (byte)8, (byte)-49, (byte)121,
(byte)-26, (byte)-113, (byte)49, (byte)-85, (byte)70, (byte)50, (byte)-116, (byte)12,
(byte)49, (byte)-101, (byte)25, (byte)-83, (byte)-40, (byte)113, (byte)39, (byte)-4,
(byte)-126, (byte)15, (byte)78, (byte)-14, (byte)22, (byte)117, (byte)-41, (byte)118,
(byte)-25, (byte)77, (byte)-53, (byte)67, (byte)63, (byte)14, (byte)108, (byte)-71,
(byte)-25, (byte)36, (byte)106, (byte)-85, (byte)-103, (byte)50, (byte)61, (byte)-15,
(byte)64, (byte)-61, (byte)45, (byte)-36, (byte)78, (byte)-70, (byte)4, (byte)-79,
(byte)84, (byte)-16, (byte)82, (byte)-61, (byte)22, (byte)94, (byte)105, (byte)80,
(byte)-96, (byte)18, (byte)26, (byte)-1, (byte)-33, (byte)-111, (byte)-123, (byte)-81,
(byte)12, (byte)29, (byte)-116, (byte)47, (byte)-92, (byte)29, (byte)17, (byte)54,
(byte)-104, (byte)-81, (byte)-49, (byte)-7, (byte)-6, (byte)-33, (byte)124, (byte)-99,
(byte)-7, (byte)-4, (byte)65, (byte)19, (byte)57, (byte)-114, (byte)-103, (byte)11,
(byte)118, (byte)102, (byte)91, (byte)127, (byte)77, (byte)88, (byte)-69, (byte)18,
(byte)105, (byte)-7, (byte)-66, (byte)43, (byte)-123, (byte)-57, (byte)118, (byte)-50,
(byte)68, (byte)16, (byte)-54, (byte)5, (byte)92, (byte)-81, (byte)-3, (byte)-5,
(byte)117, (byte)-11, (byte)83, (byte)108, (byte)-13, (byte)-57, (byte)23, (byte)-39,
(byte)-1, (byte)34, (byte)-86, (byte)-55, (byte)-16, (byte)124, (byte)-86, (byte)-94,
(byte)-124, (byte)50, (byte)43, (byte)95, (byte)-29, (byte)-13, (byte)18, (byte)52,
(byte)-58, (byte)-53, (byte)25, (byte)124, (byte)-99, (byte)-15, (byte)74, (byte)6,
(byte)-81, (byte)50, (byte)94, (byte)67, (byte)101, (byte)-127, (byte)111, (byte)48,
(byte)-66, (byte)-103, (byte)-71, (byte)95, (byte)-25, (byte)69, (byte)-119, (byte)85,
(byte)28, (byte)-17, (byte)112, (byte)-58, (byte)-32, (byte)-99, (byte)7, (byte)71,
(byte)-95, (byte)-15, (byte)13, (byte)-12, (byte)37, (byte)45, (byte)-87, (byte)-90,
(byte)-19, (byte)41, (byte)-115, (byte)119, (byte)57, (byte)106, (byte)127, (byte)10,
(byte)112, (byte)15, (byte)-9, (byte)121, (byte)87, (byte)-15, (byte)96, (byte)65,
(byte)-34, (byte)76, (byte)111, (byte)-128, (byte)82, (byte)101, (byte)-23, (byte)59,
(byte)114, (byte)95, (byte)-111, (byte)79, (byte)4, (byte)40, (byte)35, (byte)-96,
(byte)112, (byte)-36, (byte)72, (byte)69, (byte)31, (byte)-2, (byte)6, (byte)80,
(byte)75, (byte)7, (byte)8, (byte)-81, (byte)-102, (byte)-119, (byte)99, (byte)-46,
(byte)1, (byte)0, (byte)0, (byte)-23, (byte)2, (byte)0, (byte)0, (byte)80,
(byte)75, (byte)1, (byte)2, (byte)20, (byte)0, (byte)20, (byte)0, (byte)8,
(byte)0, (byte)8, (byte)0, (byte)-11, (byte)-127, (byte)-61, (byte)68, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)2, (byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)9, (byte)0, (byte)4, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)77, (byte)69, (byte)84,
(byte)65, (byte)45, (byte)73, (byte)78, (byte)70, (byte)47, (byte)-2, (byte)-54,
(byte)0, (byte)0, (byte)80, (byte)75, (byte)1, (byte)2, (byte)20, (byte)0,
(byte)20, (byte)0, (byte)8, (byte)0, (byte)8, (byte)0, (byte)-11, (byte)-127,
(byte)-61, (byte)68, (byte)127, (byte)71, (byte)56, (byte)-57, (byte)60, (byte)0,
(byte)0, (byte)0, (byte)60, (byte)0, (byte)0, (byte)0, (byte)20, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)61, (byte)0, (byte)0, (byte)0,
(byte)77, (byte)69, (byte)84, (byte)65, (byte)45, (byte)73, (byte)78, (byte)70,
(byte)47, (byte)77, (byte)65, (byte)78, (byte)73, (byte)70, (byte)69, (byte)83,
(byte)84, (byte)46, (byte)77, (byte)70, (byte)80, (byte)75, (byte)1, (byte)2,
(byte)20, (byte)0, (byte)20, (byte)0, (byte)8, (byte)0, (byte)8, (byte)0,
(byte)-49, (byte)-127, (byte)-61, (byte)68, (byte)-67, (byte)119, (byte)-82, (byte)40,
(byte)-35, (byte)2, (byte)0, (byte)0, (byte)-111, (byte)5, (byte)0, (byte)0,
(byte)49, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)-69, (byte)0,
(byte)0, (byte)0, (byte)99, (byte)111, (byte)109, (byte)47, (byte)101, (byte)120,
(byte)97, (byte)109, (byte)112, (byte)108, (byte)101, (byte)47, (byte)115, (byte)104,
(byte)114, (byte)105, (byte)110, (byte)107, (byte)117, (byte)110, (byte)105, (byte)116,
(byte)116, (byte)101, (byte)115, (byte)116, (byte)47, (byte)97, (byte)112, (byte)112,
(byte)47, (byte)77, (byte)97, (byte)105, (byte)110, (byte)65, (byte)99, (byte)116,
(byte)105, (byte)118, (byte)105, (byte)116, (byte)121, (byte)46, (byte)99, (byte)108,
(byte)97, (byte)115, (byte)115, (byte)80, (byte)75, (byte)1, (byte)2, (byte)20,
(byte)0, (byte)20, (byte)0, (byte)8, (byte)0, (byte)8, (byte)0, (byte)-49,
(byte)-127, (byte)-61, (byte)68, (byte)-81, (byte)-102, (byte)-119, (byte)99, (byte)-46,
(byte)1, (byte)0, (byte)0, (byte)-23, (byte)2, (byte)0, (byte)0, (byte)48,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)-9, (byte)3, (byte)0,
(byte)0, (byte)99, (byte)111, (byte)109, (byte)47, (byte)101, (byte)120, (byte)97,
(byte)109, (byte)112, (byte)108, (byte)101, (byte)47, (byte)115, (byte)104, (byte)114,
(byte)105, (byte)110, (byte)107, (byte)117, (byte)110, (byte)105, (byte)116, (byte)116,
(byte)101, (byte)115, (byte)116, (byte)47, (byte)97, (byte)112, (byte)112, (byte)47,
(byte)66, (byte)117, (byte)105, (byte)108, (byte)100, (byte)67, (byte)111, (byte)110,
(byte)102, (byte)105, (byte)103, (byte)46, (byte)99, (byte)108, (byte)97, (byte)115,
(byte)115, (byte)80, (byte)75, (byte)5, (byte)6, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)4, (byte)0, (byte)4, (byte)0, (byte)58, (byte)1, (byte)0,
(byte)0, (byte)39, (byte)6, (byte)0, (byte)0, (byte)0, (byte)0,
};
return createFile(dir, "app/build/intermediates/classes/debug/classes.jar", bytecode);
}
private static File createMappingFile(File dir) throws IOException {
return createFile(dir, "app/build/proguard/release/mapping.txt", ""
+ "com.example.shrinkunittest.app.MainActivity -> com.example.shrinkunittest.app.MainActivity:\n"
+ " void onCreate(android.os.Bundle) -> onCreate\n"
+ " boolean onCreateOptionsMenu(android.view.Menu) -> onCreateOptionsMenu\n"
+ " boolean onOptionsItemSelected(android.view.MenuItem) -> onOptionsItemSelected");
}
public void testFormatStringRegexp() {
assertEquals(NO_MATCH, convertFormatStringToRegexp(""));
assertEquals("\\Qfoo_\\E", convertFormatStringToRegexp("foo_"));
assertEquals("\\Qfoo\\E.*\\Q_\\E.*\\Qend\\E", convertFormatStringToRegexp("foo%s_%1$send"));
assertEquals("\\Qescape!.()\\E", convertFormatStringToRegexp("escape!.()"));
assertEquals(NO_MATCH, convertFormatStringToRegexp("%c%c%c%d"));
assertEquals(NO_MATCH, convertFormatStringToRegexp("%d%s"));
assertEquals(NO_MATCH, convertFormatStringToRegexp("%s%s"));
assertEquals(NO_MATCH, convertFormatStringToRegexp("%d_%d"));
assertEquals(NO_MATCH, convertFormatStringToRegexp("%s%s%s%s"));
assertEquals(NO_MATCH, convertFormatStringToRegexp("%s_%s_%s"));
assertEquals(NO_MATCH, convertFormatStringToRegexp("%.0f%s"));
assertEquals(".*\\Qabc\\E", convertFormatStringToRegexp("%sabc"));
assertEquals("\\Qa\\E.*", convertFormatStringToRegexp("a%d%s"));
assertTrue("foo_".matches(convertFormatStringToRegexp("foo_")));
assertTrue("fooA_BBend".matches(convertFormatStringToRegexp("foo%s_%1$send")));
assertFalse("A_BBend".matches(convertFormatStringToRegexp("foo%s_%1$send")));
}
/** Utility method to generate byte array literal dump (used by classesJarBytecode above) */
@SuppressWarnings("UnusedDeclaration") // Utility for future .class/.jar additions
public static void dumpBytes(File file) throws IOException {
byte[] bytes = Files.toByteArray(file);
int count = 0;
for (byte b : bytes) {
System.out.print("(byte)" + Byte.toString(b) + ", ");
count++;
if (count == 8) {
count = 0;
System.out.println();
}
}
System.out.println();
}
@SuppressWarnings("ResultOfMethodCallIgnored")
protected static void deleteDir(File root) {
if (root.exists()) {
File[] files = root.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
deleteDir(file);
} else {
file.delete();
}
}
}
root.delete();
}
}
@SuppressWarnings("ResultOfMethodCallIgnored")
@NonNull
private static File createFile(File dir, String relative) throws IOException {
File file = new File(dir, relative.replace('/', separatorChar));
file.getParentFile().mkdirs();
return file;
}
@NonNull
private static File createFile(File dir, String relative, String contents) throws IOException {
File file = createFile(dir, relative);
Files.write(contents, file, Charsets.UTF_8);
return file;
}
@NonNull
private static File createFile(File dir, String relative, byte[] contents) throws IOException {
File file = createFile(dir, relative);
Files.write(contents, file);
return file;
}
private static void checkState(ResourceUsageAnalyzer analyzer) {
List<Resource> resources = analyzer.getAllResources();
Collections.sort(resources, new Comparator<Resource>() {
@Override
public int compare(Resource resource1, Resource resource2) {
int delta = resource1.type.compareTo(resource2.type);
if (delta != 0) {
return delta;
}
return resource1.name.compareTo(resource2.name);
}
});
// Ensure unique
Resource prev = null;
for (Resource resource : resources) {
assertTrue(resource + " and " + prev, prev == null
|| resource.type != prev.type
|| !resource.name.equals(prev.name));
prev = resource;
}
}
public void testIsResourceClass() {
assertTrue(ResourceUsageAnalyzer.isResourceClass("android/support/v7/appcompat/R$attr.class"));
assertTrue(ResourceUsageAnalyzer.isResourceClass("android/support/v7/appcompat/R$attr.class"));
assertTrue(ResourceUsageAnalyzer.isResourceClass("android/support/v7/appcompat/R$bool.class"));
assertFalse(ResourceUsageAnalyzer.isResourceClass("android/support/v7/appcompat/R.class"));
assertFalse(ResourceUsageAnalyzer.isResourceClass("com/google/samples/apps/iosched/ui/BrowseSessionsActivity.class"));
}
}