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

Commit c32e0461 authored by Spandan Das's avatar Spandan Das
Browse files

Add android_info module type

This is heavily inspired by the implementation in
https://r.android.com/3081436. `android_info` will generate a .txt file
with board specific information which will subsequently be used to
generate build.prop file for vendor.

The key differences are
1. `android_info` is not a singleton module.
2. Create android_info.prop from android_info.txt. The .prop file will
   be passed to --prop-files when generating /vendor/build.prop
3. Board info properties like `TARGET_BOARD_INFO_FILES` will not be
   added to android.Config API. (But they will be added to the unstable
   `PartitionVarsForSoongMigrationOnlyDoNotUse` in a followup CL)
3. android-info.txt will _not_ be installed via ctx.InstallFile,
   atleast for now. This file is created in $PRODUCT_OUT, but not
   installed on device.

Test: m nothing --no-skip-soong-tests
Bug: 375500423
Change-Id: Ie79f4f5fe828d7876c12e224f4dff1cc17e1b4d4
parent 6751bac0
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ bootstrap_go_package {
    srcs: [
        "aconfig_providers.go",
        "all_teams.go",
        "android_info.go",
        "androidmk.go",
        "apex.go",
        "apex_contributions.go",
@@ -121,6 +122,7 @@ bootstrap_go_package {
        "apex_test.go",
        "arch_test.go",
        "blueprint_e2e_test.go",
        "build_prop_test.go",
        "config_test.go",
        "configured_jars_test.go",
        "csuite_config_test.go",
+77 −0
Original line number Diff line number Diff line
// Copyright 2024 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 android

import (
	"github.com/google/blueprint/proptools"
)

type androidInfoProperties struct {
	// Name of output file. Defaults to module name
	Stem *string

	// Paths of board-info.txt files.
	Board_info_files []string `android:"path"`

	// Name of bootloader board. If board_info_files is empty, `board={bootloader_board_name}` will
	// be printed to output. Ignored if board_info_files is not empty.
	Bootloader_board_name *string
}

type androidInfoModule struct {
	ModuleBase

	properties androidInfoProperties
}

func (p *androidInfoModule) GenerateAndroidBuildActions(ctx ModuleContext) {
	if len(p.properties.Board_info_files) > 0 && p.properties.Bootloader_board_name != nil {
		ctx.ModuleErrorf("Either Board_info_files or Bootloader_board_name should be set. Please remove one of them\n")
		return
	}
	outName := proptools.StringDefault(p.properties.Stem, ctx.ModuleName()+".txt")
	androidInfoTxt := PathForModuleOut(ctx, outName).OutputPath
	androidInfoProp := androidInfoTxt.ReplaceExtension(ctx, "prop")

	rule := NewRuleBuilder(pctx, ctx)

	if boardInfoFiles := PathsForModuleSrc(ctx, p.properties.Board_info_files); len(boardInfoFiles) > 0 {
		rule.Command().Text("cat").Inputs(boardInfoFiles).
			Text(" | grep").FlagWithArg("-v ", "'#'").FlagWithOutput("> ", androidInfoTxt)
	} else if bootloaderBoardName := proptools.String(p.properties.Bootloader_board_name); bootloaderBoardName != "" {
		rule.Command().Text("echo").Text("'board="+bootloaderBoardName+"'").FlagWithOutput("> ", androidInfoTxt)
	} else {
		rule.Command().Text("echo").Text("''").FlagWithOutput("> ", androidInfoTxt)
	}

	rule.Build(ctx.ModuleName(), "generating android-info.prop")

	// Create android_info.prop
	rule = NewRuleBuilder(pctx, ctx)
	rule.Command().Text("cat").Input(androidInfoTxt).
		Text(" | grep 'require version-' | sed -e 's/require version-/ro.build.expect./g' >").Output(androidInfoProp)
	rule.Build(ctx.ModuleName()+"prop", "generating android-info.prop")

	ctx.SetOutputFiles(Paths{androidInfoProp}, "")
}

// android_info module generate a file named android-info.txt that contains various information
// about the device we're building for.  This file is typically packaged up with everything else.
func AndroidInfoFactory() Module {
	module := &androidInfoModule{}
	module.AddProperties(&module.properties)
	InitAndroidModule(module)
	return module
}
+17 −7
Original line number Diff line number Diff line
@@ -19,8 +19,12 @@ import (
)

func init() {
	ctx := InitRegistrationContext
	registerBuildPropComponents(InitRegistrationContext)
}

func registerBuildPropComponents(ctx RegistrationContext) {
	ctx.RegisterModuleType("build_prop", BuildPropFactory)
	ctx.RegisterModuleType("android_info", AndroidInfoFactory)
}

type buildPropProperties struct {
@@ -38,6 +42,10 @@ type buildPropProperties struct {
	// Path to a JSON file containing product configs.
	Product_config *string `android:"path"`

	// Path to android-info.txt file containing board specific info.
	// This is empty for build.prop of all partitions except vendor.
	Android_info *string `android:"path"`

	// Optional subdirectory under which this file is installed into
	Relative_install_path *string
}
@@ -66,7 +74,10 @@ func (p *buildPropModule) propFiles(ctx ModuleContext) Paths {
	} else if partition == "odm" {
		return ctx.Config().OdmPropFiles(ctx)
	} else if partition == "vendor" {
		// TODO (b/375500423): Add android-info.txt to prop files
		if p.properties.Android_info != nil {
			androidInfo := PathForModuleSrc(ctx, proptools.String(p.properties.Android_info))
			return append(ctx.Config().VendorPropFiles(ctx), androidInfo)
		}
		return ctx.Config().VendorPropFiles(ctx)
	}
	return nil
@@ -111,13 +122,12 @@ var validPartitions = []string{
}

func (p *buildPropModule) GenerateAndroidBuildActions(ctx ModuleContext) {
	p.outputFilePath = PathForModuleOut(ctx, "build.prop").OutputPath
	if !ctx.Config().KatiEnabled() {
		WriteFileRule(ctx, p.outputFilePath, "# no build.prop if kati is disabled")
		ctx.SetOutputFiles(Paths{p.outputFilePath}, "")
		return
	if !p.SocSpecific() && p.properties.Android_info != nil {
		ctx.ModuleErrorf("Android_info cannot be set if build.prop is not installed in vendor partition")
	}

	p.outputFilePath = PathForModuleOut(ctx, "build.prop").OutputPath

	partition := p.partition(ctx.DeviceConfig())
	if !InList(partition, validPartitions) {
		ctx.PropertyErrorf("partition", "unsupported partition %q: only %q are supported", partition, validPartitions)
+41 −0
Original line number Diff line number Diff line
// Copyright 2024 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 android

import (
	"testing"
)

func TestPropFileInputs(t *testing.T) {
	bp := `
build_prop {
    name: "vendor-build.prop",
    stem: "build.prop",
    vendor: true,
    android_info: ":board-info",
    //product_config: ":product_config",
}
android_info {
    name: "board-info",
    stem: "android-info.txt",
}
`

	res := GroupFixturePreparers(
		FixtureRegisterWithContext(registerBuildPropComponents),
	).RunTestWithBp(t, bp)
	buildPropCmd := res.ModuleForTests("vendor-build.prop", "").Rule("vendor-build.prop_.vendor-build.prop").RuleParams.Command
	AssertStringDoesContain(t, "Could not find android-info in prop files of vendor build.prop", buildPropCmd, "--prop-files=out/soong/.intermediates/board-info/android-info.prop")
}