blob: fefdd4529839c16944a1be3bfcaec8b06d8aa425 [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
Yuntao Xu42e732c2021-11-18 22:33:02 +000033 // Output file name. Defaults to module name
34 Stem *string
35
Inseob Kimb554e592019-04-15 20:10:46 +090036 Product_variables struct {
37 Debuggable struct {
38 Srcs []string
39 }
40
41 Address_sanitize struct {
42 Srcs []string
43 }
44 }
45
46 // Whether reqd_mask directory is included to sepolicy directories or not.
47 Reqd_mask *bool
48
49 // Whether the comments in generated contexts file will be removed or not.
50 Remove_comment *bool
51
52 // Whether the result context file is sorted with fc_sort or not.
53 Fc_sort *bool
54
55 // Make this module available when building for recovery
56 Recovery_available *bool
Inseob Kimb554e592019-04-15 20:10:46 +090057}
58
59type fileContextsProperties struct {
60 // flatten_apex can be used to specify additional sources of file_contexts.
61 // Apex paths, /system/apex/{apex_name}, will be amended to the paths of file_contexts
62 // entries.
63 Flatten_apex struct {
64 Srcs []string
65 }
66}
67
68type selinuxContextsModule struct {
69 android.ModuleBase
70
71 properties selinuxContextsProperties
72 fileContextsProperties fileContextsProperties
Inseob Kimcd616492020-03-24 23:06:40 +090073 build func(ctx android.ModuleContext, inputs android.Paths) android.Path
74 deps func(ctx android.BottomUpMutatorContext)
75 outputPath android.Path
Colin Cross040f1512019-10-02 10:36:09 -070076 installPath android.InstallPath
Inseob Kimb554e592019-04-15 20:10:46 +090077}
78
79var (
Inseob Kimcd616492020-03-24 23:06:40 +090080 reuseContextsDepTag = dependencyTag{name: "reuseContexts"}
81 syspropLibraryDepTag = dependencyTag{name: "sysprop_library"}
Inseob Kimb554e592019-04-15 20:10:46 +090082)
83
84func init() {
85 pctx.HostBinToolVariable("fc_sort", "fc_sort")
86
87 android.RegisterModuleType("file_contexts", fileFactory)
88 android.RegisterModuleType("hwservice_contexts", hwServiceFactory)
89 android.RegisterModuleType("property_contexts", propertyFactory)
90 android.RegisterModuleType("service_contexts", serviceFactory)
Janis Danisevskisc40681f2020-07-25 13:02:29 -070091 android.RegisterModuleType("keystore2_key_contexts", keystoreKeyFactory)
Inseob Kimb554e592019-04-15 20:10:46 +090092}
93
Colin Cross040f1512019-10-02 10:36:09 -070094func (m *selinuxContextsModule) InstallInRoot() bool {
Inseob Kimfa6fe472021-01-12 13:40:27 +090095 return m.InRecovery()
96}
97
98func (m *selinuxContextsModule) InstallInRecovery() bool {
99 // ModuleBase.InRecovery() checks the image variant
100 return m.InRecovery()
101}
102
103func (m *selinuxContextsModule) onlyInRecovery() bool {
104 // ModuleBase.InstallInRecovery() checks commonProperties.Recovery property
105 return m.ModuleBase.InstallInRecovery()
Colin Cross040f1512019-10-02 10:36:09 -0700106}
107
Inseob Kimcd616492020-03-24 23:06:40 +0900108func (m *selinuxContextsModule) DepsMutator(ctx android.BottomUpMutatorContext) {
109 if m.deps != nil {
110 m.deps(ctx)
111 }
Inseob Kimfa6fe472021-01-12 13:40:27 +0900112
113 if m.InRecovery() && !m.onlyInRecovery() {
114 ctx.AddFarVariationDependencies([]blueprint.Variation{
115 {Mutator: "image", Variation: android.CoreVariation},
116 }, reuseContextsDepTag, ctx.ModuleName())
117 }
Inseob Kimcd616492020-03-24 23:06:40 +0900118}
119
120func (m *selinuxContextsModule) propertyContextsDeps(ctx android.BottomUpMutatorContext) {
121 for _, lib := range sysprop.SyspropLibraries(ctx.Config()) {
122 ctx.AddFarVariationDependencies([]blueprint.Variation{}, syspropLibraryDepTag, lib)
123 }
124}
125
Yuntao Xu42e732c2021-11-18 22:33:02 +0000126func (m *selinuxContextsModule) stem() string {
127 return proptools.StringDefault(m.properties.Stem, m.Name())
128}
129
Inseob Kimb554e592019-04-15 20:10:46 +0900130func (m *selinuxContextsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Inseob Kimfa6fe472021-01-12 13:40:27 +0900131 if m.InRecovery() {
Colin Cross040f1512019-10-02 10:36:09 -0700132 // Installing context files at the root of the recovery partition
133 m.installPath = android.PathForModuleInstall(ctx)
Inseob Kimb554e592019-04-15 20:10:46 +0900134 } else {
135 m.installPath = android.PathForModuleInstall(ctx, "etc", "selinux")
136 }
137
Inseob Kimfa6fe472021-01-12 13:40:27 +0900138 if m.InRecovery() && !m.onlyInRecovery() {
Inseob Kimb554e592019-04-15 20:10:46 +0900139 dep := ctx.GetDirectDepWithTag(m.Name(), reuseContextsDepTag)
140
141 if reuseDeps, ok := dep.(*selinuxContextsModule); ok {
142 m.outputPath = reuseDeps.outputPath
Yuntao Xu42e732c2021-11-18 22:33:02 +0000143 ctx.InstallFile(m.installPath, m.stem(), m.outputPath)
Inseob Kimb554e592019-04-15 20:10:46 +0900144 return
145 }
146 }
147
148 var inputs android.Paths
149
Paul Duffin532bde12021-07-09 22:53:03 +0100150 ctx.VisitDirectDeps(func(dep android.Module) {
151 depTag := ctx.OtherModuleDependencyTag(dep)
152 if !android.IsSourceDepTagWithOutputTag(depTag, "") {
153 return
154 }
Inseob Kimb554e592019-04-15 20:10:46 +0900155 segroup, ok := dep.(*fileGroup)
156 if !ok {
157 ctx.ModuleErrorf("srcs dependency %q is not an selinux filegroup",
158 ctx.OtherModuleName(dep))
159 return
160 }
161
162 if ctx.ProductSpecific() {
163 inputs = append(inputs, segroup.ProductPrivateSrcs()...)
164 } else if ctx.SocSpecific() {
Inseob Kim8ada8a72020-11-09 20:58:58 +0900165 if ctx.DeviceConfig().BoardSepolicyVers() == ctx.DeviceConfig().PlatformSepolicyVersion() {
166 inputs = append(inputs, segroup.SystemVendorSrcs()...)
167 }
Inseob Kimb554e592019-04-15 20:10:46 +0900168 inputs = append(inputs, segroup.VendorSrcs()...)
169 } else if ctx.DeviceSpecific() {
170 inputs = append(inputs, segroup.OdmSrcs()...)
Bowgo Tsai86a048d2019-09-09 22:04:06 +0800171 } else if ctx.SystemExtSpecific() {
172 inputs = append(inputs, segroup.SystemExtPrivateSrcs()...)
Inseob Kimb554e592019-04-15 20:10:46 +0900173 } else {
174 inputs = append(inputs, segroup.SystemPrivateSrcs()...)
Felix342b58a2020-03-02 16:13:12 +0100175 inputs = append(inputs, segroup.SystemPublicSrcs()...)
Inseob Kimb554e592019-04-15 20:10:46 +0900176 }
177
178 if proptools.Bool(m.properties.Reqd_mask) {
Inseob Kim8ada8a72020-11-09 20:58:58 +0900179 if ctx.SocSpecific() || ctx.DeviceSpecific() {
180 inputs = append(inputs, segroup.VendorReqdMaskSrcs()...)
181 } else {
182 inputs = append(inputs, segroup.SystemReqdMaskSrcs()...)
183 }
Inseob Kimb554e592019-04-15 20:10:46 +0900184 }
185 })
186
187 for _, src := range m.properties.Srcs {
188 // Module sources are handled above with VisitDirectDepsWithTag
189 if android.SrcIsModule(src) == "" {
190 inputs = append(inputs, android.PathForModuleSrc(ctx, src))
191 }
192 }
193
Inseob Kimcd616492020-03-24 23:06:40 +0900194 m.outputPath = m.build(ctx, inputs)
Yuntao Xu42e732c2021-11-18 22:33:02 +0000195 ctx.InstallFile(m.installPath, m.stem(), m.outputPath)
Inseob Kimb554e592019-04-15 20:10:46 +0900196}
197
198func newModule() *selinuxContextsModule {
199 m := &selinuxContextsModule{}
200 m.AddProperties(
201 &m.properties,
202 )
203 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
204 android.AddLoadHook(m, func(ctx android.LoadHookContext) {
205 m.selinuxContextsHook(ctx)
206 })
207 return m
208}
209
210func (m *selinuxContextsModule) selinuxContextsHook(ctx android.LoadHookContext) {
211 // TODO: clean this up to use build/soong/android/variable.go after b/79249983
212 var srcs []string
213
214 if ctx.Config().Debuggable() {
215 srcs = append(srcs, m.properties.Product_variables.Debuggable.Srcs...)
216 }
217
218 for _, sanitize := range ctx.Config().SanitizeDevice() {
219 if sanitize == "address" {
220 srcs = append(srcs, m.properties.Product_variables.Address_sanitize.Srcs...)
221 break
222 }
223 }
224
225 m.properties.Srcs = append(m.properties.Srcs, srcs...)
226}
227
228func (m *selinuxContextsModule) AndroidMk() android.AndroidMkData {
Colin Crossf82aed02021-11-04 17:25:55 -0700229 nameSuffix := ""
230 if m.InRecovery() && !m.onlyInRecovery() {
231 nameSuffix = ".recovery"
232 }
Inseob Kimb554e592019-04-15 20:10:46 +0900233 return android.AndroidMkData{
Colin Crossf82aed02021-11-04 17:25:55 -0700234 Class: "ETC",
235 OutputFile: android.OptionalPathForPath(m.outputPath),
236 SubName: nameSuffix,
237 Extra: []android.AndroidMkExtraFunc{
238 func(w io.Writer, outputFile android.Path) {
239 fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", m.installPath.ToMakePath().String())
Yuntao Xu42e732c2021-11-18 22:33:02 +0000240 fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", m.stem())
Colin Crossf82aed02021-11-04 17:25:55 -0700241 },
Inseob Kimb554e592019-04-15 20:10:46 +0900242 },
243 }
244}
245
Inseob Kimfa6fe472021-01-12 13:40:27 +0900246func (m *selinuxContextsModule) ImageMutatorBegin(ctx android.BaseModuleContext) {
Yuntao Xu42e732c2021-11-18 22:33:02 +0000247 if proptools.Bool(m.properties.Recovery_available) && m.ModuleBase.InstallInRecovery() {
Inseob Kimfa6fe472021-01-12 13:40:27 +0900248 ctx.PropertyErrorf("recovery_available",
249 "doesn't make sense at the same time as `recovery: true`")
Inseob Kimb554e592019-04-15 20:10:46 +0900250 }
251}
252
Inseob Kimfa6fe472021-01-12 13:40:27 +0900253func (m *selinuxContextsModule) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
Yuntao Xu42e732c2021-11-18 22:33:02 +0000254 return !m.ModuleBase.InstallInRecovery()
Inseob Kimfa6fe472021-01-12 13:40:27 +0900255}
256
257func (m *selinuxContextsModule) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
258 return false
259}
260
261func (m *selinuxContextsModule) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
262 return false
263}
264
Inseob Kim6cc75f42021-04-29 13:53:20 +0000265func (m *selinuxContextsModule) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
266 return false
267}
268
Inseob Kimfa6fe472021-01-12 13:40:27 +0900269func (m *selinuxContextsModule) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
Yuntao Xu42e732c2021-11-18 22:33:02 +0000270 return m.ModuleBase.InstallInRecovery() || proptools.Bool(m.properties.Recovery_available)
Inseob Kimfa6fe472021-01-12 13:40:27 +0900271}
272
273func (m *selinuxContextsModule) ExtraImageVariations(ctx android.BaseModuleContext) []string {
274 return nil
275}
276
277func (m *selinuxContextsModule) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
278}
279
280var _ android.ImageInterface = (*selinuxContextsModule)(nil)
281
Inseob Kimcd616492020-03-24 23:06:40 +0900282func (m *selinuxContextsModule) buildGeneralContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
Yuntao Xu42e732c2021-11-18 22:33:02 +0000283 builtContext := android.PathForModuleGen(ctx, ctx.ModuleName()+"_m4out")
Inseob Kimb554e592019-04-15 20:10:46 +0900284
Colin Cross242c8bc2020-11-16 17:58:17 -0800285 rule := android.NewRuleBuilder(pctx, ctx)
Inseob Kimb554e592019-04-15 20:10:46 +0900286
287 rule.Command().
Dan Willemsen3c3e59b2019-06-19 10:52:50 -0700288 Tool(ctx.Config().PrebuiltBuildTool(ctx, "m4")).
289 Text("--fatal-warnings -s").
Inseob Kimb554e592019-04-15 20:10:46 +0900290 FlagForEachArg("-D", ctx.DeviceConfig().SepolicyM4Defs()).
291 Inputs(inputs).
Yuntao Xu42e732c2021-11-18 22:33:02 +0000292 FlagWithOutput("> ", builtContext)
Inseob Kimb554e592019-04-15 20:10:46 +0900293
294 if proptools.Bool(m.properties.Remove_comment) {
Yuntao Xu42e732c2021-11-18 22:33:02 +0000295 rule.Temporary(builtContext)
Inseob Kimb554e592019-04-15 20:10:46 +0900296
297 remove_comment_output := android.PathForModuleGen(ctx, ctx.ModuleName()+"_remove_comment")
298
299 rule.Command().
300 Text("sed -e 's/#.*$//' -e '/^$/d'").
Yuntao Xu42e732c2021-11-18 22:33:02 +0000301 Input(builtContext).
Inseob Kimb554e592019-04-15 20:10:46 +0900302 FlagWithOutput("> ", remove_comment_output)
303
Yuntao Xu42e732c2021-11-18 22:33:02 +0000304 builtContext = remove_comment_output
Inseob Kimb554e592019-04-15 20:10:46 +0900305 }
306
307 if proptools.Bool(m.properties.Fc_sort) {
Yuntao Xu42e732c2021-11-18 22:33:02 +0000308 rule.Temporary(builtContext)
Inseob Kimb554e592019-04-15 20:10:46 +0900309
310 sorted_output := android.PathForModuleGen(ctx, ctx.ModuleName()+"_sorted")
311
312 rule.Command().
313 Tool(ctx.Config().HostToolPath(ctx, "fc_sort")).
Yuntao Xu42e732c2021-11-18 22:33:02 +0000314 FlagWithInput("-i ", builtContext).
Inseob Kimb554e592019-04-15 20:10:46 +0900315 FlagWithOutput("-o ", sorted_output)
316
Yuntao Xu42e732c2021-11-18 22:33:02 +0000317 builtContext = sorted_output
Inseob Kimb554e592019-04-15 20:10:46 +0900318 }
319
Yuntao Xu42e732c2021-11-18 22:33:02 +0000320 ret := android.PathForModuleGen(ctx, m.stem())
321 rule.Temporary(builtContext)
322 rule.Command().Text("cp").Input(builtContext).Output(ret)
Inseob Kimb554e592019-04-15 20:10:46 +0900323
324 rule.DeleteTemporaryFiles()
Yuntao Xu42e732c2021-11-18 22:33:02 +0000325 rule.Build("selinux_contexts", "building contexts: "+m.Name())
Inseob Kimb554e592019-04-15 20:10:46 +0900326
Inseob Kimcd616492020-03-24 23:06:40 +0900327 return ret
Inseob Kimb554e592019-04-15 20:10:46 +0900328}
329
Inseob Kimcd616492020-03-24 23:06:40 +0900330func (m *selinuxContextsModule) buildFileContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
Inseob Kimb554e592019-04-15 20:10:46 +0900331 if m.properties.Fc_sort == nil {
332 m.properties.Fc_sort = proptools.BoolPtr(true)
333 }
334
Colin Cross242c8bc2020-11-16 17:58:17 -0800335 rule := android.NewRuleBuilder(pctx, ctx)
Inseob Kimb554e592019-04-15 20:10:46 +0900336
337 if ctx.Config().FlattenApex() {
338 for _, src := range m.fileContextsProperties.Flatten_apex.Srcs {
339 if m := android.SrcIsModule(src); m != "" {
340 ctx.ModuleErrorf(
341 "Module srcs dependency %q is not supported for flatten_apex.srcs", m)
Inseob Kimcd616492020-03-24 23:06:40 +0900342 return nil
Inseob Kimb554e592019-04-15 20:10:46 +0900343 }
344 for _, path := range android.PathsForModuleSrcExcludes(ctx, []string{src}, nil) {
345 out := android.PathForModuleGen(ctx, "flattened_apex", path.Rel())
346 apex_path := "/system/apex/" + strings.Replace(
347 strings.TrimSuffix(path.Base(), "-file_contexts"),
348 ".", "\\\\.", -1)
349
350 rule.Command().
351 Text("awk '/object_r/{printf(\""+apex_path+"%s\\n\",$0)}'").
352 Input(path).
353 FlagWithOutput("> ", out)
354
355 inputs = append(inputs, out)
356 }
357 }
358 }
359
Colin Cross242c8bc2020-11-16 17:58:17 -0800360 rule.Build(m.Name(), "flattened_apex_file_contexts")
Inseob Kimcd616492020-03-24 23:06:40 +0900361 return m.buildGeneralContexts(ctx, inputs)
Inseob Kimb554e592019-04-15 20:10:46 +0900362}
363
364func fileFactory() android.Module {
365 m := newModule()
366 m.AddProperties(&m.fileContextsProperties)
367 m.build = m.buildFileContexts
368 return m
369}
370
Inseob Kimcd616492020-03-24 23:06:40 +0900371func (m *selinuxContextsModule) buildHwServiceContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
Inseob Kimb554e592019-04-15 20:10:46 +0900372 if m.properties.Remove_comment == nil {
373 m.properties.Remove_comment = proptools.BoolPtr(true)
374 }
375
Inseob Kimcd616492020-03-24 23:06:40 +0900376 return m.buildGeneralContexts(ctx, inputs)
377}
378
Inseob Kim2bcc0452020-12-21 13:16:44 +0900379func (m *selinuxContextsModule) checkVendorPropertyNamespace(ctx android.ModuleContext, inputs android.Paths) android.Paths {
380 shippingApiLevel := ctx.DeviceConfig().ShippingApiLevel()
381 ApiLevelR := android.ApiLevelOrPanic(ctx, "R")
382
383 rule := android.NewRuleBuilder(pctx, ctx)
384
385 // This list is from vts_treble_sys_prop_test.
386 allowedPropertyPrefixes := []string{
387 "ctl.odm.",
388 "ctl.vendor.",
389 "ctl.start$odm.",
390 "ctl.start$vendor.",
391 "ctl.stop$odm.",
392 "ctl.stop$vendor.",
393 "init.svc.odm.",
394 "init.svc.vendor.",
395 "ro.boot.",
396 "ro.hardware.",
397 "ro.odm.",
398 "ro.vendor.",
399 "odm.",
400 "persist.odm.",
401 "persist.vendor.",
402 "vendor.",
403 }
404
405 // persist.camera is also allowed for devices launching with R or eariler
406 if shippingApiLevel.LessThanOrEqualTo(ApiLevelR) {
407 allowedPropertyPrefixes = append(allowedPropertyPrefixes, "persist.camera.")
408 }
409
410 var allowedContextPrefixes []string
411
412 if shippingApiLevel.GreaterThanOrEqualTo(ApiLevelR) {
413 // This list is from vts_treble_sys_prop_test.
414 allowedContextPrefixes = []string{
415 "vendor_",
416 "odm_",
417 }
418 }
419
420 var ret android.Paths
421 for _, input := range inputs {
422 cmd := rule.Command().
423 BuiltTool("check_prop_prefix").
424 FlagWithInput("--property-contexts ", input).
425 FlagForEachArg("--allowed-property-prefix ", proptools.ShellEscapeList(allowedPropertyPrefixes)). // contains shell special character '$'
426 FlagForEachArg("--allowed-context-prefix ", allowedContextPrefixes)
427
428 if !ctx.DeviceConfig().BuildBrokenVendorPropertyNamespace() {
429 cmd.Flag("--strict")
430 }
431
432 out := android.PathForModuleGen(ctx, "namespace_checked").Join(ctx, input.String())
433 rule.Command().Text("cp -f").Input(input).Output(out)
434 ret = append(ret, out)
435 }
436 rule.Build("check_namespace", "checking namespace of "+ctx.ModuleName())
437 return ret
438}
439
Inseob Kimcd616492020-03-24 23:06:40 +0900440func (m *selinuxContextsModule) buildPropertyContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
Inseob Kim2bcc0452020-12-21 13:16:44 +0900441 // vendor/odm properties are enforced for devices launching with Android Q or later. So, if
442 // vendor/odm, make sure that only vendor/odm properties exist.
443 shippingApiLevel := ctx.DeviceConfig().ShippingApiLevel()
444 ApiLevelQ := android.ApiLevelOrPanic(ctx, "Q")
445 if (ctx.SocSpecific() || ctx.DeviceSpecific()) && shippingApiLevel.GreaterThanOrEqualTo(ApiLevelQ) {
446 inputs = m.checkVendorPropertyNamespace(ctx, inputs)
447 }
448
Inseob Kimcd616492020-03-24 23:06:40 +0900449 builtCtxFile := m.buildGeneralContexts(ctx, inputs)
450
451 var apiFiles android.Paths
452 ctx.VisitDirectDepsWithTag(syspropLibraryDepTag, func(c android.Module) {
Inseob Kim3a3539a2021-01-15 18:10:29 +0900453 i, ok := c.(interface{ CurrentSyspropApiFile() android.OptionalPath })
Inseob Kimcd616492020-03-24 23:06:40 +0900454 if !ok {
455 panic(fmt.Errorf("unknown dependency %q for %q", ctx.OtherModuleName(c), ctx.ModuleName()))
456 }
Inseob Kim3a3539a2021-01-15 18:10:29 +0900457 if api := i.CurrentSyspropApiFile(); api.Valid() {
458 apiFiles = append(apiFiles, api.Path())
459 }
Inseob Kimcd616492020-03-24 23:06:40 +0900460 })
461
462 // check compatibility with sysprop_library
463 if len(apiFiles) > 0 {
464 out := android.PathForModuleGen(ctx, ctx.ModuleName()+"_api_checked")
Colin Cross242c8bc2020-11-16 17:58:17 -0800465 rule := android.NewRuleBuilder(pctx, ctx)
Inseob Kimcd616492020-03-24 23:06:40 +0900466
467 msg := `\n******************************\n` +
468 `API of sysprop_library doesn't match with property_contexts\n` +
469 `Please fix the breakage and rebuild.\n` +
470 `******************************\n`
471
472 rule.Command().
473 Text("( ").
Colin Cross242c8bc2020-11-16 17:58:17 -0800474 BuiltTool("sysprop_type_checker").
Inseob Kimcd616492020-03-24 23:06:40 +0900475 FlagForEachInput("--api ", apiFiles).
476 FlagWithInput("--context ", builtCtxFile).
477 Text(" || ( echo").Flag("-e").
478 Flag(`"` + msg + `"`).
479 Text("; exit 38) )")
480
481 rule.Command().Text("cp -f").Input(builtCtxFile).Output(out)
Colin Cross242c8bc2020-11-16 17:58:17 -0800482 rule.Build("property_contexts_check_api", "checking API: "+m.Name())
Inseob Kimcd616492020-03-24 23:06:40 +0900483 builtCtxFile = out
484 }
485
486 return builtCtxFile
Inseob Kimb554e592019-04-15 20:10:46 +0900487}
488
489func hwServiceFactory() android.Module {
490 m := newModule()
491 m.build = m.buildHwServiceContexts
492 return m
493}
494
495func propertyFactory() android.Module {
496 m := newModule()
Inseob Kimcd616492020-03-24 23:06:40 +0900497 m.build = m.buildPropertyContexts
498 m.deps = m.propertyContextsDeps
Inseob Kimb554e592019-04-15 20:10:46 +0900499 return m
500}
501
502func serviceFactory() android.Module {
503 m := newModule()
504 m.build = m.buildGeneralContexts
505 return m
506}
Janis Danisevskisc40681f2020-07-25 13:02:29 -0700507
508func keystoreKeyFactory() android.Module {
509 m := newModule()
510 m.build = m.buildGeneralContexts
511 return m
512}
Yuntao Xu42e732c2021-11-18 22:33:02 +0000513
514var _ android.OutputFileProducer = (*selinuxContextsModule)(nil)
515
516// Implements android.OutputFileProducer
517func (m *selinuxContextsModule) OutputFiles(tag string) (android.Paths, error) {
518 if tag == "" {
519 return []android.Path{m.outputPath}, nil
520 }
521 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
522}