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

Commit 9f96a176 authored by Joe Onorato's avatar Joe Onorato Committed by Gerrit Code Review
Browse files

Merge "Aconfig rules"

parents 29c8ad38 fee845a7
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -183,6 +183,16 @@ func (c Config) MaxPageSizeSupported() string {
	return String(c.config.productVariables.DeviceMaxPageSizeSupported)
}

// The release version passed to aconfig, derived from RELEASE_VERSION
func (c Config) ReleaseVersion() string {
	return c.config.productVariables.ReleaseVersion
}

// The flag values files passed to aconfig, derived from RELEASE_VERSION
func (c Config) ReleaseDeviceConfigValueSets() []string {
	return c.config.productVariables.ReleaseDeviceConfigValueSets
}

// A DeviceConfig object represents the configuration for a particular device
// being built. For now there will only be one of these, but in the future there
// may be multiple devices being built.
+3 −0
Original line number Diff line number Diff line
@@ -473,6 +473,9 @@ type productVariables struct {
	ProductManufacturer string   `json:",omitempty"`
	ProductBrand        string   `json:",omitempty"`
	BuildVersionTags    []string `json:",omitempty"`

	ReleaseVersion               string   `json:",omitempty"`
	ReleaseDeviceConfigValueSets []string `json:",omitempty"`
}

