Skip to content

Commit

Permalink
merge internal:optimize hook proguard、improve compatibility、add check…
Browse files Browse the repository at this point in the history
…IncrementalInDebug、fix npe cased by refer-checker
  • Loading branch information
yangzhiqian committed Jul 27, 2020
1 parent a028267 commit 28a94be
Show file tree
Hide file tree
Showing 40 changed files with 539 additions and 302 deletions.
1 change: 1 addition & 0 deletions HookProguard/ProguardConfigurationResolver/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
7 changes: 7 additions & 0 deletions HookProguard/ProguardConfigurationResolver/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apply plugin: 'java'
group "$upload_group"
version "$upload_version"
apply from: rootProject.file('gradle/publish.gradle')
dependencies {
compileOnly gradleApi()
}
2 changes: 2 additions & 0 deletions HookProguard/ProguardConfigurationResolver/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ARTIFACT_GROUP=com.bytedance.android.byteX
ARTIFACT_NAME=ProguardConfigurationResolver
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.ss.android.ugc.bytex.proguardconfigurationresolver;

import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.file.FileCollection;

import javax.annotation.Nullable;

/**
* Created by yangzhiqian on 2020/7/6<br/>
*/
public abstract class ProguardConfigurationResolver {
protected Project project;
protected String variantName;

public ProguardConfigurationResolver(Project project, String variantName) {
this.project = project;
this.variantName = variantName;
}

@Nullable
public abstract Task getTask();

@Nullable
public abstract FileCollection getAllConfigurationFiles();
}

1 change: 1 addition & 0 deletions HookProguard/ProguardConfigurationResolver/task/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
11 changes: 11 additions & 0 deletions HookProguard/ProguardConfigurationResolver/task/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apply plugin: 'java'
group "$upload_group"
version "$upload_version"

dependencies {
compileOnly gradleApi()
compileOnly "com.android.tools.build:gradle:3.6.2"
implementation project(":ProguardConfigurationResolver")
}

apply from: rootProject.file('gradle/publish.gradle')
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ARTIFACT_GROUP=com.bytedance.android.byteX
ARTIFACT_NAME=ProguardConfigurationResolver-task
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.ss.android.ugc.bytex.proguardconfigurationresolver.task;

import com.android.build.gradle.internal.tasks.ProguardConfigurableTask;
import com.android.build.gradle.internal.tasks.ProguardTask;
import com.android.build.gradle.internal.tasks.R8Task;
import com.ss.android.ugc.bytex.proguardconfigurationresolver.ProguardConfigurationResolver;

import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.file.FileCollection;

