diff options
author | android-build-prod (mdb) <android-build-team-robot@google.com> | 2020-04-27 21:43:53 +0000 |
---|---|---|
committer | android-build-prod (mdb) <android-build-team-robot@google.com> | 2020-04-27 21:43:53 +0000 |
commit | bc674344739cd0e400ac78853f456542e01d8afb (patch) | |
tree | 3b6c36375f0d0e569d4b2e2de5d089bbe9e18160 | |
parent | fab52c92a96daf8ef778afc2b343c7ba4551105e (diff) | |
parent | 0ecdee5310522cd1b04d2241b612aa9a5c100167 (diff) | |
download | platform_external_jarjar-bc674344739cd0e400ac78853f456542e01d8afb.tar.gz platform_external_jarjar-bc674344739cd0e400ac78853f456542e01d8afb.tar.bz2 platform_external_jarjar-bc674344739cd0e400ac78853f456542e01d8afb.zip |
Snap for 6435660 from 0ecdee5310522cd1b04d2241b612aa9a5c100167 to sdk-releaseplatform-tools-30.0.1
Change-Id: If9ea07e85eb55f661ff086f859d7daff71f87d89
-rw-r--r-- | Android.bp | 5 | ||||
-rw-r--r-- | src/android/com/android/jarjar/RemoveAndroidCompatAnnotationsJarTransformer.java | 120 | ||||
-rw-r--r-- | src/main/com/tonicsystems/jarjar/Main.java | 6 | ||||
-rw-r--r-- | src/main/com/tonicsystems/jarjar/MainProcessor.java | 15 |
4 files changed, 143 insertions, 3 deletions
@@ -16,7 +16,10 @@ java_library_host { name: "jarjar", manifest: "manifest.txt", - srcs: ["src/main/**/*.java"], + srcs: [ + "src/android/**/*.java", + "src/main/**/*.java", + ], java_resource_dirs: ["res"], static_libs: [ diff --git a/src/android/com/android/jarjar/RemoveAndroidCompatAnnotationsJarTransformer.java b/src/android/com/android/jarjar/RemoveAndroidCompatAnnotationsJarTransformer.java new file mode 100644 index 0000000..990e048 --- /dev/null +++ b/src/android/com/android/jarjar/RemoveAndroidCompatAnnotationsJarTransformer.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2020 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.jarjar; + +import com.tonicsystems.jarjar.util.JarTransformer; + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.commons.Remapper; + +import java.util.Set; +import java.util.function.Supplier; + +/** + * A transformer that removes annotations from repackaged classes. + */ +public final class RemoveAndroidCompatAnnotationsJarTransformer extends JarTransformer { + + private static final Set<String> REMOVE_ANNOTATIONS = Set.of( + "Landroid/compat/annotation/UnsupportedAppUsage;"); + + private final Remapper remapper; + + public RemoveAndroidCompatAnnotationsJarTransformer(Remapper remapper) { + this.remapper = remapper; + } + + protected ClassVisitor transform(ClassVisitor classVisitor) { + return new AnnotationRemover(classVisitor); + } + + private class AnnotationRemover extends ClassVisitor { + + private boolean isClassRemapped; + + AnnotationRemover(ClassVisitor cv) { + super(Opcodes.ASM6, cv); + } + + @Override + public void visit(int version, int access, String name, String signature, String superName, + String[] interfaces) { + String newName = remapper.map(name); + // On every new class header visit, remember whether the class is repackaged. + isClassRemapped = newName != null && !newName.equals(name); + super.visit(version, access, name, signature, superName, interfaces); + } + + @Override + public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { + return visitAnnotationCommon(descriptor, + () -> super.visitAnnotation(descriptor, visible)); + } + + @Override + public FieldVisitor visitField(int access, String name, String descriptor, String signature, + Object value) { + FieldVisitor superVisitor = + super.visitField(access, name, descriptor, signature, value); + return new FieldVisitor(Opcodes.ASM6, superVisitor) { + @Override + public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { + return visitAnnotationCommon(descriptor, + () -> super.visitAnnotation(descriptor, visible)); + + } + }; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, + String signature, String[] exceptions) { + MethodVisitor superVisitor = + super.visitMethod(access, name, descriptor, signature, exceptions); + return new MethodVisitor(Opcodes.ASM6, superVisitor) { + @Override + public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { + return visitAnnotationCommon(descriptor, + () -> super.visitAnnotation(descriptor, visible)); + } + }; + } + + /** + * Create an {@link AnnotationVisitor} that removes any annotations from {@link + * #REMOVE_ANNOTATIONS} if the class is being repackaged. + * + * <p>For the annotations to be dropped correctly, do not visit the annotation beforehand, + * provide a supplier instead. + */ + private AnnotationVisitor visitAnnotationCommon(String annotation, + Supplier<AnnotationVisitor> defaultVisitorSupplier) { + if (isClassRemapped && REMOVE_ANNOTATIONS.contains(annotation)) { + return null; + } + // Only get() the default AnnotationVisitor if the annotation is to be included. + // Invoking super.visitAnnotation(descriptor, visible) causes the annotation to be + // included in the output even if the resulting AnnotationVisitor is not returned or + // used. + return defaultVisitorSupplier.get(); + } + } +} diff --git a/src/main/com/tonicsystems/jarjar/Main.java b/src/main/com/tonicsystems/jarjar/Main.java index 117bdbb..1eaa3e3 100644 --- a/src/main/com/tonicsystems/jarjar/Main.java +++ b/src/main/com/tonicsystems/jarjar/Main.java @@ -90,7 +90,11 @@ public class Main { List<PatternElement> rules = RulesFileParser.parse(rulesFile); boolean verbose = Boolean.getBoolean("verbose"); boolean skipManifest = Boolean.getBoolean("skipManifest"); - MainProcessor proc = new MainProcessor(rules, verbose, skipManifest); + // ANDROID-BEGIN: b/146418363 Add an Android-specific transformer to strip compat annotation + boolean removeAndroidCompatAnnotations = Boolean.getBoolean("removeAndroidCompatAnnotations"); + MainProcessor proc = new MainProcessor(rules, verbose, skipManifest, + removeAndroidCompatAnnotations); + // ANDROID-END: b/146418363 Add an Android-specific transformer to strip compat annotation StandaloneJarProcessor.run(inJar, outJar, proc); proc.strip(outJar); } diff --git a/src/main/com/tonicsystems/jarjar/MainProcessor.java b/src/main/com/tonicsystems/jarjar/MainProcessor.java index de15924..2778cc5 100644 --- a/src/main/com/tonicsystems/jarjar/MainProcessor.java +++ b/src/main/com/tonicsystems/jarjar/MainProcessor.java @@ -21,14 +21,23 @@ import java.io.File; import java.io.IOException; import java.util.*; +import com.android.jarjar.RemoveAndroidCompatAnnotationsJarTransformer; + class MainProcessor implements JarProcessor { private final boolean verbose; private final JarProcessorChain chain; private final KeepProcessor kp; private final Map<String, String> renames = new HashMap<String, String>(); - + + // ANDROID-BEGIN: b/146418363 Add an Android-specific transformer to strip compat annotation public MainProcessor(List<PatternElement> patterns, boolean verbose, boolean skipManifest) { + this(patterns, verbose, skipManifest, false /* removeAndroidCompatAnnotations */); + } + + public MainProcessor(List<PatternElement> patterns, boolean verbose, boolean skipManifest, + boolean removeAndroidCompatAnnotations) { + // ANDROID-END: b/146418363 Add an Android-specific transformer to strip compat annotation this.verbose = verbose; List<Zap> zapList = new ArrayList<Zap>(); List<Rule> ruleList = new ArrayList<Rule>(); @@ -52,6 +61,10 @@ class MainProcessor implements JarProcessor if (kp != null) processors.add(kp); processors.add(new ZapProcessor(zapList)); + // ANDROID-BEGIN: b/146418363 Add an Android-specific transformer to strip compat annotation + if (removeAndroidCompatAnnotations) + processors.add(new RemoveAndroidCompatAnnotationsJarTransformer(pr)); + // ANDROID-END: b/146418363 Add an Android-specific transformer to strip compat annotation processors.add(new JarTransformerChain(new RemappingClassTransformer[]{ new RemappingClassTransformer(pr) })); processors.add(new ResourceProcessor(pr)); chain = new JarProcessorChain(processors.toArray(new JarProcessor[processors.size()])); |