func boolPtr(v bool) *bool {
+30 −0
Original line number Diff line number Diff line
package {
    default_applicable_licenses: ["Android-Apache-2.0"],
}

bootstrap_go_package {
    name: "soong-device_config",
    pkgPath: "android/soong/device_config",
    deps: [
        "blueprint",
        "blueprint-pathtools",
        "sbox_proto",
        "soong",
        "soong-android",
        "soong-bazel",
        "soong-shared",
    ],
    srcs: [
        "device_config_definitions.go",
        "device_config_values.go",
        "device_config_value_set.go",
        "init.go",
        //"testing.go"
    ],
    /*
    testSrcs: [
        "device_config_test.go",
    ],
    */
    pluginFor: ["soong_build"],
}
+150 −0
Original line number Diff line number Diff line
// Copyright 2023 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package device_config

import (
	"android/soong/android"
	"fmt"
	"github.com/google/blueprint"
	"strings"
)

type DefinitionsModule struct {
	android.ModuleBase
	android.DefaultableModuleBase

	// Properties for "device_config_definitions"
	properties struct {
		// aconfig files, relative to this Android.bp file
		Srcs []string `android:"path"`

		// Release config flag namespace
		Namespace string

		// Values from TARGET_RELEASE / RELEASE_DEVICE_CONFIG_VALUE_SETS
		Values []string `blueprint:"mutated"`
	}

	intermediatePath android.WritablePath
	srcJarPath       android.WritablePath
}

func DefinitionsFactory() android.Module {
	module := &DefinitionsModule{}

	android.InitAndroidModule(module)
	android.InitDefaultableModule(module)
	module.AddProperties(&module.properties)
	// TODO: bp2build
	//android.InitBazelModule(module)

	return module
}

type implicitValuesTagType struct {
	blueprint.BaseDependencyTag
}

var implicitValuesTag = implicitValuesTagType{}

func (module *DefinitionsModule) DepsMutator(ctx android.BottomUpMutatorContext) {
	// Validate Properties
	if len(module.properties.Srcs) == 0 {
		ctx.PropertyErrorf("srcs", "missing source files")
		return
	}
	if len(module.properties.Namespace) == 0 {
		ctx.PropertyErrorf("namespace", "missing namespace property")
	}

	// Add a dependency on the device_config_value_sets defined in
	// RELEASE_DEVICE_CONFIG_VALUE_SETS, and add any device_config_values that
	// match our namespace.
	valuesFromConfig := ctx.Config().ReleaseDeviceConfigValueSets()
	ctx.AddDependency(ctx.Module(), implicitValuesTag, valuesFromConfig...)
}

func (module *DefinitionsModule) OutputFiles(tag string) (android.Paths, error) {
	switch tag {
	case ".srcjar":
		return []android.Path{module.srcJarPath}, nil
	case "":
		// The default output of this module is the intermediates format, which is
		// not installable and in a private format that no other rules can handle
		// correctly.
		return []android.Path{module.intermediatePath}, nil
	default:
		return nil, fmt.Errorf("unsupported device_config_definitions module reference tag %q", tag)
	}
}

func joinAndPrefix(prefix string, values []string) string {
	var sb strings.Builder
	for _, v := range values {
		sb.WriteString(prefix)
		sb.WriteString(v)
	}
	return sb.String()
}

func (module *DefinitionsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	// Get the values that came from the global RELEASE_DEVICE_CONFIG_VALUE_SETS flag
	ctx.VisitDirectDeps(func(dep android.Module) {
		if !ctx.OtherModuleHasProvider(dep, valueSetProviderKey) {
			// Other modules get injected as dependencies too, for example the license modules
			return
		}
		depData := ctx.OtherModuleProvider(dep, valueSetProviderKey).(valueSetProviderData)
		valuesFiles, ok := depData.AvailableNamespaces[module.properties.Namespace]
		if ok {
			for _, path := range valuesFiles {
				module.properties.Values = append(module.properties.Values, path.String())
			}
		}
	})

	// Intermediate format
	inputFiles := android.PathsForModuleSrc(ctx, module.properties.Srcs)
	module.intermediatePath = android.PathForModuleOut(ctx, "intermediate.json")
	ctx.Build(pctx, android.BuildParams{
		Rule:        aconfigRule,
		Inputs:      inputFiles,
		Output:      module.intermediatePath,
		Description: "device_config_definitions",
		Args: map[string]string{
			"release_version": ctx.Config().ReleaseVersion(),
			"namespace":       module.properties.Namespace,
			"values":          joinAndPrefix(" --values ", module.properties.Values),
		},
	})

	// Generated java inside a srcjar
	module.srcJarPath = android.PathForModuleGen(ctx, ctx.ModuleName()+".srcjar")
	ctx.Build(pctx, android.BuildParams{
		Rule:        srcJarRule,
		Input:       module.intermediatePath,
		Output:      module.srcJarPath,
		Description: "device_config.srcjar",
	})

	// TODO: C++

	// Phony target for debugging convenience
	ctx.Build(pctx, android.BuildParams{
		Rule:   blueprint.Phony,
		Output: android.PathForPhony(ctx, ctx.ModuleName()),
		Inputs: []android.Path{module.srcJarPath}, // TODO: C++
	})
}
+61 −0
Original line number Diff line number Diff line
// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package device_config

import (
	"os"
	"testing"

	"android/soong/android"
	"android/soong/java"
)

func TestMain(m *testing.M) {
	os.Exit(m.Run())
}

func test(t *testing.T, bp string) *android.TestResult {
	t.Helper()

	mockFS := android.MockFS{
		"config.aconfig": nil,
	}

	result := android.GroupFixturePreparers(
		java.PrepareForTestWithJavaDefaultModules,
		PrepareForTestWithSyspropBuildComponents,
		// TODO: Consider values files, although maybe in its own test
		// android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
		//	variables.ReleaseConfigValuesBasePaths = ...
		//})
		mockFS.AddToFixture(),
		android.FixtureWithRootAndroidBp(bp),
	).RunTest(t)

	return result
}

func TestOutputs(t *testing.T) {
	/*result := */ test(t, `
        device_config {
            name: "my_device_config",
            srcs: ["config.aconfig"],
        }
	`)

	// TODO: Make sure it exports a .srcjar, which is used by java libraries
	// TODO: Make sure it exports an intermediates file
	// TODO: Make sure the intermediates file is propagated to the Android.mk file
}
Loading