blob: b1840da76f5ce88e32690647249459a1e014a706 [file] [log] [blame]
Inseob Kim7e8bd1e2021-03-17 18:59:43 +09001// Copyright (C) 2021 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 "os"
Inseob Kim0a707fa2021-12-09 23:35:11 +090020 "sort"
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090021 "strconv"
Inseob Kim0a707fa2021-12-09 23:35:11 +090022 "strings"
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090023
24 "github.com/google/blueprint/proptools"
25
26 "android/soong/android"
27)
28
29const (
30 // TODO: sync with Android.mk
31 MlsSens = 1
32 MlsCats = 1024
33 PolicyVers = 30
34)
35
Inseob Kim0a707fa2021-12-09 23:35:11 +090036// This order should be kept. checkpolicy syntax requires it.
37var policyConfOrder = []string{
38 "security_classes",
39 "initial_sids",
40 "access_vectors",
41 "global_macros",
42 "neverallow_macros",
43 "mls_macros",
44 "mls_decl",
45 "mls",
46 "policy_capabilities",
47 "te_macros",
48 "attributes",
49 "ioctl_defines",
50 "ioctl_macros",
51 "*.te",
52 "roles_decl",
53 "roles",
54 "users",
55 "initial_sid_contexts",
56 "fs_use",
57 "genfs_contexts",
58 "port_contexts",
59}
60
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090061func init() {
62 android.RegisterModuleType("se_policy_conf", policyConfFactory)
Inseob Kimdf1a0de2021-03-17 19:05:02 +090063 android.RegisterModuleType("se_policy_cil", policyCilFactory)
Inseob Kimb9d05112021-09-27 13:13:46 +000064 android.RegisterModuleType("se_policy_binary", policyBinaryFactory)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090065}
66
67type policyConfProperties struct {
68 // Name of the output. Default is {module_name}
69 Stem *string
70
71 // Policy files to be compiled to cil file.
72 Srcs []string `android:"path"`
73
74 // Target build variant (user / userdebug / eng). Default follows the current lunch target
75 Build_variant *string
76
77 // Whether to exclude build test or not. Default is false
78 Exclude_build_test *bool
79
80 // Whether to include asan specific policies or not. Default follows the current lunch target
81 With_asan *bool
82
83 // Whether to build CTS specific policy or not. Default is false
84 Cts *bool
85
Inseob Kim5bbcd682021-12-28 14:57:03 +090086 // Whether to build recovery specific policy or not. Default is false
87 Target_recovery *bool
88
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090089 // Whether this module is directly installable to one of the partitions. Default is true
90 Installable *bool
Inseob Kim6e384f32022-03-10 13:15:05 +090091
92 // Desired number of MLS categories. Defaults to 1024
93 Mls_cats *int64
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090094}
95
96type policyConf struct {
97 android.ModuleBase
98
99 properties policyConfProperties
100
101 installSource android.Path
102 installPath android.InstallPath
103}
104
105// se_policy_conf merges collection of policy files into a policy.conf file to be processed by
106// checkpolicy.
107func policyConfFactory() android.Module {
108 c := &policyConf{}
109 c.AddProperties(&c.properties)
110 android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
111 return c
112}
113
114func (c *policyConf) installable() bool {
115 return proptools.BoolDefault(c.properties.Installable, true)
116}
117
118func (c *policyConf) stem() string {
119 return proptools.StringDefault(c.properties.Stem, c.Name())
120}
121
122func (c *policyConf) buildVariant(ctx android.ModuleContext) string {
123 if variant := proptools.String(c.properties.Build_variant); variant != "" {
124 return variant
125 }
126 if ctx.Config().Eng() {
127 return "eng"
128 }
129 if ctx.Config().Debuggable() {
130 return "userdebug"
131 }
132 return "user"
133}
134
135func (c *policyConf) cts() bool {
136 return proptools.Bool(c.properties.Cts)
137}
138
Inseob Kim5bbcd682021-12-28 14:57:03 +0900139func (c *policyConf) isTargetRecovery() bool {
140 return proptools.Bool(c.properties.Target_recovery)
141}
142
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900143func (c *policyConf) withAsan(ctx android.ModuleContext) string {
144 isAsanDevice := android.InList("address", ctx.Config().SanitizeDevice())
145 return strconv.FormatBool(proptools.BoolDefault(c.properties.With_asan, isAsanDevice))
146}
147
148func (c *policyConf) sepolicySplit(ctx android.ModuleContext) string {
149 if c.cts() {
150 return "cts"
151 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900152 if c.isTargetRecovery() {
153 return "false"
154 }
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900155 return strconv.FormatBool(ctx.DeviceConfig().SepolicySplit())
156}
157
158func (c *policyConf) compatibleProperty(ctx android.ModuleContext) string {
159 if c.cts() {
160 return "cts"
161 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900162 if c.isTargetRecovery() {
163 return "false"
164 }
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900165 return "true"
166}
167
168func (c *policyConf) trebleSyspropNeverallow(ctx android.ModuleContext) string {
169 if c.cts() {
170 return "cts"
171 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900172 if c.isTargetRecovery() {
173 return "false"
174 }
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900175 return strconv.FormatBool(!ctx.DeviceConfig().BuildBrokenTrebleSyspropNeverallow())
176}
177
178func (c *policyConf) enforceSyspropOwner(ctx android.ModuleContext) string {
179 if c.cts() {
180 return "cts"
181 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900182 if c.isTargetRecovery() {
183 return "false"
184 }
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900185 return strconv.FormatBool(!ctx.DeviceConfig().BuildBrokenEnforceSyspropOwner())
186}
187
Hridya Valsarajua885dd82021-04-26 16:32:17 -0700188func (c *policyConf) enforceDebugfsRestrictions(ctx android.ModuleContext) string {
189 if c.cts() {
190 return "cts"
191 }
192 return strconv.FormatBool(ctx.DeviceConfig().BuildDebugfsRestrictionsEnabled())
193}
194
Inseob Kim6e384f32022-03-10 13:15:05 +0900195func (c *policyConf) mlsCats() int {
196 return proptools.IntDefault(c.properties.Mls_cats, MlsCats)
197}
198
Inseob Kim0a707fa2021-12-09 23:35:11 +0900199func findPolicyConfOrder(name string) int {
200 for idx, pattern := range policyConfOrder {
201 if pattern == name || (pattern == "*.te" && strings.HasSuffix(name, ".te")) {
202 return idx
203 }
204 }
205 // name is not matched
206 return len(policyConfOrder)
207}
208
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900209func (c *policyConf) transformPolicyToConf(ctx android.ModuleContext) android.OutputPath {
Inseob Kim6c5fa542022-02-09 23:27:04 +0900210 conf := android.PathForModuleOut(ctx, c.stem()).OutputPath
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900211 rule := android.NewRuleBuilder(pctx, ctx)
Inseob Kim0a707fa2021-12-09 23:35:11 +0900212
213 srcs := android.PathsForModuleSrc(ctx, c.properties.Srcs)
214 sort.SliceStable(srcs, func(x, y int) bool {
215 return findPolicyConfOrder(srcs[x].Base()) < findPolicyConfOrder(srcs[y].Base())
216 })
217
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900218 rule.Command().Tool(ctx.Config().PrebuiltBuildTool(ctx, "m4")).
219 Flag("--fatal-warnings").
220 FlagForEachArg("-D ", ctx.DeviceConfig().SepolicyM4Defs()).
221 FlagWithArg("-D mls_num_sens=", strconv.Itoa(MlsSens)).
Inseob Kim6e384f32022-03-10 13:15:05 +0900222 FlagWithArg("-D mls_num_cats=", strconv.Itoa(c.mlsCats())).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900223 FlagWithArg("-D target_arch=", ctx.DeviceConfig().DeviceArch()).
224 FlagWithArg("-D target_with_asan=", c.withAsan(ctx)).
Inseob Kim4360c192021-03-23 20:52:53 +0900225 FlagWithArg("-D target_with_dexpreopt=", strconv.FormatBool(ctx.DeviceConfig().WithDexpreopt())).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900226 FlagWithArg("-D target_with_native_coverage=", strconv.FormatBool(ctx.DeviceConfig().ClangCoverageEnabled() || ctx.DeviceConfig().GcovCoverageEnabled())).
227 FlagWithArg("-D target_build_variant=", c.buildVariant(ctx)).
228 FlagWithArg("-D target_full_treble=", c.sepolicySplit(ctx)).
229 FlagWithArg("-D target_compatible_property=", c.compatibleProperty(ctx)).
230 FlagWithArg("-D target_treble_sysprop_neverallow=", c.trebleSyspropNeverallow(ctx)).
231 FlagWithArg("-D target_enforce_sysprop_owner=", c.enforceSyspropOwner(ctx)).
232 FlagWithArg("-D target_exclude_build_test=", strconv.FormatBool(proptools.Bool(c.properties.Exclude_build_test))).
233 FlagWithArg("-D target_requires_insecure_execmem_for_swiftshader=", strconv.FormatBool(ctx.DeviceConfig().RequiresInsecureExecmemForSwiftshader())).
Hridya Valsarajua885dd82021-04-26 16:32:17 -0700234 FlagWithArg("-D target_enforce_debugfs_restriction=", c.enforceDebugfsRestrictions(ctx)).
Inseob Kim5bbcd682021-12-28 14:57:03 +0900235 FlagWithArg("-D target_recovery=", strconv.FormatBool(c.isTargetRecovery())).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900236 Flag("-s").
Inseob Kim0a707fa2021-12-09 23:35:11 +0900237 Inputs(srcs).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900238 Text("> ").Output(conf)
239
240 rule.Build("conf", "Transform policy to conf: "+ctx.ModuleName())
241 return conf
242}
243
244func (c *policyConf) DepsMutator(ctx android.BottomUpMutatorContext) {
245 // do nothing
246}
247
248func (c *policyConf) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900249 if !c.installable() {
250 c.SkipInstall()
251 }
Inseob Kim31db2742021-06-08 10:31:09 +0900252
253 c.installSource = c.transformPolicyToConf(ctx)
254 c.installPath = android.PathForModuleInstall(ctx, "etc")
255 ctx.InstallFile(c.installPath, c.stem(), c.installSource)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900256}
257
258func (c *policyConf) AndroidMkEntries() []android.AndroidMkEntries {
259 return []android.AndroidMkEntries{android.AndroidMkEntries{
260 OutputFile: android.OptionalPathForPath(c.installSource),
261 Class: "ETC",
262 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
263 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
264 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !c.installable())
Colin Cross6c7f9372022-01-11 19:35:43 -0800265 entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900266 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
267 },
268 },
269 }}
270}
271
272func (c *policyConf) OutputFiles(tag string) (android.Paths, error) {
273 if tag == "" {
274 return android.Paths{c.installSource}, nil
275 }
276 return nil, fmt.Errorf("Unknown tag %q", tag)
277}
278
279var _ android.OutputFileProducer = (*policyConf)(nil)
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900280
281type policyCilProperties struct {
282 // Name of the output. Default is {module_name}
283 Stem *string
284
285 // Policy file to be compiled to cil file.
286 Src *string `android:"path"`
287
288 // Additional cil files to be added in the end of the output. This is to support workarounds
289 // which are not supported by the policy language.
290 Additional_cil_files []string `android:"path"`
291
292 // Cil files to be filtered out by the filter_out tool of "build_sepolicy". Used to build
293 // exported policies
294 Filter_out []string `android:"path"`
295
296 // Whether to remove line markers (denoted by ;;) out of compiled cil files. Defaults to false
297 Remove_line_marker *bool
298
299 // Whether to run secilc to check compiled policy or not. Defaults to true
300 Secilc_check *bool
301
302 // Whether to ignore neverallow when running secilc check. Defaults to
303 // SELINUX_IGNORE_NEVERALLOWS.
304 Ignore_neverallow *bool
305
306 // Whether this module is directly installable to one of the partitions. Default is true
307 Installable *bool
308}
309
310type policyCil struct {
311 android.ModuleBase
312
313 properties policyCilProperties
314
315 installSource android.Path
316 installPath android.InstallPath
317}
318
319// se_policy_cil compiles a policy.conf file to a cil file with checkpolicy, and optionally runs
320// secilc to check the output cil file. Affected by SELINUX_IGNORE_NEVERALLOWS.
321func policyCilFactory() android.Module {
322 c := &policyCil{}
323 c.AddProperties(&c.properties)
324 android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
325 return c
326}
327
328func (c *policyCil) Installable() bool {
329 return proptools.BoolDefault(c.properties.Installable, true)
330}
331
332func (c *policyCil) stem() string {
333 return proptools.StringDefault(c.properties.Stem, c.Name())
334}
335
336func (c *policyCil) compileConfToCil(ctx android.ModuleContext, conf android.Path) android.OutputPath {
337 cil := android.PathForModuleOut(ctx, c.stem()).OutputPath
338 rule := android.NewRuleBuilder(pctx, ctx)
339 rule.Command().BuiltTool("checkpolicy").
340 Flag("-C"). // Write CIL
341 Flag("-M"). // Enable MLS
342 FlagWithArg("-c ", strconv.Itoa(PolicyVers)).
343 FlagWithOutput("-o ", cil).
344 Input(conf)
345
346 if len(c.properties.Additional_cil_files) > 0 {
347 rule.Command().Text("cat").
348 Inputs(android.PathsForModuleSrc(ctx, c.properties.Additional_cil_files)).
349 Text(">> ").Output(cil)
350 }
351
352 if len(c.properties.Filter_out) > 0 {
353 rule.Command().BuiltTool("build_sepolicy").
354 Text("filter_out").
355 Flag("-f").
356 Inputs(android.PathsForModuleSrc(ctx, c.properties.Filter_out)).
357 FlagWithOutput("-t ", cil)
358 }
359
360 if proptools.Bool(c.properties.Remove_line_marker) {
361 rule.Command().Text("grep -v").
362 Text(proptools.ShellEscape(";;")).
363 Text(cil.String()).
364 Text(">").
365 Text(cil.String() + ".tmp").
366 Text("&& mv").
367 Text(cil.String() + ".tmp").
368 Text(cil.String())
369 }
370
371 if proptools.BoolDefault(c.properties.Secilc_check, true) {
372 secilcCmd := rule.Command().BuiltTool("secilc").
373 Flag("-m"). // Multiple decls
374 FlagWithArg("-M ", "true"). // Enable MLS
375 Flag("-G"). // expand and remove auto generated attributes
376 FlagWithArg("-c ", strconv.Itoa(PolicyVers)).
377 Inputs(android.PathsForModuleSrc(ctx, c.properties.Filter_out)). // Also add cil files which are filtered out
378 Text(cil.String()).
379 FlagWithArg("-o ", os.DevNull).
380 FlagWithArg("-f ", os.DevNull)
381
382 if proptools.BoolDefault(c.properties.Ignore_neverallow, ctx.Config().SelinuxIgnoreNeverallows()) {
383 secilcCmd.Flag("-N")
384 }
385 }
386
387 rule.Build("cil", "Building cil for "+ctx.ModuleName())
388 return cil
389}
390
391func (c *policyCil) GenerateAndroidBuildActions(ctx android.ModuleContext) {
392 if proptools.String(c.properties.Src) == "" {
393 ctx.PropertyErrorf("src", "must be specified")
394 return
395 }
396 conf := android.PathForModuleSrc(ctx, *c.properties.Src)
397 cil := c.compileConfToCil(ctx, conf)
398
Inseob Kim31db2742021-06-08 10:31:09 +0900399 if !c.Installable() {
400 c.SkipInstall()
401 }
402
Inseob Kim6cc75f42021-04-29 13:53:20 +0000403 if c.InstallInDebugRamdisk() {
404 // for userdebug_plat_sepolicy.cil
405 c.installPath = android.PathForModuleInstall(ctx)
406 } else {
407 c.installPath = android.PathForModuleInstall(ctx, "etc", "selinux")
408 }
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900409 c.installSource = cil
410 ctx.InstallFile(c.installPath, c.stem(), c.installSource)
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900411}
412
413func (c *policyCil) AndroidMkEntries() []android.AndroidMkEntries {
414 return []android.AndroidMkEntries{android.AndroidMkEntries{
415 OutputFile: android.OptionalPathForPath(c.installSource),
416 Class: "ETC",
417 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
418 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
419 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !c.Installable())
Colin Cross6c7f9372022-01-11 19:35:43 -0800420 entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900421 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
422 },
423 },
424 }}
425}
426
427func (c *policyCil) OutputFiles(tag string) (android.Paths, error) {
428 if tag == "" {
429 return android.Paths{c.installSource}, nil
430 }
431 return nil, fmt.Errorf("Unknown tag %q", tag)
432}
433
434var _ android.OutputFileProducer = (*policyCil)(nil)
Inseob Kimb9d05112021-09-27 13:13:46 +0000435
436type policyBinaryProperties struct {
437 // Name of the output. Default is {module_name}
438 Stem *string
439
440 // Cil files to be compiled.
441 Srcs []string `android:"path"`
442
443 // Whether to ignore neverallow when running secilc check. Defaults to
444 // SELINUX_IGNORE_NEVERALLOWS.
445 Ignore_neverallow *bool
446
447 // Whether this module is directly installable to one of the partitions. Default is true
448 Installable *bool
449}
450
451type policyBinary struct {
452 android.ModuleBase
453
454 properties policyBinaryProperties
455
456 installSource android.Path
457 installPath android.InstallPath
458}
459
460// se_policy_binary compiles cil files to a binary sepolicy file with secilc. Usually sources of
461// se_policy_binary come from outputs of se_policy_cil modules.
462func policyBinaryFactory() android.Module {
463 c := &policyBinary{}
464 c.AddProperties(&c.properties)
465 android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
466 return c
467}
468
Inseob Kim5bbcd682021-12-28 14:57:03 +0900469func (c *policyBinary) InstallInRoot() bool {
470 return c.InstallInRecovery()
471}
472
Inseob Kimb9d05112021-09-27 13:13:46 +0000473func (c *policyBinary) Installable() bool {
474 return proptools.BoolDefault(c.properties.Installable, true)
475}
476
477func (c *policyBinary) stem() string {
478 return proptools.StringDefault(c.properties.Stem, c.Name())
479}
480
481func (c *policyBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
482 if len(c.properties.Srcs) == 0 {
483 ctx.PropertyErrorf("srcs", "must be specified")
484 return
485 }
Inseob Kim3d5f9252021-12-21 20:42:35 +0900486 bin := android.PathForModuleOut(ctx, c.stem()+"_policy")
Inseob Kimb9d05112021-09-27 13:13:46 +0000487 rule := android.NewRuleBuilder(pctx, ctx)
488 secilcCmd := rule.Command().BuiltTool("secilc").
489 Flag("-m"). // Multiple decls
490 FlagWithArg("-M ", "true"). // Enable MLS
491 Flag("-G"). // expand and remove auto generated attributes
492 FlagWithArg("-c ", strconv.Itoa(PolicyVers)).
493 Inputs(android.PathsForModuleSrc(ctx, c.properties.Srcs)).
494 FlagWithOutput("-o ", bin).
495 FlagWithArg("-f ", os.DevNull)
496
497 if proptools.BoolDefault(c.properties.Ignore_neverallow, ctx.Config().SelinuxIgnoreNeverallows()) {
498 secilcCmd.Flag("-N")
499 }
Inseob Kim3d5f9252021-12-21 20:42:35 +0900500 rule.Temporary(bin)
Inseob Kimb9d05112021-09-27 13:13:46 +0000501
Inseob Kim3d5f9252021-12-21 20:42:35 +0900502 // permissive check is performed only in user build (not debuggable).
503 if !ctx.Config().Debuggable() {
504 permissiveDomains := android.PathForModuleOut(ctx, c.stem()+"_permissive")
505 rule.Command().BuiltTool("sepolicy-analyze").
506 Input(bin).
507 Text("permissive").
508 Text(" > ").
509 Output(permissiveDomains)
510 rule.Temporary(permissiveDomains)
511
512 msg := `==========\n` +
513 `ERROR: permissive domains not allowed in user builds\n` +
514 `List of invalid domains:`
515
516 rule.Command().Text("if test").
517 FlagWithInput("-s ", permissiveDomains).
518 Text("; then echo").
519 Flag("-e").
520 Text(`"` + msg + `"`).
521 Text("&& cat ").
522 Input(permissiveDomains).
523 Text("; exit 1; fi")
524 }
525
526 out := android.PathForModuleOut(ctx, c.stem())
527 rule.Command().Text("cp").
528 Flag("-f").
529 Input(bin).
530 Output(out)
531
532 rule.DeleteTemporaryFiles()
Inseob Kimb9d05112021-09-27 13:13:46 +0000533 rule.Build("secilc", "Compiling cil files for "+ctx.ModuleName())
534
535 if !c.Installable() {
536 c.SkipInstall()
537 }
538
Inseob Kim5bbcd682021-12-28 14:57:03 +0900539 if c.InstallInRecovery() {
540 // install in root
541 c.installPath = android.PathForModuleInstall(ctx)
542 } else {
543 c.installPath = android.PathForModuleInstall(ctx, "etc", "selinux")
544 }
Inseob Kim3d5f9252021-12-21 20:42:35 +0900545 c.installSource = out
Inseob Kimb9d05112021-09-27 13:13:46 +0000546 ctx.InstallFile(c.installPath, c.stem(), c.installSource)
547}
548
549func (c *policyBinary) AndroidMkEntries() []android.AndroidMkEntries {
550 return []android.AndroidMkEntries{android.AndroidMkEntries{
551 OutputFile: android.OptionalPathForPath(c.installSource),
552 Class: "ETC",
553 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
554 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
555 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !c.Installable())
Colin Cross6c7f9372022-01-11 19:35:43 -0800556 entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
Inseob Kimb9d05112021-09-27 13:13:46 +0000557 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
558 },
559 },
560 }}
561}
562
563func (c *policyBinary) OutputFiles(tag string) (android.Paths, error) {
564 if tag == "" {
565 return android.Paths{c.installSource}, nil
566 }
567 return nil, fmt.Errorf("Unknown tag %q", tag)
568}
569
570var _ android.OutputFileProducer = (*policyBinary)(nil)