blob: 11ba43037ebbc81897c02d3f4d30e25aec9a0ec5 [file] [log] [blame]
Aditya Choudhary8094b6b2023-10-12 19:40:17 +00001// Copyright 2020 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package testing
16
17import (
18 "path/filepath"
19
20 "android/soong/android"
21 "android/soong/testing/code_metadata_internal_proto"
22 "github.com/google/blueprint"
Colin Crossbc7d76c2023-12-12 16:39:03 -080023
Aditya Choudhary8094b6b2023-10-12 19:40:17 +000024 "google.golang.org/protobuf/proto"
25)
26
27func CodeMetadataFactory() android.Module {
28 module := &CodeMetadataModule{}
29
30 android.InitAndroidModule(module)
31 android.InitDefaultableModule(module)
32 module.AddProperties(&module.properties)
33
34 return module
35}
36
37type CodeMetadataModule struct {
38 android.ModuleBase
39 android.DefaultableModuleBase
Aditya Choudhary8094b6b2023-10-12 19:40:17 +000040
41 // Properties for "code_metadata"
42 properties struct {
43 // Specifies the name of the code_config.
44 Name string
45 // Specifies the team ID.
46 TeamId string
47 // Specifies the list of modules that this code_metadata covers.
48 Code []string
49 // An optional field to specify if multiple ownerships for source files is allowed.
50 MultiOwnership bool
51 }
52}
53
54type codeDepTagType struct {
55 blueprint.BaseDependencyTag
56}
57
58var codeDepTag = codeDepTagType{}
59
60func (module *CodeMetadataModule) DepsMutator(ctx android.BottomUpMutatorContext) {
61 // Validate Properties
62 if len(module.properties.TeamId) == 0 {
63 ctx.PropertyErrorf(
64 "TeamId",
65 "Team Id not found in the code_metadata module. Hint: Maybe the teamId property hasn't been properly specified.",
66 )
67 }
68 if !isInt(module.properties.TeamId) {
69 ctx.PropertyErrorf(
70 "TeamId", "Invalid value for Team ID. The Team ID must be an integer.",
71 )
72 }
73 if len(module.properties.Code) == 0 {
74 ctx.PropertyErrorf(
75 "Code",
76 "Targets to be attributed cannot be empty. Hint: Maybe the code property hasn't been properly specified.",
77 )
78 }
79 ctx.AddDependency(ctx.Module(), codeDepTag, module.properties.Code...)
80}
81
82// Provider published by CodeMetadata
83type CodeMetadataProviderData struct {
84 IntermediatePath android.WritablePath
85}
86
Colin Crossbc7d76c2023-12-12 16:39:03 -080087var CodeMetadataProviderKey = blueprint.NewProvider[CodeMetadataProviderData]()
Aditya Choudhary8094b6b2023-10-12 19:40:17 +000088
89func (module *CodeMetadataModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
90 metadataList := make(
91 []*code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership, 0,
92 len(module.properties.Code),
93 )
94 bpFilePath := filepath.Join(ctx.ModuleDir(), ctx.BlueprintsFile())
95
96 for _, m := range ctx.GetDirectDepsWithTag(codeDepTag) {
97 targetName := m.Name()
Aditya Choudhary26df39f2023-11-29 16:42:42 +000098 var moduleSrcs []string
Colin Cross313aa542023-12-13 13:47:44 -080099 if srcsFileInfo, ok := android.OtherModuleProvider(ctx, m, blueprint.SrcsFileProviderKey); ok {
100 moduleSrcs = srcsFileInfo.SrcPaths
Aditya Choudhary8094b6b2023-10-12 19:40:17 +0000101 }
102 if module.properties.MultiOwnership {
103 metadata := &code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership{
104 TargetName: &targetName,
105 TrendyTeamId: &module.properties.TeamId,
106 Path: &bpFilePath,
107 MultiOwnership: &module.properties.MultiOwnership,
Aditya Choudhary26df39f2023-11-29 16:42:42 +0000108 SourceFiles: moduleSrcs,
Aditya Choudhary8094b6b2023-10-12 19:40:17 +0000109 }
110 metadataList = append(metadataList, metadata)
111 } else {
112 metadata := &code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership{
113 TargetName: &targetName,
114 TrendyTeamId: &module.properties.TeamId,
115 Path: &bpFilePath,
Aditya Choudhary26df39f2023-11-29 16:42:42 +0000116 SourceFiles: moduleSrcs,
Aditya Choudhary8094b6b2023-10-12 19:40:17 +0000117 }
118 metadataList = append(metadataList, metadata)
119 }
120
121 }
122 codeMetadata := &code_metadata_internal_proto.CodeMetadataInternal{TargetOwnershipList: metadataList}
123 protoData, err := proto.Marshal(codeMetadata)
124 if err != nil {
125 ctx.ModuleErrorf("Error marshaling code metadata: %s", err.Error())
126 return
127 }
128 intermediatePath := android.PathForModuleOut(
129 ctx, "intermediateCodeMetadata.pb",
130 )
Colin Cross31a67452023-11-02 16:57:08 -0700131 android.WriteFileRuleVerbatim(ctx, intermediatePath, string(protoData))
Aditya Choudhary8094b6b2023-10-12 19:40:17 +0000132
Colin Cross40213022023-12-13 15:19:49 -0800133 android.SetProvider(ctx,
Aditya Choudhary8094b6b2023-10-12 19:40:17 +0000134 CodeMetadataProviderKey,
135 CodeMetadataProviderData{IntermediatePath: intermediatePath},
136 )
137}