blob: 7e03b2d416f378795024ea18fd1a5ca071520c9f [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 {
Inseob Kimb554e592019-04-15 20:10:46 +090037 Address_sanitize struct {
Inseob Kim6d3d5a62021-12-21 20:55:32 +090038 Srcs []string `android:"path"`
Inseob Kimb554e592019-04-15 20:10:46 +090039 }
40 }
41
Inseob Kimb554e592019-04-15 20:10:46 +090042 // Whether the comments in generated contexts file will be removed or not.
43 Remove_comment *bool
44
45 // Whether the result context file is sorted with fc_sort or not.
46 Fc_sort *bool
47
48 // Make this module available when building for recovery
49 Recovery_available *bool
Inseob Kimb554e592019-04-15 20:10:46 +090050}
51
52type fileContextsProperties struct {
53 // flatten_apex can be used to specify additional sources of file_contexts.
54 // Apex paths, /system/apex/{apex_name}, will be amended to the paths of file_contexts
55 // entries.
56 Flatten_apex struct {
Inseob Kim6d3d5a62021-12-21 20:55:32 +090057 Srcs []string `android:"path"`
Inseob Kimb554e592019-04-15 20:10:46 +090058 }
59}
60
61type selinuxContextsModule struct {
62 android.ModuleBase
63
64 properties selinuxContextsProperties
65 fileContextsProperties fileContextsProperties
Inseob Kimcd616492020-03-24 23:06:40 +090066 build func(ctx android.ModuleContext, inputs android.Paths) android.Path
67 deps func(ctx android.BottomUpMutatorContext)
68 outputPath android.Path
Colin Cross040f1512019-10-02 10:36:09 -070069 installPath android.InstallPath
Inseob Kimb554e592019-04-15 20:10:46 +090070}
71
72var (
Inseob Kimcd616492020-03-24 23:06:40 +090073 reuseContextsDepTag = dependencyTag{name: "reuseContexts"}
74 syspropLibraryDepTag = dependencyTag{name: "sysprop_library"}
Inseob Kimb554e592019-04-15 20:10:46 +090075)
76
77func init() {
78 pctx.HostBinToolVariable("fc_sort", "fc_sort")
79
80 android.RegisterModuleType("file_contexts", fileFactory)
81 android.RegisterModuleType("hwservice_contexts", hwServiceFactory)
82 android.RegisterModuleType("property_contexts", propertyFactory)
83 android.RegisterModuleType("service_contexts", serviceFactory)
Janis Danisevskisc40681f2020-07-25 13:02:29 -070084 android.RegisterModuleType("keystore2_key_contexts", keystoreKeyFactory)
Inseob Kimb554e592019-04-15 20:10:46 +090085}
86
Colin Cross040f1512019-10-02 10:36:09 -070087func (m *selinuxContextsModule) InstallInRoot() bool {
Inseob Kimfa6fe472021-01-12 13:40:27 +090088 return m.InRecovery()
89}
90
91func (m *selinuxContextsModule) InstallInRecovery() bool {
92 // ModuleBase.InRecovery() checks the image variant
93 return m.InRecovery()
94}
95
96func (m *selinuxContextsModule) onlyInRecovery() bool {
97 // ModuleBase.InstallInRecovery() checks commonProperties.Recovery property
98 return m.ModuleBase.InstallInRecovery()
Colin Cross040f1512019-10-02 10:36:09 -070099}
100
Inseob Kimcd616492020-03-24 23:06:40 +0900101func (m *selinuxContextsModule) DepsMutator(ctx android.BottomUpMutatorContext) {
102 if m.deps != nil {
103 m.deps(ctx)
104 }
Inseob Kimfa6fe472021-01-12 13:40:27 +0900105
106 if m.InRecovery() && !m.onlyInRecovery() {
107 ctx.AddFarVariationDependencies([]blueprint.Variation{
108 {Mutator: "image", Variation: android.CoreVariation},
109 }, reuseContextsDepTag, ctx.ModuleName())
110 }
Inseob Kimcd616492020-03-24 23:06:40 +0900111}
112
113func (m *selinuxContextsModule) propertyContextsDeps(ctx android.BottomUpMutatorContext) {
114 for _, lib := range sysprop.SyspropLibraries(ctx.Config()) {
115 ctx.AddFarVariationDependencies([]blueprint.Variation{}, syspropLibraryDepTag, lib)
116 }
117}
118
Yuntao Xu42e732c2021-11-18 22:33:02 +0000119func (m *selinuxContextsModule) stem() string {
120 return proptools.StringDefault(m.properties.Stem, m.Name())
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
Yuntao Xu42e732c2021-11-18 22:33:02 +0000136 ctx.InstallFile(m.installPath, m.stem(), m.outputPath)
Inseob Kimb554e592019-04-15 20:10:46 +0900137 return
138 }
139 }
140
Inseob Kim6d3d5a62021-12-21 20:55:32 +0900141 m.outputPath = m.build(ctx, android.PathsForModuleSrc(ctx, m.properties.Srcs))
Yuntao Xu42e732c2021-11-18 22:33:02 +0000142 ctx.InstallFile(m.installPath, m.stem(), m.outputPath)
Inseob Kimb554e592019-04-15 20:10:46 +0900143}
144
145func newModule() *selinuxContextsModule {
146 m := &selinuxContextsModule{}
147 m.AddProperties(
148 &m.properties,
Inseob Kim6d3d5a62021-12-21 20:55:32 +0900149 &m.fileContextsProperties,
Inseob Kimb554e592019-04-15 20:10:46 +0900150 )
151 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
152 android.AddLoadHook(m, func(ctx android.LoadHookContext) {
153 m.selinuxContextsHook(ctx)
154 })
155 return m
156}
157
158func (m *selinuxContextsModule) selinuxContextsHook(ctx android.LoadHookContext) {
159 // TODO: clean this up to use build/soong/android/variable.go after b/79249983
160 var srcs []string
161
Inseob Kimb554e592019-04-15 20:10:46 +0900162 for _, sanitize := range ctx.Config().SanitizeDevice() {
163 if sanitize == "address" {
164 srcs = append(srcs, m.properties.Product_variables.Address_sanitize.Srcs...)
165 break
166 }
167 }
168
169 m.properties.Srcs = append(m.properties.Srcs, srcs...)
170}
171
172func (m *selinuxContextsModule) AndroidMk() android.AndroidMkData {
Colin Crossf82aed02021-11-04 17:25:55 -0700173 nameSuffix := ""
174 if m.InRecovery() && !m.onlyInRecovery() {
175 nameSuffix = ".recovery"
176 }
Inseob Kimb554e592019-04-15 20:10:46 +0900177 return android.AndroidMkData{
Colin Crossf82aed02021-11-04 17:25:55 -0700178 Class: "ETC",
179 OutputFile: android.OptionalPathForPath(m.outputPath),
180 SubName: nameSuffix,
181 Extra: []android.AndroidMkExtraFunc{
182 func(w io.Writer, outputFile android.Path) {
Colin Cross6c7f9372022-01-11 19:35:43 -0800183 fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", m.installPath.String())
Yuntao Xu42e732c2021-11-18 22:33:02 +0000184 fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", m.stem())
Colin Crossf82aed02021-11-04 17:25:55 -0700185 },
Inseob Kimb554e592019-04-15 20:10:46 +0900186 },
187 }
188}
189
Inseob Kimfa6fe472021-01-12 13:40:27 +0900190func (m *selinuxContextsModule) ImageMutatorBegin(ctx android.BaseModuleContext) {
Yuntao Xu42e732c2021-11-18 22:33:02 +0000191 if proptools.Bool(m.properties.Recovery_available) && m.ModuleBase.InstallInRecovery() {
Inseob Kimfa6fe472021-01-12 13:40:27 +0900192 ctx.PropertyErrorf("recovery_available",
193 "doesn't make sense at the same time as `recovery: true`")
Inseob Kimb554e592019-04-15 20:10:46 +0900194 }
195}
196
Inseob Kimfa6fe472021-01-12 13:40:27 +0900197func (m *selinuxContextsModule) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
Yuntao Xu42e732c2021-11-18 22:33:02 +0000198 return !m.ModuleBase.InstallInRecovery()
Inseob Kimfa6fe472021-01-12 13:40:27 +0900199}
200
201func (m *selinuxContextsModule) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
202 return false
203}
204
205func (m *selinuxContextsModule) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
206 return false
207}
208
Inseob Kim6cc75f42021-04-29 13:53:20 +0000209func (m *selinuxContextsModule) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
210 return false
211}
212
Inseob Kimfa6fe472021-01-12 13:40:27 +0900213func (m *selinuxContextsModule) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
Yuntao Xu42e732c2021-11-18 22:33:02 +0000214 return m.ModuleBase.InstallInRecovery() || proptools.Bool(m.properties.Recovery_available)
Inseob Kimfa6fe472021-01-12 13:40:27 +0900215}
216
217func (m *selinuxContextsModule) ExtraImageVariations(ctx android.BaseModuleContext) []string {
218 return nil
219}
220
221func (m *selinuxContextsModule) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
222}
223
224var _ android.ImageInterface = (*selinuxContextsModule)(nil)
225
Inseob Kimcd616492020-03-24 23:06:40 +0900226func (m *selinuxContextsModule) buildGeneralContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
Yuntao Xu42e732c2021-11-18 22:33:02 +0000227 builtContext := android.PathForModuleGen(ctx, ctx.ModuleName()+"_m4out")
Inseob Kimb554e592019-04-15 20:10:46 +0900228
Colin Cross242c8bc2020-11-16 17:58:17 -0800229 rule := android.NewRuleBuilder(pctx, ctx)
Inseob Kimb554e592019-04-15 20:10:46 +0900230
231 rule.Command().
Dan Willemsen3c3e59b2019-06-19 10:52:50 -0700232 Tool(ctx.Config().PrebuiltBuildTool(ctx, "m4")).
233 Text("--fatal-warnings -s").
Inseob Kimb554e592019-04-15 20:10:46 +0900234 FlagForEachArg("-D", ctx.DeviceConfig().SepolicyM4Defs()).
235 Inputs(inputs).
Yuntao Xu42e732c2021-11-18 22:33:02 +0000236 FlagWithOutput("> ", builtContext)
Inseob Kimb554e592019-04-15 20:10:46 +0900237
238 if proptools.Bool(m.properties.Remove_comment) {
Yuntao Xu42e732c2021-11-18 22:33:02 +0000239 rule.Temporary(builtContext)
Inseob Kimb554e592019-04-15 20:10:46 +0900240
241 remove_comment_output := android.PathForModuleGen(ctx, ctx.ModuleName()+"_remove_comment")
242
243 rule.Command().
244 Text("sed -e 's/#.*$//' -e '/^$/d'").
Yuntao Xu42e732c2021-11-18 22:33:02 +0000245 Input(builtContext).
Inseob Kimb554e592019-04-15 20:10:46 +0900246 FlagWithOutput("> ", remove_comment_output)
247
Yuntao Xu42e732c2021-11-18 22:33:02 +0000248 builtContext = remove_comment_output
Inseob Kimb554e592019-04-15 20:10:46 +0900249 }
250
251 if proptools.Bool(m.properties.Fc_sort) {
Yuntao Xu42e732c2021-11-18 22:33:02 +0000252 rule.Temporary(builtContext)
Inseob Kimb554e592019-04-15 20:10:46 +0900253
254 sorted_output := android.PathForModuleGen(ctx, ctx.ModuleName()+"_sorted")
255
256 rule.Command().
257 Tool(ctx.Config().HostToolPath(ctx, "fc_sort")).
Yuntao Xu42e732c2021-11-18 22:33:02 +0000258 FlagWithInput("-i ", builtContext).
Inseob Kimb554e592019-04-15 20:10:46 +0900259 FlagWithOutput("-o ", sorted_output)
260
Yuntao Xu42e732c2021-11-18 22:33:02 +0000261 builtContext = sorted_output
Inseob Kimb554e592019-04-15 20:10:46 +0900262 }
263
Yuntao Xu42e732c2021-11-18 22:33:02 +0000264 ret := android.PathForModuleGen(ctx, m.stem())
265 rule.Temporary(builtContext)
266 rule.Command().Text("cp").Input(builtContext).Output(ret)
Inseob Kimb554e592019-04-15 20:10:46 +0900267
268 rule.DeleteTemporaryFiles()
Yuntao Xu42e732c2021-11-18 22:33:02 +0000269 rule.Build("selinux_contexts", "building contexts: "+m.Name())
Inseob Kimb554e592019-04-15 20:10:46 +0900270
Inseob Kimcd616492020-03-24 23:06:40 +0900271 return ret
Inseob Kimb554e592019-04-15 20:10:46 +0900272}
273
Inseob Kimcd616492020-03-24 23:06:40 +0900274func (m *selinuxContextsModule) buildFileContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
Inseob Kimb554e592019-04-15 20:10:46 +0900275 if m.properties.Fc_sort == nil {
276 m.properties.Fc_sort = proptools.BoolPtr(true)
277 }
278
Colin Cross242c8bc2020-11-16 17:58:17 -0800279 rule := android.NewRuleBuilder(pctx, ctx)
Inseob Kimb554e592019-04-15 20:10:46 +0900280
281 if ctx.Config().FlattenApex() {
Inseob Kim6d3d5a62021-12-21 20:55:32 +0900282 for _, path := range android.PathsForModuleSrc(ctx, m.fileContextsProperties.Flatten_apex.Srcs) {
283 out := android.PathForModuleGen(ctx, "flattened_apex", path.Rel())
284 apex_path := "/system/apex/" + strings.Replace(
285 strings.TrimSuffix(path.Base(), "-file_contexts"),
286 ".", "\\\\.", -1)
Inseob Kimb554e592019-04-15 20:10:46 +0900287
Inseob Kim6d3d5a62021-12-21 20:55:32 +0900288 rule.Command().
289 Text("awk '/object_r/{printf(\""+apex_path+"%s\\n\",$0)}'").
290 Input(path).
291 FlagWithOutput("> ", out)
Inseob Kimb554e592019-04-15 20:10:46 +0900292
Inseob Kim6d3d5a62021-12-21 20:55:32 +0900293 inputs = append(inputs, out)
Inseob Kimb554e592019-04-15 20:10:46 +0900294 }
295 }
296
Colin Cross242c8bc2020-11-16 17:58:17 -0800297 rule.Build(m.Name(), "flattened_apex_file_contexts")
Inseob Kimcd616492020-03-24 23:06:40 +0900298 return m.buildGeneralContexts(ctx, inputs)
Inseob Kimb554e592019-04-15 20:10:46 +0900299}
300
301func fileFactory() android.Module {
302 m := newModule()
Inseob Kimb554e592019-04-15 20:10:46 +0900303 m.build = m.buildFileContexts
304 return m
305}
306
Inseob Kimcd616492020-03-24 23:06:40 +0900307func (m *selinuxContextsModule) buildHwServiceContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
Inseob Kimb554e592019-04-15 20:10:46 +0900308 if m.properties.Remove_comment == nil {
309 m.properties.Remove_comment = proptools.BoolPtr(true)
310 }
311
Inseob Kimcd616492020-03-24 23:06:40 +0900312 return m.buildGeneralContexts(ctx, inputs)
313}
314
Inseob Kim2bcc0452020-12-21 13:16:44 +0900315func (m *selinuxContextsModule) checkVendorPropertyNamespace(ctx android.ModuleContext, inputs android.Paths) android.Paths {
316 shippingApiLevel := ctx.DeviceConfig().ShippingApiLevel()
317 ApiLevelR := android.ApiLevelOrPanic(ctx, "R")
318
319 rule := android.NewRuleBuilder(pctx, ctx)
320
321 // This list is from vts_treble_sys_prop_test.
322 allowedPropertyPrefixes := []string{
323 "ctl.odm.",
324 "ctl.vendor.",
325 "ctl.start$odm.",
326 "ctl.start$vendor.",
327 "ctl.stop$odm.",
328 "ctl.stop$vendor.",
329 "init.svc.odm.",
330 "init.svc.vendor.",
331 "ro.boot.",
332 "ro.hardware.",
333 "ro.odm.",
334 "ro.vendor.",
335 "odm.",
336 "persist.odm.",
337 "persist.vendor.",
338 "vendor.",
339 }
340
341 // persist.camera is also allowed for devices launching with R or eariler
342 if shippingApiLevel.LessThanOrEqualTo(ApiLevelR) {
343 allowedPropertyPrefixes = append(allowedPropertyPrefixes, "persist.camera.")
344 }
345
346 var allowedContextPrefixes []string
347
348 if shippingApiLevel.GreaterThanOrEqualTo(ApiLevelR) {
349 // This list is from vts_treble_sys_prop_test.
350 allowedContextPrefixes = []string{
351 "vendor_",
352 "odm_",
353 }
354 }
355
356 var ret android.Paths
357 for _, input := range inputs {
358 cmd := rule.Command().
359 BuiltTool("check_prop_prefix").
360 FlagWithInput("--property-contexts ", input).
361 FlagForEachArg("--allowed-property-prefix ", proptools.ShellEscapeList(allowedPropertyPrefixes)). // contains shell special character '$'
362 FlagForEachArg("--allowed-context-prefix ", allowedContextPrefixes)
363
364 if !ctx.DeviceConfig().BuildBrokenVendorPropertyNamespace() {
365 cmd.Flag("--strict")
366 }
367
368 out := android.PathForModuleGen(ctx, "namespace_checked").Join(ctx, input.String())
369 rule.Command().Text("cp -f").Input(input).Output(out)
370 ret = append(ret, out)
371 }
372 rule.Build("check_namespace", "checking namespace of "+ctx.ModuleName())
373 return ret
374}
375
Inseob Kimcd616492020-03-24 23:06:40 +0900376func (m *selinuxContextsModule) buildPropertyContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
Inseob Kim2bcc0452020-12-21 13:16:44 +0900377 // vendor/odm properties are enforced for devices launching with Android Q or later. So, if
378 // vendor/odm, make sure that only vendor/odm properties exist.
379 shippingApiLevel := ctx.DeviceConfig().ShippingApiLevel()
380 ApiLevelQ := android.ApiLevelOrPanic(ctx, "Q")
381 if (ctx.SocSpecific() || ctx.DeviceSpecific()) && shippingApiLevel.GreaterThanOrEqualTo(ApiLevelQ) {
382 inputs = m.checkVendorPropertyNamespace(ctx, inputs)
383 }
384
Inseob Kimcd616492020-03-24 23:06:40 +0900385 builtCtxFile := m.buildGeneralContexts(ctx, inputs)
386
387 var apiFiles android.Paths
388 ctx.VisitDirectDepsWithTag(syspropLibraryDepTag, func(c android.Module) {
Inseob Kim3a3539a2021-01-15 18:10:29 +0900389 i, ok := c.(interface{ CurrentSyspropApiFile() android.OptionalPath })
Inseob Kimcd616492020-03-24 23:06:40 +0900390 if !ok {
391 panic(fmt.Errorf("unknown dependency %q for %q", ctx.OtherModuleName(c), ctx.ModuleName()))
392 }
Inseob Kim3a3539a2021-01-15 18:10:29 +0900393 if api := i.CurrentSyspropApiFile(); api.Valid() {
394 apiFiles = append(apiFiles, api.Path())
395 }
Inseob Kimcd616492020-03-24 23:06:40 +0900396 })
397
398 // check compatibility with sysprop_library
399 if len(apiFiles) > 0 {
400 out := android.PathForModuleGen(ctx, ctx.ModuleName()+"_api_checked")
Colin Cross242c8bc2020-11-16 17:58:17 -0800401 rule := android.NewRuleBuilder(pctx, ctx)
Inseob Kimcd616492020-03-24 23:06:40 +0900402
403 msg := `\n******************************\n` +
404 `API of sysprop_library doesn't match with property_contexts\n` +
405 `Please fix the breakage and rebuild.\n` +
406 `******************************\n`
407
408 rule.Command().
409 Text("( ").
Colin Cross242c8bc2020-11-16 17:58:17 -0800410 BuiltTool("sysprop_type_checker").
Inseob Kimcd616492020-03-24 23:06:40 +0900411 FlagForEachInput("--api ", apiFiles).
412 FlagWithInput("--context ", builtCtxFile).
413 Text(" || ( echo").Flag("-e").
414 Flag(`"` + msg + `"`).
415 Text("; exit 38) )")
416
417 rule.Command().Text("cp -f").Input(builtCtxFile).Output(out)
Colin Cross242c8bc2020-11-16 17:58:17 -0800418 rule.Build("property_contexts_check_api", "checking API: "+m.Name())
Inseob Kimcd616492020-03-24 23:06:40 +0900419 builtCtxFile = out
420 }
421
422 return builtCtxFile
Inseob Kimb554e592019-04-15 20:10:46 +0900423}
424
425func hwServiceFactory() android.Module {
426 m := newModule()
427 m.build = m.buildHwServiceContexts
428 return m
429}
430
431func propertyFactory() android.Module {
432 m := newModule()
Inseob Kimcd616492020-03-24 23:06:40 +0900433 m.build = m.buildPropertyContexts
434 m.deps = m.propertyContextsDeps
Inseob Kimb554e592019-04-15 20:10:46 +0900435 return m
436}
437
438func serviceFactory() android.Module {
439 m := newModule()
440 m.build = m.buildGeneralContexts
441 return m
442}
Janis Danisevskisc40681f2020-07-25 13:02:29 -0700443
444func keystoreKeyFactory() android.Module {
445 m := newModule()
446 m.build = m.buildGeneralContexts
447 return m
448}
Yuntao Xu42e732c2021-11-18 22:33:02 +0000449
450var _ android.OutputFileProducer = (*selinuxContextsModule)(nil)
451
452// Implements android.OutputFileProducer
453func (m *selinuxContextsModule) OutputFiles(tag string) (android.Paths, error) {
454 if tag == "" {
455 return []android.Path{m.outputPath}, nil
456 }
457 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
458}