Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2de2e13d authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Refactor backported_fixes rules to share with cts" into main am: 8cccc28c

parents 87a37f64 8cccc28c
Loading
Loading
Loading
Loading
+46 −18
Original line number Diff line number Diff line
@@ -19,19 +19,24 @@ package {

genrule {
    name: "applied_backported_fixes",
    tools: ["applied_backported_fixes_main"],
    tools: ["applied_backported_fixes_property_writer"],
    srcs: [":applied_backported_fix_binpbs"],
    out: ["applied_backported_fixes.prop"],
    cmd: "$(location applied_backported_fixes_main)" +
    cmd: "$(location applied_backported_fixes_property_writer)" +
        " -p $(location applied_backported_fixes.prop)" +
        " $(in)",
}

java_library {
    name: "backported_fixes_proto",
filegroup {
    name: "backported_fixes_proto_file",
    srcs: [
        "backported_fixes.proto",
    ],
}

java_library {
    name: "backported_fixes_proto",
    srcs: ["backported_fixes.proto"],
    host_supported: true,
}

@@ -63,7 +68,7 @@ java_test_host {
}

java_library {
    name: "applied_backported_fixes_lib",
    name: "backported_fixes_main_lib",
    srcs: ["src/java/com/android/build/backportedfixes/*.java"],
    static_libs: [
        "backported_fixes_common",
@@ -75,18 +80,35 @@ java_library {
}

java_binary_host {
    name: "applied_backported_fixes_main",
    main_class: "com.android.build.backportedfixes.Main",
    name: "applied_backported_fixes_property_writer",
    main_class: "com.android.build.backportedfixes.WriteBackportedFixesPropFile",
    static_libs: [
        "applied_backported_fixes_lib",
        "backported_fixes_main_lib",
    ],
}

java_binary_host {
    name: "backported_fixes_combiner",
    main_class: "com.android.build.backportedfixes.CombineBackportedFixes",
    static_libs: [
        "backported_fixes_main_lib",
    ],
}

// Combines BackportedFix binary proto files into a single BackportedFixes binary proto file.
genrule_defaults {
    name: "default_backported_fixes_combiner",
    tools: ["backported_fixes_combiner"],
    cmd: "$(location backported_fixes_combiner)" +
        " -o $(out)" +
        " $(in)",
}

java_test_host {
    name: "applied_backported_fixes_test",
    name: "backported_fixes_main_lib_test",
    srcs: ["tests/java/com/android/build/backportedfixes/*.java"],
    static_libs: [
        "applied_backported_fixes_lib",
        "backported_fixes_main_lib",
        "backported_fixes_proto",
        "junit",
        "truth",
@@ -97,19 +119,25 @@ java_test_host {
    test_suites: ["general-tests"],
}

gensrcs {
    name: "applied_backported_fix_binpbs",
// Converts BackprotedFix text protos to binary protos
genrule_defaults {
    name: "default_backported_fix_binpbs",
    tools: ["aprotoc"],
    srcs: [
        "applied_fixes/*.txtpb",
    ],
    tool_files: [
        "backported_fixes.proto",
        ":backported_fixes_proto_file",
    ],
    output_extension: "binpb",
    cmd: "$(location aprotoc)  " +
        " --encode=com.android.build.backportedfixes.BackportedFix" +
        "  $(location backported_fixes.proto)" +
        "  $(location :backported_fixes_proto_file)" +
        " < $(in)" +
        " > $(out); echo $(out)",
}

gensrcs {
    name: "applied_backported_fix_binpbs",
    defaults: ["default_backported_fix_binpbs"],
    output_extension: "binpb",
    srcs: [
        "applied_fixes/*.txtpb",
    ],
}
+65 −0
Original line number Diff line number Diff line

/*
 * Copyright (C) 2024 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.backportedfixes;

import com.android.build.backportedfixes.common.Parser;

import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.converters.FileConverter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;


/** Creates a BackportedFixes binary proto file from a list of BackportedFix proto binary files. */
public final class CombineBackportedFixes {

    @Parameter(description = "BackportedFix proto binary files",
            converter = FileConverter.class,
            required = true)
    List<File> fixFiles;
    @Parameter(description = "Write the BackportedFixes proto binary to this file",
            names = {"--out","-o"},
            converter = FileConverter.class,
            required = true)
    File outFile;

    public static void main(String... argv) throws Exception {
        CombineBackportedFixes main = new CombineBackportedFixes();
        JCommander.newBuilder().addObject(main).build().parse(argv);
        main.run();
    }

    CombineBackportedFixes() {
    }

    private void run() throws Exception {
        try (var out = new FileOutputStream(outFile)) {
            var fixes = Parser.parseBackportedFixFiles(fixFiles);
            writeBackportedFixes(fixes, out);
        }
    }

    static void writeBackportedFixes(BackportedFixes fixes, OutputStream out)
            throws IOException {
        fixes.writeTo(out);
    }
}
+20 −10
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.build.backportedfixes;

import static java.nio.charset.StandardCharsets.UTF_8;

import com.android.build.backportedfixes.common.ClosableCollection;
import com.android.build.backportedfixes.common.Parser;

import com.beust.jcommander.JCommander;
@@ -33,27 +32,38 @@ import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public final class Main {
    @Parameter(description = "BackportedFix proto binary files", converter = FileConverter.class,

/**
 * Creates backported fix properties file.
 *
 * <p>Writes BitSet of backported fix aliases from a list of BackportedFix proto binary files and
 * writes the property {@value PROPERTY_NAME} to a file.
 */
public final class WriteBackportedFixesPropFile {

    private static final String PROPERTY_NAME = "ro.build.backported_fixes.alias_bitset.long_list";
    @Parameter(description = "BackportedFix proto binary files",
            converter = FileConverter.class,
            required = true)
    List<File> fixFiles;
    @Parameter(description = "The file to write the property value to.",
            names = {"--property_file", "-p"}, converter = FileConverter.class, required = true)
            names = {"--property_file", "-p"},
            converter = FileConverter.class,
            required = true)
    File propertyFile;

    public static void main(String... argv) throws Exception {
        Main main = new Main();
        WriteBackportedFixesPropFile main = new WriteBackportedFixesPropFile();
        JCommander.newBuilder().addObject(main).build().parse(argv);
        main.run();
    }

    Main() {
    WriteBackportedFixesPropFile() {
    }

    private void run() throws Exception {
        try (var fixStreams = ClosableCollection.wrap(Parser.getFileInputStreams(fixFiles));
             var out = Files.newWriter(propertyFile, UTF_8)) {
            var fixes = Parser.parseBackportedFixes(fixStreams.getCollection());
        try (var out = Files.newWriter(propertyFile, UTF_8)) {
            var fixes = Parser.parseBackportedFixFiles(fixFiles);
            writeFixesAsAliasBitSet(fixes, out);
        }
    }
@@ -70,7 +80,7 @@ public final class Main {
                fixes.getFixesList().stream().mapToInt(BackportedFix::getAlias).toArray());
        String bsString = Arrays.stream(bsArray).mapToObj(Long::toString).collect(
                Collectors.joining(","));
        printWriter.printf("ro.build.backported_fixes.alias_bitset.long_list=%s", bsString);
        printWriter.printf("%s=%s", PROPERTY_NAME, bsString);
        printWriter.println();
        if (printWriter.checkError()) {
            throw new RuntimeException("There was an error writing to " + out.toString());
+0 −67
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.backportedfixes.common;

import com.google.common.collect.ImmutableList;

import java.util.ArrayList;
import java.util.Collection;

/** An AutoCloseable holder for a collection of AutoCloseables. */
public final class ClosableCollection<T extends AutoCloseable, C extends Collection<T>> implements
        AutoCloseable {
    C source;

    /** Makes the collection AutoCloseable. */
    public static <T extends AutoCloseable, C extends Collection<T>> ClosableCollection<T, C> wrap(
            C source) {
        return new ClosableCollection<>(source);
    }

    private ClosableCollection(C source) {
        this.source = source;
    }

    /** Get the source collection. */
    public C getCollection() {
        return source;
    }

    /**
     * Closes each item in the collection.
     *
     * @throws Exception if any close throws an an exception, a new exception is thrown with
     *                   all the exceptions thrown closing the streams added as a suppressed
     *                   exceptions.
     */
    @Override
    public void close() throws Exception {
        var failures = new ArrayList<Exception>();
        for (T t : source) {
            try {
                t.close();
            } catch (Exception e) {
                failures.add(e);
            }
        }
        if (!failures.isEmpty()) {
            Exception e = new Exception(
                    "%d of %d failed while closing".formatted(failures.size(), source.size()));
            failures.forEach(e::addSuppressed);
            throw e;
        }
    }
}
+77 −8
Original line number Diff line number Diff line
@@ -15,9 +15,12 @@
 */
package com.android.build.backportedfixes.common;

import static com.google.common.base.Preconditions.checkNotNull;

import com.android.build.backportedfixes.BackportedFix;
import com.android.build.backportedfixes.BackportedFixes;

import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;

import java.io.File;
@@ -26,7 +29,10 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.BitSet;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;


/** Static utilities for working with {@link BackportedFixes}. */
@@ -54,16 +60,79 @@ public final class Parser {
    /**
     * Creates a {@link BackportedFixes} from a list of {@link BackportedFix} binary proto streams.
     */
    public static BackportedFixes parseBackportedFixes(List<? extends InputStream> fixStreams)
            throws
            IOException {
        var fixes = BackportedFixes.newBuilder();
        for (var s : fixStreams) {
            BackportedFix fix = BackportedFix.parseFrom(s);
            fixes.addFixes(fix);
    public static BackportedFixes parseBackportedFixFiles(List<File> fixFiles)
            throws IOException {
        try {
            return fixFiles.stream().map(Parser::tunelFileInputStream)
                    .map(Parser::tunnelParse)
                    .sorted(Comparator.comparing(BackportedFix::getKnownIssue))
                    .collect(fixCollector());

        } catch (TunnelException e) {
            throw e.rethrow(FileNotFoundException.class, IOException.class);
        }
    }


    private static Collector<BackportedFix, ?, BackportedFixes> fixCollector() {
        return Collectors.collectingAndThen(Collectors.toList(), fixList -> {
            var result = BackportedFixes.newBuilder();
            result.addAllFixes(fixList);
            return result.build();
        });
    }

    private static FileInputStream tunelFileInputStream(File file) throws TunnelException {
        try {
            return new FileInputStream(file);
        } catch (FileNotFoundException e) {
            throw new TunnelException(e);
        }
    }

    private static BackportedFix tunnelParse(InputStream s) throws TunnelException {
        try {
            var fix = BackportedFix.parseFrom(s);
            s.close();
            return fix;
        } catch (IOException e) {
            throw new TunnelException(e);
        }
        return fixes.build();
    }

    private static class TunnelException extends RuntimeException {
        TunnelException(Exception cause) {
            super("If you see this TunnelException something went wrong.  It should always be rethrown as the cause.", cause);
        }

        <X extends Exception> RuntimeException rethrow(Class<X> exceptionClazz) throws X {
            checkNotNull(exceptionClazz);
            Throwables.throwIfInstanceOf(getCause(), exceptionClazz);
            throw exception(
                    getCause(),
                    "rethrow(%s) doesn't match underlying exception", exceptionClazz);
        }

        public <X1 extends Exception, X2 extends Exception> RuntimeException rethrow(
                Class<X1> exceptionClazz1, Class<X2> exceptionClazz2) throws X1, X2 {
            checkNotNull(exceptionClazz1);
            checkNotNull(exceptionClazz2);
            Throwables.throwIfInstanceOf(getCause(), exceptionClazz1);
            Throwables.throwIfInstanceOf(getCause(), exceptionClazz2);
            throw exception(
                    getCause(),
                    "rethrow(%s, %s) doesn't match underlying exception",
                    exceptionClazz1,
                    exceptionClazz2);
        }

        private static ClassCastException exception(
                Throwable cause, String message, Object... formatArgs) {
            ClassCastException result = new ClassCastException(String.format(message, formatArgs));
            result.initCause(cause);
            return result;
        }

    }

    private Parser() {
Loading