blob: ea04dc8f40acdefbef5d7102a752b668cba86f1a [file] [log] [blame]
Sam Mortimer3458e6a2019-10-07 11:41:14 -07001// Copyright (C) 2019 The LineageOS 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 android
16
17import (
18 "strings"
19)
20
21// Keys are bootjar name, value is whether or not
22// we've marked a module as being a provider for it.
23var jarMap map[string]bool
24
25func init() {
26 PreArchMutators(RegisterBootJarMutators)
27}
28
29// Note: registration function is structured this way so that it can be included
30// from soong module tests.
31func RegisterBootJarMutators(ctx RegisterMutatorsContext) {
32 // Note: can't use Parallel() since we touch global jarMap
33 ctx.TopDown("bootjar_exportednamespace", bootJarMutatorExportedNamespace)
34 ctx.TopDown("bootjar_anynamespace", bootJarMutatorAnyNamespace)
35}
36
37func mutatorInit(mctx TopDownMutatorContext) {
38 // Did we init already ?
39 if jarMap != nil {
40 return
41 }
42
43 jarMap = make(map[string]bool)
44 for _, moduleName := range mctx.Config().BootJars() {
45 jarMap[moduleName] = false
46 }
47}
48
49// Mark modules in soong exported namespace as providing a boot jar.
50func bootJarMutatorExportedNamespace(mctx TopDownMutatorContext) {
51 bootJarMutator(mctx, true)
52}
53
54// Mark modules in any namespace (incl root) as providing a boot jar.
55func bootJarMutatorAnyNamespace(mctx TopDownMutatorContext) {
56 bootJarMutator(mctx, false)
57}
58
59func bootJarMutator(mctx TopDownMutatorContext, requireExportedNamespace bool) {
60 mutatorInit(mctx)
61
62 module, ok := mctx.Module().(Module)
63 if !ok {
64 // Not a proper module
65 return
66 }
67
68 // Does this module produce a dex jar ?
69 if _, ok := module.(interface{ DexJar() Path }); !ok {
70 // No
71 return
72 }
73
74 // If jarMap is empty we must be running in a test so
75 // set boot jar provide to true for all modules.
76 if len(jarMap) == 0 {
77 module.base().commonProperties.BootJarProvider = true
78 return
79 }
80
81 name := mctx.ModuleName()
82 dir := mctx.ModuleDir()
83
84 // Special treatment for hiddenapi modules - create extra
85 // jarMap entries if needed.
86 baseName := strings.TrimSuffix(name, "-hiddenapi")
87 if name != baseName {
88 _, baseIsBootJar := jarMap[baseName]
89 _, alreadyExists := jarMap[name]
90 if baseIsBootJar && !alreadyExists {
91 // This is a hidden api module whose base name exists in the boot jar list
92 // and we've not visited it before. Create a map entry for it.
93 jarMap[name] = false
94 }
95 }
96
97 // Does this module match the name of a boot jar ?
98 if found, exists := jarMap[name]; !exists || found {
99 // No
100 return
101 }
102
103 if requireExportedNamespace {
104 for _, n := range mctx.Config().ExportedNamespaces() {
105 if strings.HasPrefix(dir, n) {
106 jarMap[name] = true
107 module.base().commonProperties.BootJarProvider = true
108 break
109 }
110 }
111 } else {
112 jarMap[name] = true
113 module.base().commonProperties.BootJarProvider = true
114 }
115
116 return
117}