/**
* Created by yangzhiqian on 2020/7/6<br/>
*/
public class ProguardConfigurableTaskResolver extends ProguardConfigurationResolver {

public ProguardConfigurableTaskResolver(Project project, String variantName) {
super(project, variantName);
}

@Override
public Task getTask() {
for (Task task : project.getTasks()) {
if ((task instanceof ProguardTask || task instanceof R8Task) &&
((ProguardConfigurableTask) task).getVariantName().equals(variantName)) {
return task;
}
}
return null;
}

@Override
public FileCollection getAllConfigurationFiles() {
Task task = getTask();
if (task == null) {
return null;
}
return ((ProguardConfigurableTask) getTask()).getConfigurationFiles();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
11 changes: 11 additions & 0 deletions HookProguard/ProguardConfigurationResolver/transform/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apply plugin: 'java'
group "$upload_group"
version "$upload_version"

dependencies {
compileOnly gradleApi()
compileOnly "com.android.tools.build:gradle:3.5.3"
implementation project(":ProguardConfigurationResolver")
}

apply from: rootProject.file('gradle/publish.gradle')
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ARTIFACT_GROUP=com.bytedance.android.byteX
ARTIFACT_NAME=ProguardConfigurationResolver-transform
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.ss.android.ugc.bytex.proguardconfigurationresolver.transform;

import com.android.build.gradle.internal.pipeline.TransformTask;
import com.android.build.gradle.internal.transforms.ProguardConfigurable;
import com.ss.android.ugc.bytex.proguardconfigurationresolver.ProguardConfigurationResolver;

import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.file.FileCollection;

import java.lang.reflect.Method;

/**
* Created by yangzhiqian on 2020/7/6<br/>
*/
public class ProguardConfigurableTransformResolver extends ProguardConfigurationResolver {

public ProguardConfigurableTransformResolver(Project project, String variantName) {
super(project, variantName);
}

@Override
public Task getTask() {
for (Task task : project.getTasks()) {
if (task instanceof TransformTask) {
TransformTask transformTask = (TransformTask) task;
String name = transformTask.getTransform().getClass().getName();
if (transformTask.getVariantName().equals(variantName) &&
("com.android.build.gradle.internal.transforms.ProGuardTransform".equals(name) ||
"com.android.build.gradle.internal.transforms.R8Transform".equals(name))) {
return task;
}
}
}
return null;
}

@Override
public FileCollection getAllConfigurationFiles() {
Task task = getTask();
if (task == null) {
return null;
}
ProguardConfigurable proguardConfigurable = (ProguardConfigurable) ((TransformTask) task).getTransform();
try {
Method method = ProguardConfigurable.class.getDeclaredMethod("getAllConfigurationFiles");
method.setAccessible(true);
return (FileCollection) method.invoke(proguardConfigurable);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
7 changes: 6 additions & 1 deletion HookProguard/build.gradle
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
apply from: rootProject.file('gradle/plugin.gradle')
apply from: rootProject.file('gradle/plugin.gradle')
dependencies {
implementation project(':ProguardConfigurationResolver')
implementation project(':ProguardConfigurationResolver-task')
implementation project(':ProguardConfigurationResolver-transform')
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@
import com.android.build.gradle.LibraryExtension;
import com.android.build.gradle.LibraryPlugin;
import com.android.build.gradle.api.BaseVariant;
import com.android.build.gradle.internal.pipeline.TransformTask;
import com.android.build.gradle.internal.transforms.ProGuardTransform;
import com.android.build.gradle.internal.transforms.ProguardConfigurable;
import com.android.build.gradle.internal.transforms.R8Transform;
import com.ss.android.ugc.bytex.common.configuration.BooleanProperty;
import com.ss.android.ugc.bytex.common.graph.Graph;
import com.ss.android.ugc.bytex.common.graph.Node;
import com.ss.android.ugc.bytex.proguardconfigurationresolver.ProguardConfigurationResolver;

import org.gradle.api.Plugin;
import org.gradle.api.Project;
Expand All @@ -24,9 +21,9 @@
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
Expand Down Expand Up @@ -293,38 +290,26 @@ private static class ProguardConfigurationWithVariantAnalyzer {
// specification with the class hierarchy
private final List<KeepClassSpecificationHolder> classHierarchySpecifications = new ArrayList<>();
private final Map<String, Long> configurationFiles = new HashMap<>();
private ProguardConfigurable proGuardTransform;
private final ProguardConfigurationResolver configurationResolver;
private boolean valid = false;

ProguardConfigurationWithVariantAnalyzer(Project project, String variantName, Set<String> dependenciesRunBeforeTasks, boolean verify) {
super();
Task hookTask = null;
for (Task task : project.getTasks()) {
if (task instanceof TransformTask) {
TransformTask transformTask = (TransformTask) task;
if (transformTask.getVariantName().equals(variantName) && (transformTask.getTransform() instanceof ProGuardTransform || transformTask.getTransform() instanceof R8Transform)) {
hookTask = task;
proGuardTransform = (ProguardConfigurable) transformTask.getTransform();
FileCollection fileCollection = getAllConfigurationFileCollection();
String capitalVariantName = variantName.substring(0, 1).toUpperCase() + variantName.substring(1);
dependenciesRunBeforeTasks.stream()
.map(s -> task.getProject().getTasks().findByName(s + capitalVariantName))
.filter(Objects::nonNull)
.forEach(t -> t.dependsOn(fileCollection));
if (verify) {
task.doFirst(task1 -> verifyProguardConfiguration());
task.doLast(task12 -> verifyProguardConfiguration());
}
}
}
}
final Task hTask = hookTask;
configurationResolver = ProguardConfigurationResolverFactory.createProguardConfigurationResolver(project, variantName);
Task hookTask = configurationResolver.getTask();
if (hookTask != null) {
String capitalVariantName = variantName.substring(0, 1).toUpperCase() + variantName.substring(1);
dependenciesRunBeforeTasks.stream()
.map(s -> hookTask.getProject().getTasks().findByName(s + capitalVariantName))
.filter(Objects::nonNull)
.forEach(t -> t.dependsOn(configurationResolver.getAllConfigurationFiles()));
if (verify) {
hookTask.doFirst(task1 -> verifyProguardConfiguration());
hookTask.doLast(task12 -> verifyProguardConfiguration());
}
project.getGradle()
.getTaskGraph()
.whenReady(taskExecutionGraph -> valid = taskExecutionGraph.hasTask(hTask));
} else {
project.getLogger().warn("Can not find proguard task for " + variantName);
.whenReady(taskExecutionGraph -> valid = taskExecutionGraph.hasTask(hookTask));
}
}

Expand Down Expand Up @@ -387,26 +372,17 @@ synchronized void prepare() {
}

private List<File> getAllConfigurationFiles() {
FileCollection allConfigurationFiles = configurationResolver.getAllConfigurationFiles();
if (allConfigurationFiles == null) {
return Collections.emptyList();
}
List<File> allFiles = new LinkedList<>();
for (File file : getAllConfigurationFileCollection()) {
for (File file : allConfigurationFiles) {
allFiles.add(file);
}
return allFiles;
}

private FileCollection getAllConfigurationFileCollection() {
if (proGuardTransform == null) {
throw new RuntimeException("This plugin can only be applied in release build or when proguard is enabled.");
}
try {
Method method = ProguardConfigurable.class.getDeclaredMethod("getAllConfigurationFiles");
method.setAccessible(true);
return (FileCollection) method.invoke(proGuardTransform);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private void filterAndSplit(Configuration configuration) {
if (configuration.keep == null) return;
List<KeepClassSpecification> newKeepList = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.ss.android.ugc.bytex.hookproguard;

import com.android.builder.model.Version;
import com.android.repository.Revision;
import com.ss.android.ugc.bytex.proguardconfigurationresolver.ProguardConfigurationResolver;
import com.ss.android.ugc.bytex.proguardconfigurationresolver.task.ProguardConfigurableTaskResolver;
import com.ss.android.ugc.bytex.proguardconfigurationresolver.transform.ProguardConfigurableTransformResolver;

import org.gradle.api.Project;

/**
* Created by yangzhiqian on 2020/7/27<br/>
*/
class ProguardConfigurationResolverFactory {
public static ProguardConfigurationResolver createProguardConfigurationResolver(Project project, String variantName) {
Revision revision = Revision.parseRevision(Version.ANDROID_GRADLE_PLUGIN_VERSION);
if (revision.getMajor() >= 3 && revision.getMinor() >= 6) {
return new ProguardConfigurableTaskResolver(project, variantName);
} else {
return new ProguardConfigurableTransformResolver(project, variantName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package com.ss.android.ugc.bytex.transformer
import com.android.build.api.transform.Status
import com.android.build.api.transform.TransformInput
import com.android.build.api.transform.TransformInvocation
import com.android.build.gradle.internal.utils.toImmutableList
import com.android.build.gradle.internal.utils.toImmutableMap
import com.google.common.collect.Streams
import com.google.gson.GsonBuilder
import com.google.gson.TypeAdapter
Expand Down Expand Up @@ -69,7 +67,7 @@ class TransformInputs internal constructor(private val context: TransformContext
}.forEach {
map[it.parent] = it.items.toSet()
}
map.toImmutableMap()
Collections.unmodifiableMap(map)
} finally {
//用完即删
cacheFile.delete()
Expand All @@ -86,7 +84,7 @@ class TransformInputs internal constructor(private val context: TransformContext
}
}
}
inputs.toImmutableMap()
Collections.unmodifiableMap(inputs)
}

val changedFiles by lazy {
Expand Down Expand Up @@ -206,7 +204,7 @@ class TransformInputs internal constructor(private val context: TransformContext
}
}
`in`.endObject()
return Entry(parent!!, items!!.toImmutableList())
return Entry(parent!!, Collections.unmodifiableList(items!!))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package com.ss.android.ugc.bytex.transformer

import com.android.build.api.transform.*
import com.android.build.gradle.internal.pipeline.TransformManager
import com.android.build.gradle.internal.utils.toImmutableList
import com.android.build.gradle.internal.utils.toImmutableMap
import com.google.common.hash.Hashing
import com.google.common.io.Files
import com.google.gson.GsonBuilder
Expand Down Expand Up @@ -72,7 +70,7 @@ class TransformOutputs internal constructor(private val context: TransformContex
for (entry in it) {
map[entry.path] = entry
}
map.toImmutableMap()
Collections.unmodifiableMap(map)
}
} finally {
//用完即删
Expand Down Expand Up @@ -187,7 +185,7 @@ class TransformOutputs internal constructor(private val context: TransformContex
items.add(it.outputEntry("$parent/$relativePath"))
}
items.sort()
items.toImmutableList()
Collections.unmodifiableList(items)
}
val hash = if (status == Status.REMOVED || bytes == null || bytes.isEmpty()) {
INVALID_HASH
Expand Down Expand Up @@ -247,7 +245,7 @@ class TransformOutputs internal constructor(private val context: TransformContex
}
}
`in`.endObject()
return Entry(input, path!!, hash, items.toImmutableList())
return Entry(input, path!!, hash, Collections.unmodifiableList(items))
}
}

Expand Down
Loading

0 comments on commit 28a94be

Please sign in to comment.