blob: 53bd07be5b51c613ee5602e962c22a33d16eb7fb [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
99 if ctx.OtherModuleHasProvider(m, blueprint.SrcsFileProviderKey) {
Aditya Choudhary8094b6b2023-10-12 19:40:17 +0000100 moduleSrcs = ctx.OtherModuleProvider(
Aditya Choudhary26df39f2023-11-29 16:42:42 +0000101 m, blueprint.SrcsFileProviderKey,
102 ).(blueprint.SrcsFileProviderData).SrcPaths
Aditya Choudhary8094b6b2023-10-12 19:40:17 +0000103 }
104 if module.properties.MultiOwnership {
105 metadata := &code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership{
106 TargetName: &targetName,
107 TrendyTeamId: &module.properties.TeamId,
108 Path: &bpFilePath,
109 MultiOwnership: &module.properties.MultiOwnership,
Aditya Choudhary26df39f2023-11-29 16:42:42 +0000110 SourceFiles: moduleSrcs,
Aditya Choudhary8094b6b2023-10-12 19:40:17 +0000111 }
112 metadataList = append(metadataList, metadata)
113 } else {
114 metadata := &code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership{
115 TargetName: &targetName,
116 TrendyTeamId: &module.properties.TeamId,
117 Path: &bpFilePath,
Aditya Choudhary26df39f2023-11-29 16:42:42 +0000118 SourceFiles: moduleSrcs,
Aditya Choudhary8094b6b2023-10-12 19:40:17 +0000119 }
120 metadataList = append(metadataList, metadata)
121 }
122
123 }
124 codeMetadata := &code_metadata_internal_proto.CodeMetadataInternal{TargetOwnershipList: metadataList}
125 protoData, err := proto.Marshal(codeMetadata)
126 if err != nil {
127 ctx.ModuleErrorf("Error marshaling code metadata: %s", err.Error())
128 return
129 }
130 intermediatePath := android.PathForModuleOut(
131 ctx, "intermediateCodeMetadata.pb",
132 )
133 android.WriteFileRule(ctx, intermediatePath, string(protoData))
134
135 ctx.SetProvider(
136 CodeMetadataProviderKey,
137 CodeMetadataProviderData{IntermediatePath: intermediatePath},
138 )
139}