blob: bbb8639684bd2c0d720c7eb4f92a875c5b4723f5 [file] [log] [blame]
Inseob Kimb554e592019-04-15 20:10:46 +09001// Copyright (C) 2019 The Android Open Source Project
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 selinux
16
17import (
18 "fmt"
19 "io"
20 "strings"
21
Inseob Kimcd616492020-03-24 23:06:40 +090022 "github.com/google/blueprint"
Inseob Kimb554e592019-04-15 20:10:46 +090023 "github.com/google/blueprint/proptools"
24
25 "android/soong/android"
Inseob Kimcd616492020-03-24 23:06:40 +090026 "android/soong/sysprop"
Inseob Kimb554e592019-04-15 20:10:46 +090027)
28
Inseob Kimb554e592019-04-15 20:10:46 +090029type selinuxContextsProperties struct {
30 // Filenames under sepolicy directories, which will be used to generate contexts file.
31 Srcs []string `android:"path"`
32
33 Product_variables struct {
34 Debuggable struct {
35 Srcs []string
36 }
37
38 Address_sanitize struct {
39 Srcs []string
40 }
41 }
42
43 // Whether reqd_mask directory is included to sepolicy directories or not.
44 Reqd_mask *bool
45
46 // Whether the comments in generated contexts file will be removed or not.
47 Remove_comment *bool
48
49 // Whether the result context file is sorted with fc_sort or not.
50 Fc_sort *bool
51
52 // Make this module available when building for recovery
53 Recovery_available *bool
Inseob Kimb554e592019-04-15 20:10:46 +090054}
55
56type fileContextsProperties struct {
57 // flatten_apex can be used to specify additional sources of file_contexts.
58 // Apex paths, /system/apex/{apex_name}, will be amended to the paths of file_contexts
59 // entries.
60 Flatten_apex struct {
61 Srcs []string
62 }
63}
64
65type selinuxContextsModule struct {
66 android.ModuleBase
67
68 properties selinuxContextsProperties
69 fileContextsProperties fileContextsProperties
Inseob Kimcd616492020-03-24 23:06:40 +090070 build func(ctx android.ModuleContext, inputs android.Paths) android.Path
71 deps func(ctx android.BottomUpMutatorContext)
72 outputPath android.Path
Colin Cross040f1512019-10-02 10:36:09 -070073 installPath android.InstallPath
Inseob Kimb554e592019-04-15 20:10:46 +090074}
75
76var (
Inseob Kimcd616492020-03-24 23:06:40 +090077 reuseContextsDepTag = dependencyTag{name: "reuseContexts"}
78 syspropLibraryDepTag = dependencyTag{name: "sysprop_library"}
Inseob Kimb554e592019-04-15 20:10:46 +090079)
80
81func init() {
82 pctx.HostBinToolVariable("fc_sort", "fc_sort")
83
84 android.RegisterModuleType("file_contexts", fileFactory)
85 android.RegisterModuleType("hwservice_contexts", hwServiceFactory)
86 android.RegisterModuleType("property_contexts", propertyFactory)
87 android.RegisterModuleType("service_contexts", serviceFactory)
Janis Danisevskisc40681f2020-07-25 13:02:29 -070088 android.RegisterModuleType("keystore2_key_contexts", keystoreKeyFactory)
Inseob Kimb554e592019-04-15 20:10:46 +090089}
90
Colin Cross040f1512019-10-02 10:36:09 -070091func (m *selinuxContextsModule) InstallInRoot() bool {
Inseob Kimfa6fe472021-01-12 13:40:27 +090092 return m.InRecovery()
93}
94
95func (m *selinuxContextsModule) InstallInRecovery() bool {
96 // ModuleBase.InRecovery() checks the image variant
97 return m.InRecovery()
98}
99
100func (m *selinuxContextsModule) onlyInRecovery() bool {
101 // ModuleBase.InstallInRecovery() checks commonProperties.Recovery property
102 return m.ModuleBase.InstallInRecovery()
Colin Cross040f1512019-10-02 10:36:09 -0700103}
104
Inseob Kimcd616492020-03-24 23:06:40 +0900105func (m *selinuxContextsModule) DepsMutator(ctx android.BottomUpMutatorContext) {
106 if m.deps != nil {
107 m.deps(ctx)
108 }
Inseob Kimfa6fe472021-01-12 13:40:27 +0900109
110 if m.InRecovery() && !m.onlyInRecovery() {
111 ctx.AddFarVariationDependencies([]blueprint.Variation{
112 {Mutator: "image", Variation: android.CoreVariation},
113 }, reuseContextsDepTag, ctx.ModuleName())
114 }
Inseob Kimcd616492020-03-24 23:06:40 +0900115}
116
117func (m *selinuxContextsModule) propertyContextsDeps(ctx android.BottomUpMutatorContext) {
118 for _, lib := range sysprop.SyspropLibraries(ctx.Config()) {
119 ctx.AddFarVariationDependencies([]blueprint.Variation{}, syspropLibraryDepTag, lib)
120 }
121}
122
Inseob Kimb554e592019-04-15 20:10:46 +0900123func (m *selinuxContextsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Inseob Kimfa6fe472021-01-12 13:40:27 +0900124 if m.InRecovery() {
Colin Cross040f1512019-10-02 10:36:09 -0700125 // Installing context files at the root of the recovery partition
126 m.installPath = android.PathForModuleInstall(ctx)
Inseob Kimb554e592019-04-15 20:10:46 +0900127 } else {
128 m.installPath = android.PathForModuleInstall(ctx, "etc", "selinux")
129 }
130
Inseob Kimfa6fe472021-01-12 13:40:27 +0900131 if m.InRecovery() && !m.onlyInRecovery() {
Inseob Kimb554e592019-04-15 20:10:46 +0900132 dep := ctx.GetDirectDepWithTag(m.Name(), reuseContextsDepTag)
133
134 if reuseDeps, ok := dep.(*selinuxContextsModule); ok {
135 m.outputPath = reuseDeps.outputPath
136 ctx.InstallFile(m.installPath, m.Name(), m.outputPath)
137 return
138 }
139 }
140
141 var inputs android.Paths
142
Paul Duffin532bde12021-07-09 22:53:03 +0100143 ctx.VisitDirectDeps(func(dep android.Module) {
144 depTag := ctx.OtherModuleDependencyTag(dep)
145 if !android.IsSourceDepTagWithOutputTag(depTag, "") {
146 return
147 }
Inseob Kimb554e592019-04-15 20:10:46 +0900148 segroup, ok := dep.(*fileGroup)
149 if !ok {
150 ctx.ModuleErrorf("srcs dependency %q is not an selinux filegroup",
151 ctx.OtherModuleName(dep))
152 return
153 }
154
155 if ctx.ProductSpecific() {
156 inputs = append(inputs, segroup.ProductPrivateSrcs()...)
157 } else if ctx.SocSpecific() {
Inseob Kim8ada8a72020-11-09 20:58:58 +0900158 if ctx.DeviceConfig().BoardSepolicyVers() == ctx.DeviceConfig().PlatformSepolicyVersion() {
159 inputs = append(inputs, segroup.SystemVendorSrcs()...)
160 }
Inseob Kimb554e592019-04-15 20:10:46 +0900161 inputs = append(inputs, segroup.VendorSrcs()...)
162 } else if ctx.DeviceSpecific() {
163 inputs = append(inputs, segroup.OdmSrcs()...)
Bowgo Tsai86a048d2019-09-09 22:04:06 +0800164 } else if ctx.SystemExtSpecific() {
165 inputs = append(inputs, segroup.SystemExtPrivateSrcs()...)
Inseob Kimb554e592019-04-15 20:10:46 +0900166 } else {
167 inputs = append(inputs, segroup.SystemPrivateSrcs()...)
Felix342b58a2020-03-02 16:13:12 +0100168 inputs = append(inputs, segroup.SystemPublicSrcs()...)
Inseob Kimb554e592019-04-15 20:10:46 +0900169 }
170
171 if proptools.Bool(m.properties.Reqd_mask) {
Inseob Kim8ada8a72020-11-09 20:58:58 +0900172 if ctx.SocSpecific() || ctx.DeviceSpecific() {
173 inputs = append(inputs, segroup.VendorReqdMaskSrcs()...)
174 } else {
175 inputs = append(inputs, segroup.SystemReqdMaskSrcs()...)
176 }
Inseob Kimb554e592019-04-15 20:10:46 +0900177 }
178 })
179
180 for _, src := range m.properties.Srcs {
181 // Module sources are handled above with VisitDirectDepsWithTag
182 if android.SrcIsModule(src) == "" {
183 inputs = append(inputs, android.PathForModuleSrc(ctx, src))
184 }
185 }
186
Inseob Kimcd616492020-03-24 23:06:40 +0900187 m.outputPath = m.build(ctx, inputs)
188 ctx.InstallFile(m.installPath, ctx.ModuleName(), m.outputPath)
Inseob Kimb554e592019-04-15 20:10:46 +0900189}
190
191func newModule() *selinuxContextsModule {
192 m := &selinuxContextsModule{}
193 m.AddProperties(
194 &m.properties,
195 )
196 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
197 android.AddLoadHook(m, func(ctx android.LoadHookContext) {
198 m.selinuxContextsHook(ctx)
199 })
200 return m
201}
202
203func (m *selinuxContextsModule) selinuxContextsHook(ctx android.LoadHookContext) {
204 // TODO: clean this up to use build/soong/android/variable.go after b/79249983
205 var srcs []string
206
207 if ctx.Config().Debuggable() {
208 srcs = append(srcs, m.properties.Product_variables.Debuggable.Srcs...)
209 }
210
211 for _, sanitize := range ctx.Config().SanitizeDevice() {
212 if sanitize == "address" {
213 srcs = append(srcs, m.properties.Product_variables.Address_sanitize.Srcs...)
214 break
215 }
216 }
217
218 m.properties.Srcs = append(m.properties.Srcs, srcs...)
219}
220
221func (m *selinuxContextsModule) AndroidMk() android.AndroidMkData {
222 return android.AndroidMkData{
223 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
224 nameSuffix := ""
Inseob Kimfa6fe472021-01-12 13:40:27 +0900225 if m.InRecovery() && !m.onlyInRecovery() {
Inseob Kimb554e592019-04-15 20:10:46 +0900226 nameSuffix = ".recovery"
227 }
228 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
229 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
230 fmt.Fprintln(w, "LOCAL_MODULE :=", name+nameSuffix)
Bob Badour4eeb6a22021-01-07 03:34:31 +0000231 data.Entries.WriteLicenseVariables(w)
Inseob Kimb554e592019-04-15 20:10:46 +0900232 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
233 if m.Owner() != "" {
234 fmt.Fprintln(w, "LOCAL_MODULE_OWNER :=", m.Owner())
235 }
236 fmt.Fprintln(w, "LOCAL_MODULE_TAGS := optional")
237 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", m.outputPath.String())
Colin Cross040f1512019-10-02 10:36:09 -0700238 fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", m.installPath.ToMakePath().String())
Inseob Kimb554e592019-04-15 20:10:46 +0900239 fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", name)
240 fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
241 },
242 }
243}
244
Inseob Kimfa6fe472021-01-12 13:40:27 +0900245func (m *selinuxContextsModule) ImageMutatorBegin(ctx android.BaseModuleContext) {
246 if proptools.Bool(m.properties.Recovery_available) && m.InstallInRecovery() {
247 ctx.PropertyErrorf("recovery_available",
248 "doesn't make sense at the same time as `recovery: true`")
Inseob Kimb554e592019-04-15 20:10:46 +0900249 }
250}
251
Inseob Kimfa6fe472021-01-12 13:40:27 +0900252func (m *selinuxContextsModule) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
253 return !m.InstallInRecovery()
254}
255
256func (m *selinuxContextsModule) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
257 return false
258}
259
260func (m *selinuxContextsModule) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
261 return false
262}
263
Inseob Kim6cc75f42021-04-29 13:53:20 +0000264func (m *selinuxContextsModule) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
265 return false
266}
267
Inseob Kimfa6fe472021-01-12 13:40:27 +0900268func (m *selinuxContextsModule) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
269 return m.InstallInRecovery() || proptools.Bool(m.properties.Recovery_available)
270}
271
272func (m *selinuxContextsModule) ExtraImageVariations(ctx android.BaseModuleContext) []string {
273 return nil
274}
275
276func (m *selinuxContextsModule) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
277}
278
279var _ android.ImageInterface = (*selinuxContextsModule)(nil)
280
Inseob Kimcd616492020-03-24 23:06:40 +0900281func (m *selinuxContextsModule) buildGeneralContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
282 ret := android.PathForModuleGen(ctx, ctx.ModuleName()+"_m4out")
Inseob Kimb554e592019-04-15 20:10:46 +0900283
Colin Cross242c8bc2020-11-16 17:58:17 -0800284 rule := android.NewRuleBuilder(pctx, ctx)
Inseob Kimb554e592019-04-15 20:10:46 +0900285
286 rule.Command().
Dan Willemsen3c3e59b2019-06-19 10:52:50 -0700287 Tool(ctx.Config().PrebuiltBuildTool(ctx, "m4")).
288 Text("--fatal-warnings -s").
Inseob Kimb554e592019-04-15 20:10:46 +0900289 FlagForEachArg("-D", ctx.DeviceConfig().SepolicyM4Defs()).
290 Inputs(inputs).
Inseob Kimcd616492020-03-24 23:06:40 +0900291 FlagWithOutput("> ", ret)
Inseob Kimb554e592019-04-15 20:10:46 +0900292
293 if proptools.Bool(m.properties.Remove_comment) {
Inseob Kimcd616492020-03-24 23:06:40 +0900294 rule.Temporary(ret)
Inseob Kimb554e592019-04-15 20:10:46 +0900295
296 remove_comment_output := android.PathForModuleGen(ctx, ctx.ModuleName()+"_remove_comment")
297
298 rule.Command().
299 Text("sed -e 's/#.*$//' -e '/^$/d'").
Inseob Kimcd616492020-03-24 23:06:40 +0900300 Input(ret).
Inseob Kimb554e592019-04-15 20:10:46 +0900301 FlagWithOutput("> ", remove_comment_output)
302
Inseob Kimcd616492020-03-24 23:06:40 +0900303 ret = remove_comment_output
Inseob Kimb554e592019-04-15 20:10:46 +0900304 }
305
306 if proptools.Bool(m.properties.Fc_sort) {
Inseob Kimcd616492020-03-24 23:06:40 +0900307 rule.Temporary(ret)
Inseob Kimb554e592019-04-15 20:10:46 +0900308
309 sorted_output := android.PathForModuleGen(ctx, ctx.ModuleName()+"_sorted")
310
311 rule.Command().
312 Tool(ctx.Config().HostToolPath(ctx, "fc_sort")).
Inseob Kimcd616492020-03-24 23:06:40 +0900313 FlagWithInput("-i ", ret).
Inseob Kimb554e592019-04-15 20:10:46 +0900314 FlagWithOutput("-o ", sorted_output)
315
Inseob Kimcd616492020-03-24 23:06:40 +0900316 ret = sorted_output
Inseob Kimb554e592019-04-15 20:10:46 +0900317 }
318
Colin Cross242c8bc2020-11-16 17:58:17 -0800319 rule.Build("selinux_contexts", "building contexts: "+m.Name())
Inseob Kimb554e592019-04-15 20:10:46 +0900320
321 rule.DeleteTemporaryFiles()
322
Inseob Kimcd616492020-03-24 23:06:40 +0900323 return ret
Inseob Kimb554e592019-04-15 20:10:46 +0900324}
325
Inseob Kimcd616492020-03-24 23:06:40 +0900326func (m *selinuxContextsModule) buildFileContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
Inseob Kimb554e592019-04-15 20:10:46 +0900327 if m.properties.Fc_sort == nil {
328 m.properties.Fc_sort = proptools.BoolPtr(true)
329 }
330
Colin Cross242c8bc2020-11-16 17:58:17 -0800331 rule := android.NewRuleBuilder(pctx, ctx)
Inseob Kimb554e592019-04-15 20:10:46 +0900332
333 if ctx.Config().FlattenApex() {
334 for _, src := range m.fileContextsProperties.Flatten_apex.Srcs {
335 if m := android.SrcIsModule(src); m != "" {
336 ctx.ModuleErrorf(
337 "Module srcs dependency %q is not supported for flatten_apex.srcs", m)
Inseob Kimcd616492020-03-24 23:06:40 +0900338 return nil
Inseob Kimb554e592019-04-15 20:10:46 +0900339 }
340 for _, path := range android.PathsForModuleSrcExcludes(ctx, []string{src}, nil) {
341 out := android.PathForModuleGen(ctx, "flattened_apex", path.Rel())
342 apex_path := "/system/apex/" + strings.Replace(
343 strings.TrimSuffix(path.Base(), "-file_contexts"),
344 ".", "\\\\.", -1)
345
346 rule.Command().
347 Text("awk '/object_r/{printf(\""+apex_path+"%s\\n\",$0)}'").
348 Input(path).
349 FlagWithOutput("> ", out)
350
351 inputs = append(inputs, out)
352 }
353 }
354 }
355
Colin Cross242c8bc2020-11-16 17:58:17 -0800356 rule.Build(m.Name(), "flattened_apex_file_contexts")
Inseob Kimcd616492020-03-24 23:06:40 +0900357 return m.buildGeneralContexts(ctx, inputs)
Inseob Kimb554e592019-04-15 20:10:46 +0900358}
359
360func fileFactory() android.Module {
361 m := newModule()
362 m.AddProperties(&m.fileContextsProperties)
363 m.build = m.buildFileContexts
364 return m
365}
366
Inseob Kimcd616492020-03-24 23:06:40 +0900367func (m *selinuxContextsModule) buildHwServiceContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
Inseob Kimb554e592019-04-15 20:10:46 +0900368 if m.properties.Remove_comment == nil {
369 m.properties.Remove_comment = proptools.BoolPtr(true)
370 }
371
Inseob Kimcd616492020-03-24 23:06:40 +0900372 return m.buildGeneralContexts(ctx, inputs)
373}
374
Inseob Kim2bcc0452020-12-21 13:16:44 +0900375func (m *selinuxContextsModule) checkVendorPropertyNamespace(ctx android.ModuleContext, inputs android.Paths) android.Paths {
376 shippingApiLevel := ctx.DeviceConfig().ShippingApiLevel()
377 ApiLevelR := android.ApiLevelOrPanic(ctx, "R")
378
379 rule := android.NewRuleBuilder(pctx, ctx)
380
381 // This list is from vts_treble_sys_prop_test.
382 allowedPropertyPrefixes := []string{
383 "ctl.odm.",
384 "ctl.vendor.",
385 "ctl.start$odm.",
386 "ctl.start$vendor.",
387 "ctl.stop$odm.",
388 "ctl.stop$vendor.",
389 "init.svc.odm.",
390 "init.svc.vendor.",
391 "ro.boot.",
392 "ro.hardware.",
393 "ro.odm.",
394 "ro.vendor.",
395 "odm.",
396 "persist.odm.",
397 "persist.vendor.",
398 "vendor.",
399 }
400
401 // persist.camera is also allowed for devices launching with R or eariler
402 if shippingApiLevel.LessThanOrEqualTo(ApiLevelR) {
403 allowedPropertyPrefixes = append(allowedPropertyPrefixes, "persist.camera.")
404 }
405
406 var allowedContextPrefixes []string
407
408 if shippingApiLevel.GreaterThanOrEqualTo(ApiLevelR) {
409 // This list is from vts_treble_sys_prop_test.
410 allowedContextPrefixes = []string{
411 "vendor_",
412 "odm_",
413 }
414 }
415
416 var ret android.Paths
417 for _, input := range inputs {
418 cmd := rule.Command().
419 BuiltTool("check_prop_prefix").
420 FlagWithInput("--property-contexts ", input).
421 FlagForEachArg("--allowed-property-prefix ", proptools.ShellEscapeList(allowedPropertyPrefixes)). // contains shell special character '$'
422 FlagForEachArg("--allowed-context-prefix ", allowedContextPrefixes)
423
424 if !ctx.DeviceConfig().BuildBrokenVendorPropertyNamespace() {
425 cmd.Flag("--strict")
426 }
427
428 out := android.PathForModuleGen(ctx, "namespace_checked").Join(ctx, input.String())
429 rule.Command().Text("cp -f").Input(input).Output(out)
430 ret = append(ret, out)
431 }
432 rule.Build("check_namespace", "checking namespace of "+ctx.ModuleName())
433 return ret
434}
435
Inseob Kimcd616492020-03-24 23:06:40 +0900436func (m *selinuxContextsModule) buildPropertyContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
Inseob Kim2bcc0452020-12-21 13:16:44 +0900437 // vendor/odm properties are enforced for devices launching with Android Q or later. So, if
438 // vendor/odm, make sure that only vendor/odm properties exist.
439 shippingApiLevel := ctx.DeviceConfig().ShippingApiLevel()
440 ApiLevelQ := android.ApiLevelOrPanic(ctx, "Q")
441 if (ctx.SocSpecific() || ctx.DeviceSpecific()) && shippingApiLevel.GreaterThanOrEqualTo(ApiLevelQ) {
442 inputs = m.checkVendorPropertyNamespace(ctx, inputs)
443 }
444
Inseob Kimcd616492020-03-24 23:06:40 +0900445 builtCtxFile := m.buildGeneralContexts(ctx, inputs)
446
447 var apiFiles android.Paths
448 ctx.VisitDirectDepsWithTag(syspropLibraryDepTag, func(c android.Module) {
Inseob Kim3a3539a2021-01-15 18:10:29 +0900449 i, ok := c.(interface{ CurrentSyspropApiFile() android.OptionalPath })
Inseob Kimcd616492020-03-24 23:06:40 +0900450 if !ok {
451 panic(fmt.Errorf("unknown dependency %q for %q", ctx.OtherModuleName(c), ctx.ModuleName()))
452 }
Inseob Kim3a3539a2021-01-15 18:10:29 +0900453 if api := i.CurrentSyspropApiFile(); api.Valid() {
454 apiFiles = append(apiFiles, api.Path())
455 }
Inseob Kimcd616492020-03-24 23:06:40 +0900456 })
457
458 // check compatibility with sysprop_library
459 if len(apiFiles) > 0 {
460 out := android.PathForModuleGen(ctx, ctx.ModuleName()+"_api_checked")
Colin Cross242c8bc2020-11-16 17:58:17 -0800461 rule := android.NewRuleBuilder(pctx, ctx)
Inseob Kimcd616492020-03-24 23:06:40 +0900462
463 msg := `\n******************************\n` +
464 `API of sysprop_library doesn't match with property_contexts\n` +
465 `Please fix the breakage and rebuild.\n` +
466 `******************************\n`
467
468 rule.Command().
469 Text("( ").
Colin Cross242c8bc2020-11-16 17:58:17 -0800470 BuiltTool("sysprop_type_checker").
Inseob Kimcd616492020-03-24 23:06:40 +0900471 FlagForEachInput("--api ", apiFiles).
472 FlagWithInput("--context ", builtCtxFile).
473 Text(" || ( echo").Flag("-e").
474 Flag(`"` + msg + `"`).
475 Text("; exit 38) )")
476
477 rule.Command().Text("cp -f").Input(builtCtxFile).Output(out)
Colin Cross242c8bc2020-11-16 17:58:17 -0800478 rule.Build("property_contexts_check_api", "checking API: "+m.Name())
Inseob Kimcd616492020-03-24 23:06:40 +0900479 builtCtxFile = out
480 }
481
482 return builtCtxFile
Inseob Kimb554e592019-04-15 20:10:46 +0900483}
484
485func hwServiceFactory() android.Module {
486 m := newModule()
487 m.build = m.buildHwServiceContexts
488 return m
489}
490
491func propertyFactory() android.Module {
492 m := newModule()
Inseob Kimcd616492020-03-24 23:06:40 +0900493 m.build = m.buildPropertyContexts
494 m.deps = m.propertyContextsDeps
Inseob Kimb554e592019-04-15 20:10:46 +0900495 return m
496}
497
498func serviceFactory() android.Module {
499 m := newModule()
500 m.build = m.buildGeneralContexts
501 return m
502}
Janis Danisevskisc40681f2020-07-25 13:02:29 -0700503
504func keystoreKeyFactory() android.Module {
505 m := newModule()
506 m.build = m.buildGeneralContexts
507 return m
508}