diff --git a/ClassySharkWS/src/com/google/classyshark/Version.java b/ClassySharkWS/src/com/google/classyshark/Version.java index 9a94140e..26162d08 100644 --- a/ClassySharkWS/src/com/google/classyshark/Version.java +++ b/ClassySharkWS/src/com/google/classyshark/Version.java @@ -22,5 +22,5 @@ public class Version { public static final int MAJOR = 7; - public static final int MINOR = 1; + public static final int MINOR = 2; } diff --git a/ClassySharkWS/src/com/google/classyshark/silverghost/translator/apk/ApkTranslator.java b/ClassySharkWS/src/com/google/classyshark/silverghost/translator/apk/ApkTranslator.java index 717ee72c..b1e1c8a7 100644 --- a/ClassySharkWS/src/com/google/classyshark/silverghost/translator/apk/ApkTranslator.java +++ b/ClassySharkWS/src/com/google/classyshark/silverghost/translator/apk/ApkTranslator.java @@ -55,6 +55,9 @@ public void apply() { apkDashboard = new ApkDashboard(apkFile); apkDashboard.inspect(); + ELEMENT element = new ELEMENT("\n ~ APK DASHBOARD ~\n" , TAG.IDENTIFIER); + elements.add(element); + Iterator dexesIter = apkDashboard.iterator(); @@ -62,7 +65,7 @@ public void apply() { ClassesDexDataEntry dexEntry = dexesIter.next(); - ELEMENT element = new ELEMENT("\n" + dexEntry.getName(), TAG.MODIFIER); + element = new ELEMENT("\n" + dexEntry.getName(), TAG.MODIFIER); elements.add(element); element = new ELEMENT( @@ -74,7 +77,13 @@ public void apply() { elements.add(element); } - ELEMENT element = new ELEMENT("\n\n\nDynamic Symbol Errors", TAG.MODIFIER); + element = new ELEMENT("\n\nPossible Java Dependencies Errors", TAG.MODIFIER); + elements.add(element); + + element = new ELEMENT("\n" + apkDashboard.getJavaDependenciesErrorsAsString(), TAG.DOCUMENT); + elements.add(element); + + element = new ELEMENT("\n\n\nDynamic Symbol Errors", TAG.MODIFIER); elements.add(element); for (String error : apkDashboard.getNativeErrors()) { @@ -131,11 +140,9 @@ public List getDependencies() { public String toString() { StringBuilder sb = new StringBuilder(); - for (ELEMENT element : elements) { sb.append(element.text); } - return sb.toString(); } } \ No newline at end of file diff --git a/ClassySharkWS/src/com/google/classyshark/silverghost/translator/apk/dashboard/ApkDashboard.java b/ClassySharkWS/src/com/google/classyshark/silverghost/translator/apk/dashboard/ApkDashboard.java index a08dd72c..a0adab68 100644 --- a/ClassySharkWS/src/com/google/classyshark/silverghost/translator/apk/dashboard/ApkDashboard.java +++ b/ClassySharkWS/src/com/google/classyshark/silverghost/translator/apk/dashboard/ApkDashboard.java @@ -40,7 +40,8 @@ public class ApkDashboard implements Iterable { public ArrayList customClassesDexEntries = new ArrayList<>(); public List nativeLibs = new ArrayList<>(); public ArrayList nativeDependencies = new ArrayList<>(); - public List nativeErrors = new LinkedList<>(); + public List nativeErrors = new ArrayList<>(); + public List allClasses = new ArrayList<>(); public File apkFile; public ApkDashboard(File apkFile) { @@ -84,7 +85,6 @@ public String getPrivateLibErrorTag(String nativeLib) { } else { return ""; } - } public static Set getClassesWithNativeMethodsPerDexIndex(int dexIndex, @@ -95,6 +95,25 @@ public static Set getClassesWithNativeMethodsPerDexIndex(int dexIndex, return dexInspectionsData.classesWithNativeMethods; } + public String getJavaDependenciesErrorsAsString() { + List javaDependenciesErrors = getJavaDependenciesErrors(); + + StringBuilder builder = new StringBuilder(); + + for (String javaDepError : javaDependenciesErrors) { + builder.append(javaDepError); + } + + return builder.toString(); + } + + public List getJavaDependenciesErrors() { + JavaDependenciesInspector ddi = new JavaDependenciesInspector(allClasses); + List result = ddi.getInspections(); + + return result; + } + public static ClassesDexDataEntry fillAnalysisPerClassesDexIndex(int dexIndex, File classesDex) { ClassesDexDataEntry dexData = new ClassesDexDataEntry(dexIndex); diff --git a/ClassySharkWS/src/com/google/classyshark/silverghost/translator/apk/dashboard/JavaDependenciesInspector.java b/ClassySharkWS/src/com/google/classyshark/silverghost/translator/apk/dashboard/JavaDependenciesInspector.java new file mode 100644 index 00000000..fe1e745d --- /dev/null +++ b/ClassySharkWS/src/com/google/classyshark/silverghost/translator/apk/dashboard/JavaDependenciesInspector.java @@ -0,0 +1,132 @@ +/* + * Copyright 2016 Google, Inc. + * + * 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.google.classyshark.silverghost.translator.apk.dashboard; + +import java.util.ArrayList; +import java.util.List; + +public class JavaDependenciesInspector { + + private final List allClasses; + + private int imageLoading = 0; + private boolean hasGlide; + private boolean hasPicasso; + private boolean hasFresco; + + private int asyncHttp = 0; + private boolean hasOkHttp; + private boolean hasVolley; + private boolean hasLoopj; + + private int jsonParsing = 0; + private boolean hasJackson; + private boolean hasGson; + + // other dependencies + private boolean hasGuava; + private boolean hasDeprecatedHttp; + private boolean hasActionBarSherlock; + private boolean hasPullToRefresh; + + public JavaDependenciesInspector(List allClasses) { + this.allClasses = allClasses; + } + + public List getInspections() { + List result = new ArrayList<>(); + + for (String cName : allClasses) { + updateLogic(cName); + } + + if (imageLoading > 1) { + result.add("\n* Duplicate image loading libraries - "); + if (hasPicasso) result.add("picasso "); + if (hasGlide) result.add("glide "); + if (hasFresco) result.add("fresco "); + } + + if (asyncHttp > 1) { + result.add("\n* Duplicate async http libraries - "); + if (hasOkHttp) result.add("okhttp "); + if (hasVolley) result.add("volley "); + if (hasLoopj) result.add("loopj "); + } + + if (jsonParsing > 1) { + result.add("\n* Duplicate json parsing - "); + if (hasJackson) result.add("jackson "); + if (hasGson) result.add("gson "); + } + + if (hasGuava) { + result.add("\n* Guava (server side library)usage"); + } + + if (hasDeprecatedHttp) { + result.add("\n* Apache Http is deprecated"); + } + + if (hasActionBarSherlock) { + result.add("\n* ActionBar Sherlock is deprecated"); + } + + if (hasPullToRefresh) { + result.add("\n* PullToRefresh is deprecated"); + } + + return result; + } + + private void updateLogic(String cName) { + + if (cName.contains("glide") && !hasGlide) { + hasGlide = true; + imageLoading++; + } else if (cName.contains("picasso") && !hasPicasso) { + hasPicasso = true; + imageLoading++; + } else if (cName.contains("fresco") && !hasFresco) { + hasFresco = true; + imageLoading++; + } else if (cName.contains("okhttp") && !hasOkHttp) { + hasOkHttp = true; + asyncHttp++; + } else if (cName.contains("volley") && !hasVolley) { + hasVolley = true; + asyncHttp++; + } else if (cName.contains("loopj") && !hasLoopj) { + hasLoopj = true; + asyncHttp++; + } else if (cName.contains("fasterxml.jackson") && !hasJackson) { + hasJackson = true; + jsonParsing++; + } else if (cName.contains("google.code.gson") && !hasGson) { + hasGson = true; + jsonParsing++; + } else if (cName.contains("google.common") && !hasGuava) { + hasGuava = true; + } else if (cName.contains("apache.http") && !hasDeprecatedHttp) { + hasDeprecatedHttp = true; + } else if (cName.contains("'com.actionbarsherlock") && !hasActionBarSherlock) { + hasActionBarSherlock = true; + } else if (cName.contains("chrisbanes.pulltorefresh") && !hasPullToRefresh) { + hasPullToRefresh = true; + } + } +} diff --git a/ClassySharkWS/src/com/google/classyshark/silverghost/translator/java/dex/MultidexReader.java b/ClassySharkWS/src/com/google/classyshark/silverghost/translator/java/dex/MultidexReader.java index 2288b5bb..ea56605d 100644 --- a/ClassySharkWS/src/com/google/classyshark/silverghost/translator/java/dex/MultidexReader.java +++ b/ClassySharkWS/src/com/google/classyshark/silverghost/translator/java/dex/MultidexReader.java @@ -25,6 +25,7 @@ import com.google.classyshark.silverghost.translator.elf.ElfTranslator; import java.io.File; import java.io.FileInputStream; +import java.util.ArrayList; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -125,6 +126,8 @@ public static void fillApkDashboard(File binaryArchiveFile, ApkDashboard to) { } catch (Exception e) { e.printStackTrace(); } + + readClassNamesFromMultidex(binaryArchiveFile, to.allClasses, new ArrayList()); } public static void readClassNamesFromMultidex(File binaryArchiveFile,