Output apkcerts file for android_app_set.
Soong and Make have no ways to figure out what splits will be outputted
from a given android_app_set, so it's impossible for them to provide
full PACKAGES.$(LOCAL_MODULE).CERTIFICATE entries, which are required to
build a final apkcerts.txt. This change makes extract_apks produce
apkcerts.txt files for each input modules instead. The Make-side
counterpart of this change merges all local apkcerts.txt into a final
one.
Fixes: 160119159
Test: main_test.go
Test: m apkcerts-list
Change-Id: I321e80fd636a955213761f56a3ac64bfe7f7f7c0
diff --git a/cmd/extract_apks/main.go b/cmd/extract_apks/main.go
index e9a850e..db54ffb 100644
--- a/cmd/extract_apks/main.go
+++ b/cmd/extract_apks/main.go
@@ -24,6 +24,7 @@
"math"
"os"
"regexp"
+ "sort"
"strings"
"github.com/golang/protobuf/proto"
@@ -355,7 +356,7 @@
// Writes out selected entries, renaming them as needed
func (apkSet *ApkSet) writeApks(selected SelectionResult, config TargetConfig,
- writer Zip2ZipWriter) error {
+ writer Zip2ZipWriter, partition string) ([]string, error) {
// Renaming rules:
// splits/MODULE-master.apk to STEM.apk
// else
@@ -389,10 +390,11 @@
}
entryOrigin := make(map[string]string) // output entry to input entry
+ var apkcerts []string
for _, apk := range selected.entries {
apkFile, ok := apkSet.entries[apk]
if !ok {
- return fmt.Errorf("TOC refers to an entry %s which does not exist", apk)
+ return nil, fmt.Errorf("TOC refers to an entry %s which does not exist", apk)
}
inName := apkFile.Name
outName, ok := renamer(inName)
@@ -405,10 +407,15 @@
}
entryOrigin[outName] = inName
if err := writer.CopyFrom(apkFile, outName); err != nil {
- return err
+ return nil, err
+ }
+ if partition != "" {
+ apkcerts = append(apkcerts, fmt.Sprintf(
+ `name="%s" certificate="PRESIGNED" private_key="" partition="%s"`, outName, partition))
}
}
- return nil
+ sort.Strings(apkcerts)
+ return apkcerts, nil
}
func (apkSet *ApkSet) extractAndCopySingle(selected SelectionResult, outFile *os.File) error {
@@ -433,6 +440,9 @@
}
extractSingle = flag.Bool("extract-single", false,
"extract a single target and output it uncompressed. only available for standalone apks and apexes.")
+ apkcertsOutput = flag.String("apkcerts", "",
+ "optional apkcerts.txt output file containing signing info of all outputted apks")
+ partition = flag.String("partition", "", "partition string. required when -apkcerts is used.")
)
// Parse abi values
@@ -485,7 +495,8 @@
func processArgs() {
flag.Usage = func() {
fmt.Fprintln(os.Stderr, `usage: extract_apks -o <output-file> -sdk-version value -abis value `+
- `-screen-densities value {-stem value | -extract-single} [-allow-prereleased] <APK set>`)
+ `-screen-densities value {-stem value | -extract-single} [-allow-prereleased] `+
+ `[-apkcerts <apkcerts output file> -partition <partition>] <APK set>`)
flag.PrintDefaults()
os.Exit(2)
}
@@ -498,7 +509,8 @@
"allow prereleased")
flag.StringVar(&targetConfig.stem, "stem", "", "output entries base name in the output zip file")
flag.Parse()
- if (*outputFile == "") || len(flag.Args()) != 1 || *version == 0 || (targetConfig.stem == "" && !*extractSingle) {
+ if (*outputFile == "") || len(flag.Args()) != 1 || *version == 0 ||
+ (targetConfig.stem == "" && !*extractSingle) || (*apkcertsOutput != "" && *partition == "") {
flag.Usage()
}
targetConfig.sdkVersion = int32(*version)
@@ -536,7 +548,20 @@
log.Fatal(err)
}
}()
- err = apkSet.writeApks(sel, targetConfig, writer)
+ apkcerts, err := apkSet.writeApks(sel, targetConfig, writer, *partition)
+ if err == nil && *apkcertsOutput != "" {
+ apkcertsFile, err := os.Create(*apkcertsOutput)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer apkcertsFile.Close()
+ for _, a := range apkcerts {
+ _, err = apkcertsFile.WriteString(a + "\n")
+ if err != nil {
+ log.Fatal(err)
+ }
+ }
+ }
}
if err != nil {
log.Fatal(err)