■ ■ ■ ■ ■ ■
jadx-gui/src/main/java/jadx/gui/ui/treenodes/SummaryNode.java
| skipped 2 lines |
3 | 3 | | import java.io.File; |
4 | 4 | | import java.io.IOException; |
5 | 5 | | import java.util.Comparator; |
| 6 | + | import java.util.HashMap; |
6 | 7 | | import java.util.HashSet; |
7 | 8 | | import java.util.List; |
| 9 | + | import java.util.Map; |
8 | 10 | | import java.util.Set; |
9 | 11 | | import java.util.stream.Collectors; |
10 | 12 | | |
11 | 13 | | import javax.swing.Icon; |
12 | 14 | | import javax.swing.ImageIcon; |
13 | 15 | | |
| 16 | + | import org.apache.commons.lang3.StringUtils; |
14 | 17 | | import org.apache.commons.text.StringEscapeUtils; |
15 | 18 | | |
16 | 19 | | import jadx.api.ICodeInfo; |
| 20 | + | import jadx.api.ResourceFile; |
17 | 21 | | import jadx.api.impl.SimpleCodeInfo; |
18 | 22 | | import jadx.core.dex.attributes.IAttributeNode; |
19 | 23 | | import jadx.core.dex.nodes.ClassNode; |
| skipped 72 lines |
92 | 96 | | } |
93 | 97 | | builder.append("</ul>"); |
94 | 98 | | |
| 99 | + | addNativeLibsInfo(builder); |
| 100 | + | |
95 | 101 | | int methodsCount = classes.stream().mapToInt(cls -> cls.getMethods().size()).sum(); |
96 | 102 | | int fieldsCount = classes.stream().mapToInt(cls -> cls.getFields().size()).sum(); |
97 | 103 | | int insnCount = classes.stream().flatMap(cls -> cls.getMethods().stream()).mapToInt(MethodNode::getInsnsCount).sum(); |
| skipped 3 lines |
101 | 107 | | builder.append("<li>Methods: " + methodsCount + "</li>"); |
102 | 108 | | builder.append("<li>Fields: " + fieldsCount + "</li>"); |
103 | 109 | | builder.append("<li>Instructions: " + insnCount + " (units)</li>"); |
| 110 | + | builder.append("</ul>"); |
| 111 | + | } |
| 112 | + | |
| 113 | + | private void addNativeLibsInfo(StringEscapeUtils.Builder builder) { |
| 114 | + | List<String> nativeLibs = wrapper.getResources().stream() |
| 115 | + | .map(ResourceFile::getOriginalName) |
| 116 | + | .filter(f -> f.endsWith(".so")) |
| 117 | + | .sorted(Comparator.naturalOrder()) |
| 118 | + | .collect(Collectors.toList()); |
| 119 | + | builder.append("<h3>Native libs</h3>"); |
| 120 | + | builder.append("<ul>"); |
| 121 | + | if (nativeLibs.isEmpty()) { |
| 122 | + | builder.append("<li>Total count: 0</li>"); |
| 123 | + | } else { |
| 124 | + | Map<String, Set<String>> libsByArch = new HashMap<>(); |
| 125 | + | for (String libFile : nativeLibs) { |
| 126 | + | String[] parts = StringUtils.split(libFile, '/'); |
| 127 | + | int count = parts.length; |
| 128 | + | if (count >= 2) { |
| 129 | + | String arch = parts[count - 2]; |
| 130 | + | String name = parts[count - 1]; |
| 131 | + | libsByArch.computeIfAbsent(arch, (a) -> new HashSet<>()) |
| 132 | + | .add(name); |
| 133 | + | } |
| 134 | + | } |
| 135 | + | String arches = libsByArch.keySet().stream() |
| 136 | + | .sorted(Comparator.naturalOrder()) |
| 137 | + | .collect(Collectors.joining(", ")); |
| 138 | + | builder.append("<li>Arch list: " + arches + "</li>"); |
| 139 | + | |
| 140 | + | String perArchCount = libsByArch.entrySet().stream() |
| 141 | + | .map(entry -> entry.getKey() + ":" + entry.getValue().size()) |
| 142 | + | .sorted(Comparator.naturalOrder()) |
| 143 | + | .collect(Collectors.joining(", ")); |
| 144 | + | builder.append("<li>Per arch count: " + perArchCount + "</li>"); |
| 145 | + | |
| 146 | + | builder.append("<br>"); |
| 147 | + | builder.append("<li>Total count: " + nativeLibs.size() + "</li>"); |
| 148 | + | for (String lib : nativeLibs) { |
| 149 | + | builder.append("<li>"); |
| 150 | + | builder.escape(lib); |
| 151 | + | builder.append("</li>"); |
| 152 | + | } |
| 153 | + | } |
104 | 154 | | builder.append("</ul>"); |
105 | 155 | | } |
106 | 156 | | |
| skipped 61 lines |