Merge changes from topic "app_set" am: 25f15a18e5
am: cf0dd40fb3
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1893517 Change-Id: I0348caf9bf02422c844a7d68cfd288f858deead5
This commit is contained in:
@@ -52,10 +52,10 @@ var (
|
|||||||
// A copy rule.
|
// A copy rule.
|
||||||
Cp = pctx.AndroidStaticRule("Cp",
|
Cp = pctx.AndroidStaticRule("Cp",
|
||||||
blueprint.RuleParams{
|
blueprint.RuleParams{
|
||||||
Command: "rm -f $out && cp $cpPreserveSymlinks $cpFlags $in $out",
|
Command: "rm -f $out && cp $cpPreserveSymlinks $cpFlags $in $out$extraCmds",
|
||||||
Description: "cp $out",
|
Description: "cp $out",
|
||||||
},
|
},
|
||||||
"cpFlags")
|
"cpFlags", "extraCmds")
|
||||||
|
|
||||||
// A copy rule that only updates the output if it changed.
|
// A copy rule that only updates the output if it changed.
|
||||||
CpIfChanged = pctx.AndroidStaticRule("CpIfChanged",
|
CpIfChanged = pctx.AndroidStaticRule("CpIfChanged",
|
||||||
@@ -68,10 +68,10 @@ var (
|
|||||||
|
|
||||||
CpExecutable = pctx.AndroidStaticRule("CpExecutable",
|
CpExecutable = pctx.AndroidStaticRule("CpExecutable",
|
||||||
blueprint.RuleParams{
|
blueprint.RuleParams{
|
||||||
Command: "rm -f $out && cp $cpPreserveSymlinks $cpFlags $in $out && chmod +x $out",
|
Command: "rm -f $out && cp $cpPreserveSymlinks $cpFlags $in $out && chmod +x $out$extraCmds",
|
||||||
Description: "cp $out",
|
Description: "cp $out",
|
||||||
},
|
},
|
||||||
"cpFlags")
|
"cpFlags", "extraCmds")
|
||||||
|
|
||||||
// A timestamp touch rule.
|
// A timestamp touch rule.
|
||||||
Touch = pctx.AndroidStaticRule("Touch",
|
Touch = pctx.AndroidStaticRule("Touch",
|
||||||
|
@@ -456,6 +456,9 @@ func (s *makeVarsSingleton) writeInstalls(installs, symlinks []katiInstall) []by
|
|||||||
for _, dep := range install.implicitDeps {
|
for _, dep := range install.implicitDeps {
|
||||||
fmt.Fprintf(buf, " %s", dep.String())
|
fmt.Fprintf(buf, " %s", dep.String())
|
||||||
}
|
}
|
||||||
|
if extraFiles := install.extraFiles; extraFiles != nil {
|
||||||
|
fmt.Fprintf(buf, " %s", extraFiles.zip.String())
|
||||||
|
}
|
||||||
if len(install.orderOnlyDeps) > 0 {
|
if len(install.orderOnlyDeps) > 0 {
|
||||||
fmt.Fprintf(buf, " |")
|
fmt.Fprintf(buf, " |")
|
||||||
}
|
}
|
||||||
@@ -463,12 +466,14 @@ func (s *makeVarsSingleton) writeInstalls(installs, symlinks []katiInstall) []by
|
|||||||
fmt.Fprintf(buf, " %s", dep.String())
|
fmt.Fprintf(buf, " %s", dep.String())
|
||||||
}
|
}
|
||||||
fmt.Fprintln(buf)
|
fmt.Fprintln(buf)
|
||||||
|
fmt.Fprintln(buf, "\t@echo \"Install $@\"")
|
||||||
fmt.Fprintf(buf, "\trm -f $@ && cp -f %s $< $@", preserveSymlinksFlag)
|
fmt.Fprintf(buf, "\trm -f $@ && cp -f %s $< $@\n", preserveSymlinksFlag)
|
||||||
if install.executable {
|
if install.executable {
|
||||||
fmt.Fprintf(buf, " && chmod +x $@")
|
fmt.Fprintf(buf, "\tchmod +x $@\n")
|
||||||
|
}
|
||||||
|
if extraFiles := install.extraFiles; extraFiles != nil {
|
||||||
|
fmt.Fprintf(buf, "\tunzip -qDD -d '%s' '%s'\n", extraFiles.dir.String(), extraFiles.zip.String())
|
||||||
}
|
}
|
||||||
fmt.Fprintln(buf)
|
|
||||||
fmt.Fprintln(buf)
|
fmt.Fprintln(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,6 +509,7 @@ func (s *makeVarsSingleton) writeInstalls(installs, symlinks []katiInstall) []by
|
|||||||
fromStr = symlink.absFrom
|
fromStr = symlink.absFrom
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Fprintln(buf, "\t@echo \"Symlink $@\"")
|
||||||
fmt.Fprintf(buf, "\trm -f $@ && ln -sfn %s $@", fromStr)
|
fmt.Fprintf(buf, "\trm -f $@ && ln -sfn %s $@", fromStr)
|
||||||
fmt.Fprintln(buf)
|
fmt.Fprintln(buf)
|
||||||
fmt.Fprintln(buf)
|
fmt.Fprintln(buf)
|
||||||
|
@@ -381,6 +381,16 @@ type ModuleContext interface {
|
|||||||
// for which IsInstallDepNeeded returns true.
|
// for which IsInstallDepNeeded returns true.
|
||||||
InstallFile(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath
|
InstallFile(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath
|
||||||
|
|
||||||
|
// InstallFileWithExtraFilesZip creates a rule to copy srcPath to name in the installPath
|
||||||
|
// directory, and also unzip a zip file containing extra files to install into the same
|
||||||
|
// directory.
|
||||||
|
//
|
||||||
|
// The installed file will be returned by FilesToInstall(), and the PackagingSpec for the
|
||||||
|
// installed file will be returned by PackagingSpecs() on this module or by
|
||||||
|
// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
|
||||||
|
// for which IsInstallDepNeeded returns true.
|
||||||
|
InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path, extraZip Path, deps ...Path) InstallPath
|
||||||
|
|
||||||
// InstallSymlink creates a rule to create a symlink from src srcPath to name in the installPath
|
// InstallSymlink creates a rule to create a symlink from src srcPath to name in the installPath
|
||||||
// directory.
|
// directory.
|
||||||
//
|
//
|
||||||
@@ -2235,10 +2245,16 @@ type katiInstall struct {
|
|||||||
implicitDeps Paths
|
implicitDeps Paths
|
||||||
orderOnlyDeps Paths
|
orderOnlyDeps Paths
|
||||||
executable bool
|
executable bool
|
||||||
|
extraFiles *extraFilesZip
|
||||||
|
|
||||||
absFrom string
|
absFrom string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type extraFilesZip struct {
|
||||||
|
zip Path
|
||||||
|
dir InstallPath
|
||||||
|
}
|
||||||
|
|
||||||
type katiInstalls []katiInstall
|
type katiInstalls []katiInstall
|
||||||
|
|
||||||
// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
|
// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
|
||||||
@@ -2852,12 +2868,20 @@ func (m *moduleContext) skipInstall() bool {
|
|||||||
|
|
||||||
func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path,
|
func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path,
|
||||||
deps ...Path) InstallPath {
|
deps ...Path) InstallPath {
|
||||||
return m.installFile(installPath, name, srcPath, deps, false)
|
return m.installFile(installPath, name, srcPath, deps, false, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *moduleContext) InstallExecutable(installPath InstallPath, name string, srcPath Path,
|
func (m *moduleContext) InstallExecutable(installPath InstallPath, name string, srcPath Path,
|
||||||
deps ...Path) InstallPath {
|
deps ...Path) InstallPath {
|
||||||
return m.installFile(installPath, name, srcPath, deps, true)
|
return m.installFile(installPath, name, srcPath, deps, true, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *moduleContext) InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path,
|
||||||
|
extraZip Path, deps ...Path) InstallPath {
|
||||||
|
return m.installFile(installPath, name, srcPath, deps, false, &extraFilesZip{
|
||||||
|
zip: extraZip,
|
||||||
|
dir: installPath,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *moduleContext) PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec {
|
func (m *moduleContext) PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec {
|
||||||
@@ -2878,7 +2902,8 @@ func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, e
|
|||||||
return spec
|
return spec
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path, deps []Path, executable bool) InstallPath {
|
func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path, deps []Path,
|
||||||
|
executable bool, extraZip *extraFilesZip) InstallPath {
|
||||||
|
|
||||||
fullInstallPath := installPath.Join(m, name)
|
fullInstallPath := installPath.Join(m, name)
|
||||||
m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, false)
|
m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, false)
|
||||||
@@ -2906,6 +2931,7 @@ func (m *moduleContext) installFile(installPath InstallPath, name string, srcPat
|
|||||||
implicitDeps: implicitDeps,
|
implicitDeps: implicitDeps,
|
||||||
orderOnlyDeps: orderOnlyDeps,
|
orderOnlyDeps: orderOnlyDeps,
|
||||||
executable: executable,
|
executable: executable,
|
||||||
|
extraFiles: extraZip,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
rule := Cp
|
rule := Cp
|
||||||
@@ -2913,6 +2939,13 @@ func (m *moduleContext) installFile(installPath InstallPath, name string, srcPat
|
|||||||
rule = CpExecutable
|
rule = CpExecutable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extraCmds := ""
|
||||||
|
if extraZip != nil {
|
||||||
|
extraCmds += fmt.Sprintf(" && unzip -qDD -d '%s' '%s'",
|
||||||
|
extraZip.dir.String(), extraZip.zip.String())
|
||||||
|
implicitDeps = append(implicitDeps, extraZip.zip)
|
||||||
|
}
|
||||||
|
|
||||||
m.Build(pctx, BuildParams{
|
m.Build(pctx, BuildParams{
|
||||||
Rule: rule,
|
Rule: rule,
|
||||||
Description: "install " + fullInstallPath.Base(),
|
Description: "install " + fullInstallPath.Base(),
|
||||||
@@ -2921,6 +2954,9 @@ func (m *moduleContext) installFile(installPath InstallPath, name string, srcPat
|
|||||||
Implicits: implicitDeps,
|
Implicits: implicitDeps,
|
||||||
OrderOnly: orderOnlyDeps,
|
OrderOnly: orderOnlyDeps,
|
||||||
Default: !m.Config().KatiEnabled(),
|
Default: !m.Config().KatiEnabled(),
|
||||||
|
Args: map[string]string{
|
||||||
|
"extraCmds": extraCmds,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -263,7 +263,7 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, apexName, mo
|
|||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Sprintf("Expected %s to be AndroidAppSet", fi.module))
|
panic(fmt.Sprintf("Expected %s to be AndroidAppSet", fi.module))
|
||||||
}
|
}
|
||||||
fmt.Fprintln(w, "LOCAL_APK_SET_INSTALL_FILE :=", as.InstallFile())
|
fmt.Fprintln(w, "LOCAL_APK_SET_INSTALL_FILE :=", as.PackedAdditionalOutputs().String())
|
||||||
fmt.Fprintln(w, "LOCAL_APKCERTS_FILE :=", as.APKCertsFile().String())
|
fmt.Fprintln(w, "LOCAL_APKCERTS_FILE :=", as.APKCertsFile().String())
|
||||||
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_android_app_set.mk")
|
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_android_app_set.mk")
|
||||||
case nativeSharedLib, nativeExecutable, nativeTest:
|
case nativeSharedLib, nativeExecutable, nativeTest:
|
||||||
|
@@ -442,7 +442,8 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
} else {
|
} else {
|
||||||
if fi.class == appSet {
|
if fi.class == appSet {
|
||||||
copyCommands = append(copyCommands,
|
copyCommands = append(copyCommands,
|
||||||
fmt.Sprintf("unzip -qDD -d %s %s", destPathDir, fi.builtFile.String()))
|
fmt.Sprintf("unzip -qDD -d %s %s", destPathDir,
|
||||||
|
fi.module.(*java.AndroidAppSet).PackedAdditionalOutputs().String()))
|
||||||
} else {
|
} else {
|
||||||
copyCommands = append(copyCommands, "cp -f "+fi.builtFile.String()+" "+destPath)
|
copyCommands = append(copyCommands, "cp -f "+fi.builtFile.String()+" "+destPath)
|
||||||
}
|
}
|
||||||
|
@@ -356,7 +356,7 @@ type Zip2ZipWriter interface {
|
|||||||
|
|
||||||
// Writes out selected entries, renaming them as needed
|
// Writes out selected entries, renaming them as needed
|
||||||
func (apkSet *ApkSet) writeApks(selected SelectionResult, config TargetConfig,
|
func (apkSet *ApkSet) writeApks(selected SelectionResult, config TargetConfig,
|
||||||
writer Zip2ZipWriter, partition string) ([]string, error) {
|
outFile io.Writer, zipWriter Zip2ZipWriter, partition string) ([]string, error) {
|
||||||
// Renaming rules:
|
// Renaming rules:
|
||||||
// splits/MODULE-master.apk to STEM.apk
|
// splits/MODULE-master.apk to STEM.apk
|
||||||
// else
|
// else
|
||||||
@@ -406,9 +406,15 @@ func (apkSet *ApkSet) writeApks(selected SelectionResult, config TargetConfig,
|
|||||||
origin, inName, outName)
|
origin, inName, outName)
|
||||||
}
|
}
|
||||||
entryOrigin[outName] = inName
|
entryOrigin[outName] = inName
|
||||||
if err := writer.CopyFrom(apkFile, outName); err != nil {
|
if outName == config.stem+".apk" {
|
||||||
|
if err := writeZipEntryToFile(outFile, apkFile); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if err := zipWriter.CopyFrom(apkFile, outName); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
if partition != "" {
|
if partition != "" {
|
||||||
apkcerts = append(apkcerts, fmt.Sprintf(
|
apkcerts = append(apkcerts, fmt.Sprintf(
|
||||||
`name="%s" certificate="PRESIGNED" private_key="" partition="%s"`, outName, partition))
|
`name="%s" certificate="PRESIGNED" private_key="" partition="%s"`, outName, partition))
|
||||||
@@ -426,14 +432,13 @@ func (apkSet *ApkSet) extractAndCopySingle(selected SelectionResult, outFile *os
|
|||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Couldn't find apk path %s", selected.entries[0])
|
return fmt.Errorf("Couldn't find apk path %s", selected.entries[0])
|
||||||
}
|
}
|
||||||
inputReader, _ := apk.Open()
|
return writeZipEntryToFile(outFile, apk)
|
||||||
_, err := io.Copy(outFile, inputReader)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arguments parsing
|
// Arguments parsing
|
||||||
var (
|
var (
|
||||||
outputFile = flag.String("o", "", "output file containing extracted entries")
|
outputFile = flag.String("o", "", "output file for primary entry")
|
||||||
|
zipFile = flag.String("zip", "", "output file containing additional extracted entries")
|
||||||
targetConfig = TargetConfig{
|
targetConfig = TargetConfig{
|
||||||
screenDpi: map[android_bundle_proto.ScreenDensity_DensityAlias]bool{},
|
screenDpi: map[android_bundle_proto.ScreenDensity_DensityAlias]bool{},
|
||||||
abis: map[android_bundle_proto.Abi_AbiAlias]int{},
|
abis: map[android_bundle_proto.Abi_AbiAlias]int{},
|
||||||
@@ -494,7 +499,8 @@ func (s screenDensityFlagValue) Set(densityList string) error {
|
|||||||
|
|
||||||
func processArgs() {
|
func processArgs() {
|
||||||
flag.Usage = func() {
|
flag.Usage = func() {
|
||||||
fmt.Fprintln(os.Stderr, `usage: extract_apks -o <output-file> -sdk-version value -abis value `+
|
fmt.Fprintln(os.Stderr, `usage: extract_apks -o <output-file> [-zip <output-zip-file>] `+
|
||||||
|
`-sdk-version value -abis value `+
|
||||||
`-screen-densities value {-stem value | -extract-single} [-allow-prereleased] `+
|
`-screen-densities value {-stem value | -extract-single} [-allow-prereleased] `+
|
||||||
`[-apkcerts <apkcerts output file> -partition <partition>] <APK set>`)
|
`[-apkcerts <apkcerts output file> -partition <partition>] <APK set>`)
|
||||||
flag.PrintDefaults()
|
flag.PrintDefaults()
|
||||||
@@ -510,7 +516,8 @@ func processArgs() {
|
|||||||
flag.StringVar(&targetConfig.stem, "stem", "", "output entries base name in the output zip file")
|
flag.StringVar(&targetConfig.stem, "stem", "", "output entries base name in the output zip file")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
if (*outputFile == "") || len(flag.Args()) != 1 || *version == 0 ||
|
if (*outputFile == "") || len(flag.Args()) != 1 || *version == 0 ||
|
||||||
(targetConfig.stem == "" && !*extractSingle) || (*apkcertsOutput != "" && *partition == "") {
|
((targetConfig.stem == "" || *zipFile == "") && !*extractSingle) ||
|
||||||
|
(*apkcertsOutput != "" && *partition == "") {
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
}
|
}
|
||||||
targetConfig.sdkVersion = int32(*version)
|
targetConfig.sdkVersion = int32(*version)
|
||||||
@@ -542,13 +549,20 @@ func main() {
|
|||||||
if *extractSingle {
|
if *extractSingle {
|
||||||
err = apkSet.extractAndCopySingle(sel, outFile)
|
err = apkSet.extractAndCopySingle(sel, outFile)
|
||||||
} else {
|
} else {
|
||||||
writer := zip.NewWriter(outFile)
|
zipOutputFile, err := os.Create(*zipFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer zipOutputFile.Close()
|
||||||
|
|
||||||
|
zipWriter := zip.NewWriter(zipOutputFile)
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := writer.Close(); err != nil {
|
if err := zipWriter.Close(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
apkcerts, err := apkSet.writeApks(sel, targetConfig, writer, *partition)
|
|
||||||
|
apkcerts, err := apkSet.writeApks(sel, targetConfig, outFile, zipWriter, *partition)
|
||||||
if err == nil && *apkcertsOutput != "" {
|
if err == nil && *apkcertsOutput != "" {
|
||||||
apkcertsFile, err := os.Create(*apkcertsOutput)
|
apkcertsFile, err := os.Create(*apkcertsOutput)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -567,3 +581,13 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeZipEntryToFile(outFile io.Writer, zipEntry *zip.File) error {
|
||||||
|
reader, err := zipEntry.Open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer reader.Close()
|
||||||
|
_, err = io.Copy(outFile, reader)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -437,7 +438,7 @@ type testCaseWriteApks struct {
|
|||||||
stem string
|
stem string
|
||||||
partition string
|
partition string
|
||||||
// what we write from what
|
// what we write from what
|
||||||
expectedZipEntries map[string]string
|
zipEntries map[string]string
|
||||||
expectedApkcerts []string
|
expectedApkcerts []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,7 +449,7 @@ func TestWriteApks(t *testing.T) {
|
|||||||
moduleName: "mybase",
|
moduleName: "mybase",
|
||||||
stem: "Foo",
|
stem: "Foo",
|
||||||
partition: "system",
|
partition: "system",
|
||||||
expectedZipEntries: map[string]string{
|
zipEntries: map[string]string{
|
||||||
"Foo.apk": "splits/mybase-master.apk",
|
"Foo.apk": "splits/mybase-master.apk",
|
||||||
"Foo-xhdpi.apk": "splits/mybase-xhdpi.apk",
|
"Foo-xhdpi.apk": "splits/mybase-xhdpi.apk",
|
||||||
},
|
},
|
||||||
@@ -462,7 +463,7 @@ func TestWriteApks(t *testing.T) {
|
|||||||
moduleName: "base",
|
moduleName: "base",
|
||||||
stem: "Bar",
|
stem: "Bar",
|
||||||
partition: "product",
|
partition: "product",
|
||||||
expectedZipEntries: map[string]string{
|
zipEntries: map[string]string{
|
||||||
"Bar.apk": "universal.apk",
|
"Bar.apk": "universal.apk",
|
||||||
},
|
},
|
||||||
expectedApkcerts: []string{
|
expectedApkcerts: []string{
|
||||||
@@ -471,23 +472,46 @@ func TestWriteApks(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
testZipBuf := &bytes.Buffer{}
|
||||||
|
testZip := zip.NewWriter(testZipBuf)
|
||||||
|
for _, in := range testCase.zipEntries {
|
||||||
|
f, _ := testZip.Create(in)
|
||||||
|
f.Write([]byte(in))
|
||||||
|
}
|
||||||
|
testZip.Close()
|
||||||
|
|
||||||
|
zipReader, _ := zip.NewReader(bytes.NewReader(testZipBuf.Bytes()), int64(testZipBuf.Len()))
|
||||||
|
|
||||||
apkSet := ApkSet{entries: make(map[string]*zip.File)}
|
apkSet := ApkSet{entries: make(map[string]*zip.File)}
|
||||||
sel := SelectionResult{moduleName: testCase.moduleName}
|
sel := SelectionResult{moduleName: testCase.moduleName}
|
||||||
for _, in := range testCase.expectedZipEntries {
|
for _, f := range zipReader.File {
|
||||||
apkSet.entries[in] = &zip.File{FileHeader: zip.FileHeader{Name: in}}
|
apkSet.entries[f.Name] = f
|
||||||
sel.entries = append(sel.entries, in)
|
sel.entries = append(sel.entries, f.Name)
|
||||||
}
|
}
|
||||||
writer := testZip2ZipWriter{make(map[string]string)}
|
|
||||||
|
zipWriter := testZip2ZipWriter{make(map[string]string)}
|
||||||
|
outWriter := &bytes.Buffer{}
|
||||||
config := TargetConfig{stem: testCase.stem}
|
config := TargetConfig{stem: testCase.stem}
|
||||||
apkcerts, err := apkSet.writeApks(sel, config, writer, testCase.partition)
|
apkcerts, err := apkSet.writeApks(sel, config, outWriter, zipWriter, testCase.partition)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(testCase.expectedZipEntries, writer.entries) {
|
expectedZipEntries := make(map[string]string)
|
||||||
t.Errorf("expected zip entries %v, got %v", testCase.expectedZipEntries, writer.entries)
|
for k, v := range testCase.zipEntries {
|
||||||
|
if k != testCase.stem+".apk" {
|
||||||
|
expectedZipEntries[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(expectedZipEntries, zipWriter.entries) {
|
||||||
|
t.Errorf("expected zip entries %v, got %v", testCase.zipEntries, zipWriter.entries)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(testCase.expectedApkcerts, apkcerts) {
|
if !reflect.DeepEqual(testCase.expectedApkcerts, apkcerts) {
|
||||||
t.Errorf("expected apkcerts %v, got %v", testCase.expectedApkcerts, apkcerts)
|
t.Errorf("expected apkcerts %v, got %v", testCase.expectedApkcerts, apkcerts)
|
||||||
}
|
}
|
||||||
|
if g, w := outWriter.String(), testCase.zipEntries[testCase.stem+".apk"]; !reflect.DeepEqual(g, w) {
|
||||||
|
t.Errorf("expected output file contents %q, got %q", testCase.stem+".apk", outWriter.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -696,12 +696,12 @@ func (apkSet *AndroidAppSet) AndroidMkEntries() []android.AndroidMkEntries {
|
|||||||
return []android.AndroidMkEntries{
|
return []android.AndroidMkEntries{
|
||||||
android.AndroidMkEntries{
|
android.AndroidMkEntries{
|
||||||
Class: "APPS",
|
Class: "APPS",
|
||||||
OutputFile: android.OptionalPathForPath(apkSet.packedOutput),
|
OutputFile: android.OptionalPathForPath(apkSet.primaryOutput),
|
||||||
Include: "$(BUILD_SYSTEM)/soong_android_app_set.mk",
|
Include: "$(BUILD_SYSTEM)/soong_android_app_set.mk",
|
||||||
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
|
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
|
||||||
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
||||||
entries.SetBoolIfTrue("LOCAL_PRIVILEGED_MODULE", apkSet.Privileged())
|
entries.SetBoolIfTrue("LOCAL_PRIVILEGED_MODULE", apkSet.Privileged())
|
||||||
entries.SetString("LOCAL_APK_SET_INSTALL_FILE", apkSet.InstallFile())
|
entries.SetPath("LOCAL_APK_SET_INSTALL_FILE", apkSet.PackedAdditionalOutputs())
|
||||||
entries.SetPath("LOCAL_APKCERTS_FILE", apkSet.apkcertsFile)
|
entries.SetPath("LOCAL_APKCERTS_FILE", apkSet.apkcertsFile)
|
||||||
entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", apkSet.properties.Overrides...)
|
entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", apkSet.properties.Overrides...)
|
||||||
},
|
},
|
||||||
|
@@ -57,7 +57,7 @@ type AndroidAppSet struct {
|
|||||||
|
|
||||||
properties AndroidAppSetProperties
|
properties AndroidAppSetProperties
|
||||||
packedOutput android.WritablePath
|
packedOutput android.WritablePath
|
||||||
installFile string
|
primaryOutput android.WritablePath
|
||||||
apkcertsFile android.ModuleOutPath
|
apkcertsFile android.ModuleOutPath
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,11 +78,11 @@ func (as *AndroidAppSet) Privileged() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (as *AndroidAppSet) OutputFile() android.Path {
|
func (as *AndroidAppSet) OutputFile() android.Path {
|
||||||
return as.packedOutput
|
return as.primaryOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
func (as *AndroidAppSet) InstallFile() string {
|
func (as *AndroidAppSet) PackedAdditionalOutputs() android.Path {
|
||||||
return as.installFile
|
return as.packedOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
func (as *AndroidAppSet) APKCertsFile() android.Path {
|
func (as *AndroidAppSet) APKCertsFile() android.Path {
|
||||||
@@ -114,11 +114,11 @@ func SupportedAbis(ctx android.ModuleContext) []string {
|
|||||||
|
|
||||||
func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
as.packedOutput = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
|
as.packedOutput = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
|
||||||
|
as.primaryOutput = android.PathForModuleOut(ctx, as.BaseModuleName()+".apk")
|
||||||
as.apkcertsFile = android.PathForModuleOut(ctx, "apkcerts.txt")
|
as.apkcertsFile = android.PathForModuleOut(ctx, "apkcerts.txt")
|
||||||
// We are assuming here that the install file in the APK
|
// We are assuming here that the install file in the APK
|
||||||
// set has `.apk` suffix. If it doesn't the build will fail.
|
// set has `.apk` suffix. If it doesn't the build will fail.
|
||||||
// APK sets containing APEX files are handled elsewhere.
|
// APK sets containing APEX files are handled elsewhere.
|
||||||
as.installFile = as.BaseModuleName() + ".apk"
|
|
||||||
screenDensities := "all"
|
screenDensities := "all"
|
||||||
if dpis := ctx.Config().ProductAAPTPrebuiltDPI(); len(dpis) > 0 {
|
if dpis := ctx.Config().ProductAAPTPrebuiltDPI(); len(dpis) > 0 {
|
||||||
screenDensities = strings.ToUpper(strings.Join(dpis, ","))
|
screenDensities = strings.ToUpper(strings.Join(dpis, ","))
|
||||||
@@ -129,8 +129,8 @@ func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext)
|
|||||||
android.BuildParams{
|
android.BuildParams{
|
||||||
Rule: extractMatchingApks,
|
Rule: extractMatchingApks,
|
||||||
Description: "Extract APKs from APK set",
|
Description: "Extract APKs from APK set",
|
||||||
Output: as.packedOutput,
|
Output: as.primaryOutput,
|
||||||
ImplicitOutput: as.apkcertsFile,
|
ImplicitOutputs: android.WritablePaths{as.packedOutput, as.apkcertsFile},
|
||||||
Inputs: android.Paths{as.prebuilt.SingleSourcePath(ctx)},
|
Inputs: android.Paths{as.prebuilt.SingleSourcePath(ctx)},
|
||||||
Args: map[string]string{
|
Args: map[string]string{
|
||||||
"abis": strings.Join(SupportedAbis(ctx), ","),
|
"abis": strings.Join(SupportedAbis(ctx), ","),
|
||||||
@@ -140,10 +140,21 @@ func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext)
|
|||||||
"stem": as.BaseModuleName(),
|
"stem": as.BaseModuleName(),
|
||||||
"apkcerts": as.apkcertsFile.String(),
|
"apkcerts": as.apkcertsFile.String(),
|
||||||
"partition": as.PartitionTag(ctx.DeviceConfig()),
|
"partition": as.PartitionTag(ctx.DeviceConfig()),
|
||||||
|
"zip": as.packedOutput.String(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
var installDir android.InstallPath
|
||||||
|
if as.Privileged() {
|
||||||
|
installDir = android.PathForModuleInstall(ctx, "priv-app", as.BaseModuleName())
|
||||||
|
} else {
|
||||||
|
installDir = android.PathForModuleInstall(ctx, "app", as.BaseModuleName())
|
||||||
|
}
|
||||||
|
ctx.InstallFileWithExtraFilesZip(installDir, as.BaseModuleName()+".apk", as.primaryOutput, as.packedOutput)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (as *AndroidAppSet) InstallBypassMake() bool { return true }
|
||||||
|
|
||||||
// android_app_set extracts a set of APKs based on the target device
|
// android_app_set extracts a set of APKs based on the target device
|
||||||
// configuration and installs this set as "split APKs".
|
// configuration and installs this set as "split APKs".
|
||||||
// The extracted set always contains an APK whose name is
|
// The extracted set always contains an APK whose name is
|
||||||
|
@@ -17,19 +17,20 @@ package java
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAndroidAppSet(t *testing.T) {
|
func TestAndroidAppSet(t *testing.T) {
|
||||||
ctx, _ := testJava(t, `
|
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
|
||||||
android_app_set {
|
android_app_set {
|
||||||
name: "foo",
|
name: "foo",
|
||||||
set: "prebuilts/apks/app.apks",
|
set: "prebuilts/apks/app.apks",
|
||||||
prerelease: true,
|
prerelease: true,
|
||||||
}`)
|
}`)
|
||||||
module := ctx.ModuleForTests("foo", "android_common")
|
module := result.ModuleForTests("foo", "android_common")
|
||||||
const packedSplitApks = "foo.zip"
|
const packedSplitApks = "foo.zip"
|
||||||
params := module.Output(packedSplitApks)
|
params := module.Output(packedSplitApks)
|
||||||
if params.Rule == nil {
|
if params.Rule == nil {
|
||||||
@@ -41,9 +42,22 @@ func TestAndroidAppSet(t *testing.T) {
|
|||||||
if s := params.Args["partition"]; s != "system" {
|
if s := params.Args["partition"]; s != "system" {
|
||||||
t.Errorf("wrong partition value: '%s', expected 'system'", s)
|
t.Errorf("wrong partition value: '%s', expected 'system'", s)
|
||||||
}
|
}
|
||||||
mkEntries := android.AndroidMkEntriesForTest(t, ctx, module.Module())[0]
|
|
||||||
|
android.AssertPathRelativeToTopEquals(t, "incorrect output path",
|
||||||
|
"out/soong/.intermediates/foo/android_common/foo.apk", params.Output)
|
||||||
|
|
||||||
|
android.AssertPathsRelativeToTopEquals(t, "incorrect implicit output paths",
|
||||||
|
[]string{
|
||||||
|
"out/soong/.intermediates/foo/android_common/foo.zip",
|
||||||
|
"out/soong/.intermediates/foo/android_common/apkcerts.txt",
|
||||||
|
},
|
||||||
|
params.ImplicitOutputs.Paths())
|
||||||
|
|
||||||
|
mkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, module.Module())[0]
|
||||||
actualInstallFile := mkEntries.EntryMap["LOCAL_APK_SET_INSTALL_FILE"]
|
actualInstallFile := mkEntries.EntryMap["LOCAL_APK_SET_INSTALL_FILE"]
|
||||||
expectedInstallFile := []string{"foo.apk"}
|
expectedInstallFile := []string{
|
||||||
|
strings.Replace(params.ImplicitOutputs[0].String(), android.OutSoongDir, result.Config.SoongOutDir(), 1),
|
||||||
|
}
|
||||||
if !reflect.DeepEqual(actualInstallFile, expectedInstallFile) {
|
if !reflect.DeepEqual(actualInstallFile, expectedInstallFile) {
|
||||||
t.Errorf("Unexpected LOCAL_APK_SET_INSTALL_FILE value: '%s', expected: '%s',",
|
t.Errorf("Unexpected LOCAL_APK_SET_INSTALL_FILE value: '%s', expected: '%s',",
|
||||||
actualInstallFile, expectedInstallFile)
|
actualInstallFile, expectedInstallFile)
|
||||||
|
@@ -120,14 +120,14 @@ var (
|
|||||||
"extractMatchingApks",
|
"extractMatchingApks",
|
||||||
blueprint.RuleParams{
|
blueprint.RuleParams{
|
||||||
Command: `rm -rf "$out" && ` +
|
Command: `rm -rf "$out" && ` +
|
||||||
`${config.ExtractApksCmd} -o "${out}" -allow-prereleased=${allow-prereleased} ` +
|
`${config.ExtractApksCmd} -o "${out}" -zip "${zip}" -allow-prereleased=${allow-prereleased} ` +
|
||||||
`-sdk-version=${sdk-version} -abis=${abis} ` +
|
`-sdk-version=${sdk-version} -abis=${abis} ` +
|
||||||
`--screen-densities=${screen-densities} --stem=${stem} ` +
|
`--screen-densities=${screen-densities} --stem=${stem} ` +
|
||||||
`-apkcerts=${apkcerts} -partition=${partition} ` +
|
`-apkcerts=${apkcerts} -partition=${partition} ` +
|
||||||
`${in}`,
|
`${in}`,
|
||||||
CommandDeps: []string{"${config.ExtractApksCmd}"},
|
CommandDeps: []string{"${config.ExtractApksCmd}"},
|
||||||
},
|
},
|
||||||
"abis", "allow-prereleased", "screen-densities", "sdk-version", "stem", "apkcerts", "partition")
|
"abis", "allow-prereleased", "screen-densities", "sdk-version", "stem", "apkcerts", "partition", "zip")
|
||||||
|
|
||||||
turbine, turbineRE = pctx.RemoteStaticRules("turbine",
|
turbine, turbineRE = pctx.RemoteStaticRules("turbine",
|
||||||
blueprint.RuleParams{
|
blueprint.RuleParams{
|
||||||
|
Reference in New Issue
Block a user