Merge "sbox error message now lists the files that were created"
diff --git a/android/testing.go b/android/testing.go
index 03572b3..fc58cec 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -131,7 +131,7 @@
outputs = append(outputs, p.Output)
}
for _, f := range outputs {
- if f.Rel() == file {
+ if f.String() == file || f.Rel() == file {
return p
}
}
diff --git a/java/aapt2.go b/java/aapt2.go
index cebd6d1..84e3729 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -16,6 +16,7 @@
import (
"path/filepath"
+ "sort"
"strconv"
"strings"
@@ -85,6 +86,9 @@
})
}
+ sort.Slice(ret, func(i, j int) bool {
+ return ret[i].String() < ret[j].String()
+ })
return ret
}
diff --git a/java/androidmk.go b/java/androidmk.go
index 86e000d..2e67639 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -143,6 +143,13 @@
// framework_res.
fmt.Fprintln(w, "LOCAL_NO_STANDARD_LIBRARIES := true")
}
+
+ if len(app.rroDirs) > 0 {
+ fmt.Fprintln(w, "LOCAL_SOONG_RRO_DIRS :=", strings.Join(app.rroDirs.Strings(), " "))
+ }
+ fmt.Fprintln(w, "LOCAL_EXPORT_PACKAGE_RESOURCES :=",
+ Bool(app.appProperties.Export_package_resources))
+ fmt.Fprintln(w, "LOCAL_FULL_MANIFEST_FILE :=", app.manifestPath.String())
}
},
},
diff --git a/java/app.go b/java/app.go
index b66eb4b..6866e2a 100644
--- a/java/app.go
+++ b/java/app.go
@@ -70,6 +70,8 @@
aaptSrcJar android.Path
exportPackage android.Path
+ rroDirs android.Paths
+ manifestPath android.Path
}
func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -86,7 +88,7 @@
}
func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- linkFlags, linkDeps, resDirs, overlayDirs := a.aapt2Flags(ctx)
+ linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, manifestPath := a.aapt2Flags(ctx)
packageRes := android.PathForModuleOut(ctx, "package-res.apk")
srcJar := android.PathForModuleGen(ctx, "R.jar")
@@ -144,6 +146,8 @@
CreateAppPackage(ctx, packageFile, a.exportPackage, a.outputFile, certificates)
a.outputFile = packageFile
+ a.rroDirs = rroDirs
+ a.manifestPath = manifestPath
if ctx.ModuleName() == "framework-res" {
// framework-res.apk is installed as system/framework/framework-res.apk
@@ -171,7 +175,7 @@
}
func (a *AndroidApp) aapt2Flags(ctx android.ModuleContext) (flags []string, deps android.Paths,
- resDirs, overlayDirs []globbedResourceDir) {
+ resDirs, overlayDirs []globbedResourceDir, rroDirs android.Paths, manifestPath android.Path) {
hasVersionCode := false
hasVersionName := false
@@ -205,7 +209,9 @@
dir: dir,
files: resourceGlob(ctx, dir),
})
- overlayDirs = append(overlayDirs, overlayResourceGlob(ctx, dir)...)
+ resOverlayDirs, resRRODirs := overlayResourceGlob(ctx, dir)
+ overlayDirs = append(overlayDirs, resOverlayDirs...)
+ rroDirs = append(rroDirs, resRRODirs...)
}
var assetFiles android.Paths
@@ -221,7 +227,7 @@
manifestFile = *a.properties.Manifest
}
- manifestPath := android.PathForModuleSrc(ctx, manifestFile)
+ manifestPath = android.PathForModuleSrc(ctx, manifestFile)
linkFlags = append(linkFlags, "--manifest "+manifestPath.String())
linkDeps = append(linkDeps, manifestPath)
@@ -288,7 +294,7 @@
// TODO: LOCAL_PACKAGE_OVERRIDES
// $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
- return linkFlags, linkDeps, resDirs, overlayDirs
+ return linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, manifestPath
}
func AndroidAppFactory() android.Module {
@@ -320,26 +326,49 @@
type overlayGlobResult struct {
dir string
paths android.DirectorySortedPaths
+
+ // Set to true of the product has selected that values in this overlay should not be moved to
+ // Runtime Resource Overlay (RRO) packages.
+ excludeFromRRO bool
}
const overlayDataKey = "overlayDataKey"
-func overlayResourceGlob(ctx android.ModuleContext, dir android.Path) []globbedResourceDir {
+func overlayResourceGlob(ctx android.ModuleContext, dir android.Path) (res []globbedResourceDir,
+ rroDirs android.Paths) {
+
overlayData := ctx.Config().Get(overlayDataKey).([]overlayGlobResult)
- var ret []globbedResourceDir
+ // Runtime resource overlays (RRO) may be turned on by the product config for some modules
+ rroEnabled := false
+ enforceRROTargets := ctx.Config().ProductVariables.EnforceRROTargets
+ if enforceRROTargets != nil {
+ if len(*enforceRROTargets) == 1 && (*enforceRROTargets)[0] == "*" {
+ rroEnabled = true
+ } else if inList(ctx.ModuleName(), *enforceRROTargets) {
+ rroEnabled = true
+ }
+ }
for _, data := range overlayData {
files := data.paths.PathsInDirectory(filepath.Join(data.dir, dir.String()))
if len(files) > 0 {
- ret = append(ret, globbedResourceDir{
- dir: android.PathForSource(ctx, data.dir, dir.String()),
- files: files,
- })
+ overlayModuleDir := android.PathForSource(ctx, data.dir, dir.String())
+ // If enforce RRO is enabled for this module and this overlay is not in the
+ // exclusion list, ignore the overlay. The list of ignored overlays will be
+ // passed to Make to be turned into an RRO package.
+ if rroEnabled && !data.excludeFromRRO {
+ rroDirs = append(rroDirs, overlayModuleDir)
+ } else {
+ res = append(res, globbedResourceDir{
+ dir: overlayModuleDir,
+ files: files,
+ })
+ }
}
}
- return ret
+ return res, rroDirs
}
func OverlaySingletonFactory() android.Singleton {
@@ -349,10 +378,25 @@
type overlaySingleton struct{}
func (overlaySingleton) GenerateBuildActions(ctx android.SingletonContext) {
+
+ // Specific overlays may be excluded from Runtime Resource Overlays by the product config
+ var rroExcludedOverlays []string
+ if ctx.Config().ProductVariables.EnforceRROExcludedOverlays != nil {
+ rroExcludedOverlays = *ctx.Config().ProductVariables.EnforceRROExcludedOverlays
+ }
+
var overlayData []overlayGlobResult
for _, overlay := range ctx.Config().ResourceOverlays() {
var result overlayGlobResult
result.dir = overlay
+
+ // Mark overlays that will not have Runtime Resource Overlays enforced on them
+ for _, exclude := range rroExcludedOverlays {
+ if strings.HasPrefix(overlay, exclude) {
+ result.excludeFromRRO = true
+ }
+ }
+
files, err := ctx.GlobWithDeps(filepath.Join(overlay, "**/*"), aaptIgnoreFilenames)
if err != nil {
ctx.Errorf("failed to glob resource dir %q: %s", overlay, err.Error())
diff --git a/java/app_test.go b/java/app_test.go
index 37489f5..73ac3f7 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -17,6 +17,7 @@
import (
"android/soong/android"
"reflect"
+ "sort"
"testing"
)
@@ -79,7 +80,11 @@
t.Errorf("expected aapt2 compile inputs expected:\n %#v\n got:\n %#v",
resourceFiles, compile.Inputs.Strings())
}
- expectedLinkImplicits = append(expectedLinkImplicits, compile.Outputs.Strings()...)
+
+ compiledResourceOutputs := compile.Outputs.Strings()
+ sort.Strings(compiledResourceOutputs)
+
+ expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...)
list := foo.Output("aapt2/res.list")
expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
@@ -91,3 +96,144 @@
expectedLinkImplicits, res.Implicits.Strings())
}
}
+
+var testEnforceRROTests = []struct {
+ name string
+ enforceRROTargets []string
+ enforceRROExcludedOverlays []string
+ fooOverlayFiles []string
+ fooRRODirs []string
+ barOverlayFiles []string
+ barRRODirs []string
+}{
+ {
+ name: "no RRO",
+ enforceRROTargets: nil,
+ enforceRROExcludedOverlays: nil,
+ fooOverlayFiles: []string{
+ "device/vendor/blah/overlay/foo/res/values/strings.xml",
+ "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
+ },
+ fooRRODirs: nil,
+ barOverlayFiles: []string{
+ "device/vendor/blah/overlay/bar/res/values/strings.xml",
+ "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
+ },
+ barRRODirs: nil,
+ },
+ {
+ name: "enforce RRO on foo",
+ enforceRROTargets: []string{"foo"},
+ enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
+ fooOverlayFiles: []string{
+ "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
+ },
+ fooRRODirs: []string{
+ "device/vendor/blah/overlay/foo/res",
+ },
+ barOverlayFiles: []string{
+ "device/vendor/blah/overlay/bar/res/values/strings.xml",
+ "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
+ },
+ barRRODirs: nil,
+ },
+ {
+ name: "enforce RRO on all",
+ enforceRROTargets: []string{"*"},
+ enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
+ fooOverlayFiles: []string{
+ "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
+ },
+ fooRRODirs: []string{
+ "device/vendor/blah/overlay/foo/res",
+ },
+ barOverlayFiles: []string{
+ "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
+ },
+ barRRODirs: []string{
+ "device/vendor/blah/overlay/bar/res",
+ },
+ },
+}
+
+func TestEnforceRRO(t *testing.T) {
+ resourceOverlays := []string{
+ "device/vendor/blah/overlay",
+ "device/vendor/blah/overlay2",
+ "device/vendor/blah/static_overlay",
+ }
+
+ fs := map[string][]byte{
+ "foo/res/res/values/strings.xml": nil,
+ "bar/res/res/values/strings.xml": nil,
+ "device/vendor/blah/overlay/foo/res/values/strings.xml": nil,
+ "device/vendor/blah/overlay/bar/res/values/strings.xml": nil,
+ "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
+ "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
+ "device/vendor/blah/overlay2/res/values/strings.xml": nil,
+ }
+
+ bp := `
+ android_app {
+ name: "foo",
+ resource_dirs: ["foo/res"],
+ }
+
+ android_app {
+ name: "bar",
+ resource_dirs: ["bar/res"],
+ }
+ `
+
+ for _, testCase := range testEnforceRROTests {
+ t.Run(testCase.name, func(t *testing.T) {
+ config := testConfig(nil)
+ config.ProductVariables.ResourceOverlays = &resourceOverlays
+ if testCase.enforceRROTargets != nil {
+ config.ProductVariables.EnforceRROTargets = &testCase.enforceRROTargets
+ }
+ if testCase.enforceRROExcludedOverlays != nil {
+ config.ProductVariables.EnforceRROExcludedOverlays = &testCase.enforceRROExcludedOverlays
+ }
+
+ ctx := testAppContext(config, bp, fs)
+ run(t, ctx, config)
+
+ getOverlays := func(moduleName string) ([]string, []string) {
+ module := ctx.ModuleForTests(moduleName, "android_common")
+ overlayCompiledPaths := module.Output("aapt2/overlay.list").Inputs.Strings()
+
+ var overlayFiles []string
+ for _, o := range overlayCompiledPaths {
+ overlayFiles = append(overlayFiles, module.Output(o).Inputs.Strings()...)
+ }
+
+ rroDirs := module.Module().(*AndroidApp).rroDirs.Strings()
+
+ return overlayFiles, rroDirs
+ }
+
+ fooOverlayFiles, fooRRODirs := getOverlays("foo")
+ barOverlayFiles, barRRODirs := getOverlays("bar")
+
+ if !reflect.DeepEqual(fooOverlayFiles, testCase.fooOverlayFiles) {
+ t.Errorf("expected foo overlay files:\n %#v\n got:\n %#v",
+ testCase.fooOverlayFiles, fooOverlayFiles)
+ }
+ if !reflect.DeepEqual(fooRRODirs, testCase.fooRRODirs) {
+ t.Errorf("expected foo rroDirs: %#v\n got:\n %#v",
+ testCase.fooRRODirs, fooRRODirs)
+ }
+
+ if !reflect.DeepEqual(barOverlayFiles, testCase.barOverlayFiles) {
+ t.Errorf("expected bar overlay files:\n %#v\n got:\n %#v",
+ testCase.barOverlayFiles, barOverlayFiles)
+ }
+ if !reflect.DeepEqual(barRRODirs, testCase.barRRODirs) {
+ t.Errorf("expected bar rroDirs: %#v\n got:\n %#v",
+ testCase.barRRODirs, barRRODirs)
+ }
+
+ })
+ }
+}
diff --git a/python/androidmk.go b/python/androidmk.go
index 4c94450..5fa01ab 100644
--- a/python/androidmk.go
+++ b/python/androidmk.go
@@ -39,7 +39,7 @@
}
func (p *Module) AndroidMk() android.AndroidMkData {
- ret := android.AndroidMkData{}
+ ret := android.AndroidMkData{OutputFile: p.installSource}
p.subAndroidMk(&ret, p.installer)
@@ -55,7 +55,7 @@
strings.Join(p.binaryProperties.Test_suites, " "))
}
})
- base.subAndroidMk(ret, p.baseInstaller)
+ base.subAndroidMk(ret, p.pythonInstaller)
}
func (p *testDecorator) AndroidMk(base *Module, ret *android.AndroidMkData) {
@@ -67,7 +67,7 @@
strings.Join(p.binaryDecorator.binaryProperties.Test_suites, " "))
}
})
- base.subAndroidMk(ret, p.binaryDecorator.baseInstaller)
+ base.subAndroidMk(ret, p.binaryDecorator.pythonInstaller)
}
func (installer *pythonInstaller) AndroidMk(base *Module, ret *android.AndroidMkData) {
diff --git a/python/binary.go b/python/binary.go
index 14c4952..457c7fa 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -49,24 +49,20 @@
type binaryDecorator struct {
binaryProperties BinaryProperties
- baseInstaller *pythonInstaller
+ *pythonInstaller
}
type IntermPathProvider interface {
IntermPathForModuleOut() android.OptionalPath
}
-func (binary *binaryDecorator) install(ctx android.ModuleContext, file android.Path) {
- binary.baseInstaller.install(ctx, file)
-}
-
var (
stubTemplateHost = "build/soong/python/scripts/stub_template_host.txt"
)
func NewBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) {
module := newModule(hod, android.MultilibFirst)
- decorator := &binaryDecorator{baseInstaller: NewPythonInstaller("bin")}
+ decorator := &binaryDecorator{pythonInstaller: NewPythonInstaller("bin", "")}
module.bootstrapper = decorator
module.installer = decorator
diff --git a/python/installer.go b/python/installer.go
index 04698c5..ab3d9b4 100644
--- a/python/installer.go
+++ b/python/installer.go
@@ -15,26 +15,47 @@
package python
import (
+ "path/filepath"
+
"android/soong/android"
)
// This file handles installing python executables into their final location
+type installLocation int
+
+const (
+ InstallInData installLocation = iota
+)
+
type pythonInstaller struct {
- dir string
+ dir string
+ dir64 string
+ relative string
path android.OutputPath
}
-func NewPythonInstaller(dir string) *pythonInstaller {
+func NewPythonInstaller(dir, dir64 string) *pythonInstaller {
return &pythonInstaller{
- dir: dir,
+ dir: dir,
+ dir64: dir64,
}
}
var _ installer = (*pythonInstaller)(nil)
+func (installer *pythonInstaller) installDir(ctx android.ModuleContext) android.OutputPath {
+ dir := installer.dir
+ if ctx.Arch().ArchType.Multilib == "lib64" && installer.dir64 != "" {
+ dir = installer.dir64
+ }
+ if !ctx.Host() && !ctx.Arch().Native {
+ dir = filepath.Join(dir, ctx.Arch().ArchType.String())
+ }
+ return android.PathForModuleInstall(ctx, dir, installer.relative)
+}
+
func (installer *pythonInstaller) install(ctx android.ModuleContext, file android.Path) {
- installer.path = ctx.InstallFile(android.PathForModuleInstall(ctx, installer.dir),
- file.Base(), file)
+ installer.path = ctx.InstallFile(installer.installDir(ctx), file.Base(), file)
}
diff --git a/python/library.go b/python/library.go
index 58ee55f..65c1352 100644
--- a/python/library.go
+++ b/python/library.go
@@ -22,6 +22,7 @@
func init() {
android.RegisterModuleType("python_library_host", PythonLibraryHostFactory)
+ android.RegisterModuleType("python_library", PythonLibraryFactory)
}
func PythonLibraryHostFactory() android.Module {
@@ -29,3 +30,9 @@
return module.Init()
}
+
+func PythonLibraryFactory() android.Module {
+ module := newModule(android.HostAndDeviceSupported, android.MultilibBoth)
+
+ return module.Init()
+}
diff --git a/python/python.go b/python/python.go
index 9d6d6a7..05efbea 100644
--- a/python/python.go
+++ b/python/python.go
@@ -558,5 +558,9 @@
return true
}
+func (p *Module) InstallInData() bool {
+ return true
+}
+
var Bool = proptools.Bool
var String = proptools.String
diff --git a/python/test.go b/python/test.go
index de2b13e..825e63c 100644
--- a/python/test.go
+++ b/python/test.go
@@ -22,6 +22,7 @@
func init() {
android.RegisterModuleType("python_test_host", PythonTestHostFactory)
+ android.RegisterModuleType("python_test", PythonTestFactory)
}
type testDecorator struct {
@@ -29,13 +30,18 @@
}
func (test *testDecorator) install(ctx android.ModuleContext, file android.Path) {
- test.binaryDecorator.baseInstaller.install(ctx, file)
+ test.binaryDecorator.pythonInstaller.dir = "nativetest"
+ test.binaryDecorator.pythonInstaller.dir64 = "nativetest64"
+
+ test.binaryDecorator.pythonInstaller.relative = ctx.ModuleName()
+
+ test.binaryDecorator.pythonInstaller.install(ctx, file)
}
func NewTest(hod android.HostOrDeviceSupported) *Module {
module, binary := NewBinary(hod)
- binary.baseInstaller = NewPythonInstaller("nativetest")
+ binary.pythonInstaller = NewPythonInstaller("nativetest", "nativetest64")
test := &testDecorator{binaryDecorator: binary}
@@ -50,3 +56,10 @@
return module.Init()
}
+
+func PythonTestFactory() android.Module {
+ module := NewTest(android.HostAndDeviceSupported)
+ module.multilib = android.MultilibBoth
+
+ return module.Init()
+}