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

Commit 4d125bd8 authored by Paul Duffin's avatar Paul Duffin
Browse files

Retry: Adds support for 'ignored-on-host'

Adds a filter mechanism that can exclude property values from being
included in the common value extraction. That is needed to prevent the
snapshot mechanism from generating invalid output for properties that
are ignored on host (and have their values cleared) and which are not
tagged with `android:"arch_variant"`.

Changes:
* Updates the documentation of SdkMemberType to explain what effect
  the 'ignored-on-host' tag has.
* Adds some tests for this new mechanism.

Bug: 155628860
Test: m nothing
Merged-In: Ibafdb6e921ba5abe505bd8a91ca5a1d9c9b5d0cb
Change-Id: Ibafdb6e921ba5abe505bd8a91ca5a1d9c9b5d0cb
(cherry picked from commit c459f89f)
parent 08385bf9
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -351,6 +351,15 @@ type SdkMemberType interface {
	//   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.
+4 −1
Original line number Diff line number Diff line
@@ -289,9 +289,12 @@ func TestCommonValueOptimization(t *testing.T) {
	}

	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",
+45 −0
Original line number Diff line number Diff line
@@ -1215,11 +1215,26 @@ func (s *sdk) getPossibleOsTypes() []android.OsType {
// 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 @@ func (e *commonValueExtractor) gatherFields(structType reflect.Type, containingS
			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 @@ func (e *commonValueExtractor) gatherFields(structType reflect.Type, containingS
		} else {
			property := extractorProperty{
				name,
				filter,
				fieldGetter,
				reflect.Zero(field.Type),
				proptools.HasTag(field, "android", "arch_variant"),
@@ -1372,6 +1402,12 @@ func (e *commonValueExtractor) extractCommonProperties(commonProperties interfac

	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 @@ func (e *commonValueExtractor) extractCommonProperties(commonProperties interfac
			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