Merge "Retry: Adds support for 'ignored-on-host'"
diff --git a/android/sdk.go b/android/sdk.go
index 36afc3d..e823106 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -351,6 +351,15 @@
// values that differ by arch, fields not tagged as such must have common values across
// all variants.
//
+ // * Additional field tags can be specified on a field that will ignore certain values
+ // for the purpose of common value optimization. A value that is ignored must have the
+ // default value for the property type. This is to ensure that significant value are not
+ // ignored by accident. The purpose of this is to allow the snapshot generation to reflect
+ // the behavior of the runtime. e.g. if a property is ignored on the host then a property
+ // that is common for android can be treated as if it was common for android and host as
+ // the setting for host is ignored anyway.
+ // * `sdk:"ignored-on-host" - this indicates the property is ignored on the host variant.
+ //
// * The sdk module type populates the BpModule structure, creating the arch specific
// structure and calls AddToPropertySet(...) on the properties struct to add the member
// specific properties in the correct place in the structure.
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index 898ecea..ae1a492 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -289,9 +289,12 @@
}
extractor := newCommonValueExtractor(common)
- extractor.extractCommonProperties(common, structs)
h := TestHelper{t}
+
+ err := extractor.extractCommonProperties(common, structs)
+ h.AssertDeepEquals("unexpected error", nil, err)
+
h.AssertDeepEquals("common properties not correct",
&testPropertiesStruct{
name: "common",
diff --git a/sdk/update.go b/sdk/update.go
index bcc2c77..991428e 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -1215,11 +1215,26 @@
// struct (or one of its embedded structs).
type fieldAccessorFunc func(structValue reflect.Value) reflect.Value
+// Checks the metadata to determine whether the property should be ignored for the
+// purposes of common value extraction or not.
+type extractorMetadataPredicate func(metadata propertiesContainer) bool
+
+// Indicates whether optimizable properties are provided by a host variant or
+// not.
+type isHostVariant interface {
+ isHostVariant() bool
+}
+
// A property that can be optimized by the commonValueExtractor.
type extractorProperty struct {
// The name of the field for this property.
name string
+ // Filter that can use metadata associated with the properties being optimized
+ // to determine whether the field should be ignored during common value
+ // optimization.
+ filter extractorMetadataPredicate
+
// Retrieves the value on which common value optimization will be performed.
getter fieldAccessorFunc
@@ -1273,6 +1288,20 @@
continue
}
+ var filter extractorMetadataPredicate
+
+ // Add a filter
+ if proptools.HasTag(field, "sdk", "ignored-on-host") {
+ filter = func(metadata propertiesContainer) bool {
+ if m, ok := metadata.(isHostVariant); ok {
+ if m.isHostVariant() {
+ return false
+ }
+ }
+ return true
+ }
+ }
+
// Save a copy of the field index for use in the function.
fieldIndex := f
@@ -1304,6 +1333,7 @@
} else {
property := extractorProperty{
name,
+ filter,
fieldGetter,
reflect.Zero(field.Type),
proptools.HasTag(field, "android", "arch_variant"),
@@ -1372,6 +1402,12 @@
for _, property := range e.properties {
fieldGetter := property.getter
+ filter := property.filter
+ if filter == nil {
+ filter = func(metadata propertiesContainer) bool {
+ return true
+ }
+ }
// Check to see if all the structures have the same value for the field. The commonValue
// is nil on entry to the loop and if it is nil on exit then there is no common value or
@@ -1389,6 +1425,15 @@
itemValue := reflect.ValueOf(container.optimizableProperties())
fieldValue := fieldGetter(itemValue)
+ if !filter(container) {
+ expectedValue := property.emptyValue.Interface()
+ actualValue := fieldValue.Interface()
+ if !reflect.DeepEqual(expectedValue, actualValue) {
+ return fmt.Errorf("field %q is supposed to be ignored for %q but is set to %#v instead of %#v", property, container, actualValue, expectedValue)
+ }
+ continue
+ }
+
if commonValue == nil {
// Use the first value as the commonProperties value.
commonValue = &fieldValue