blob: 78343db9039cca527ea076744af71c6f43b0f0bc [file] [log] [blame]
Colin Cross7228ecd2019-11-18 16:00:16 -08001// Copyright 2019 Google Inc. All rights reserved.
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
Cole Faustfa6e0fd2024-10-15 15:22:57 -070017type ImageInterfaceContext interface {
18 ArchModuleContext
19
20 Module() Module
21
22 ModuleErrorf(fmt string, args ...interface{})
23 PropertyErrorf(property, fmt string, args ...interface{})
24
25 DeviceSpecific() bool
26 SocSpecific() bool
27 ProductSpecific() bool
28 SystemExtSpecific() bool
29 Platform() bool
30
31 Config() Config
32}
33
Jihoon Kang5402bbd2024-07-31 18:37:49 +000034// ImageInterface is implemented by modules that need to be split by the imageTransitionMutator.
Colin Cross7228ecd2019-11-18 16:00:16 -080035type ImageInterface interface {
36 // ImageMutatorBegin is called before any other method in the ImageInterface.
Cole Faustfa6e0fd2024-10-15 15:22:57 -070037 ImageMutatorBegin(ctx ImageInterfaceContext)
Colin Cross7228ecd2019-11-18 16:00:16 -080038
Jihoon Kang47e91842024-06-19 00:51:16 +000039 // VendorVariantNeeded should return true if the module needs a vendor variant (installed on the vendor image).
Cole Faustfa6e0fd2024-10-15 15:22:57 -070040 VendorVariantNeeded(ctx ImageInterfaceContext) bool
Jihoon Kang47e91842024-06-19 00:51:16 +000041
Jihoon Kangc3d4e112024-06-24 22:16:27 +000042 // ProductVariantNeeded should return true if the module needs a product variant (installed on the product image).
Cole Faustfa6e0fd2024-10-15 15:22:57 -070043 ProductVariantNeeded(ctx ImageInterfaceContext) bool
Jihoon Kang47e91842024-06-19 00:51:16 +000044
Colin Cross7228ecd2019-11-18 16:00:16 -080045 // CoreVariantNeeded should return true if the module needs a core variant (installed on the system image).
Cole Faustfa6e0fd2024-10-15 15:22:57 -070046 CoreVariantNeeded(ctx ImageInterfaceContext) bool
Colin Cross7228ecd2019-11-18 16:00:16 -080047
Yifan Hong1b3348d2020-01-21 15:53:22 -080048 // RamdiskVariantNeeded should return true if the module needs a ramdisk variant (installed on the
49 // ramdisk partition).
Cole Faustfa6e0fd2024-10-15 15:22:57 -070050 RamdiskVariantNeeded(ctx ImageInterfaceContext) bool
Yifan Hong1b3348d2020-01-21 15:53:22 -080051
Yifan Hong60e0cfb2020-10-21 15:17:56 -070052 // VendorRamdiskVariantNeeded should return true if the module needs a vendor ramdisk variant (installed on the
53 // vendor ramdisk partition).
Cole Faustfa6e0fd2024-10-15 15:22:57 -070054 VendorRamdiskVariantNeeded(ctx ImageInterfaceContext) bool
Yifan Hong60e0cfb2020-10-21 15:17:56 -070055
Inseob Kim08758f02021-04-08 21:13:22 +090056 // DebugRamdiskVariantNeeded should return true if the module needs a debug ramdisk variant (installed on the
57 // debug ramdisk partition: $(PRODUCT_OUT)/debug_ramdisk).
Cole Faustfa6e0fd2024-10-15 15:22:57 -070058 DebugRamdiskVariantNeeded(ctx ImageInterfaceContext) bool
Inseob Kim08758f02021-04-08 21:13:22 +090059
Colin Cross7228ecd2019-11-18 16:00:16 -080060 // RecoveryVariantNeeded should return true if the module needs a recovery variant (installed on the
61 // recovery partition).
Cole Faustfa6e0fd2024-10-15 15:22:57 -070062 RecoveryVariantNeeded(ctx ImageInterfaceContext) bool
Colin Cross7228ecd2019-11-18 16:00:16 -080063
64 // ExtraImageVariations should return a list of the additional variations needed for the module. After the
65 // variants are created the SetImageVariation method will be called on each newly created variant with the
66 // its variation.
Cole Faustfa6e0fd2024-10-15 15:22:57 -070067 ExtraImageVariations(ctx ImageInterfaceContext) []string
Colin Cross7228ecd2019-11-18 16:00:16 -080068
Lukacs T. Berki2f5c3402021-06-15 11:27:56 +020069 // SetImageVariation is called for each newly created image variant. The receiver is the original
Jihoon Kang7583e832024-06-13 21:25:45 +000070 // module, "variation" is the name of the newly created variant. "variation" is set on the receiver.
Cole Faustfa6e0fd2024-10-15 15:22:57 -070071 SetImageVariation(ctx ImageInterfaceContext, variation string)
Colin Cross7228ecd2019-11-18 16:00:16 -080072}
73
74const (
Jihoon Kang47e91842024-06-19 00:51:16 +000075 // VendorVariation is the variant name used for /vendor code that does not
76 // compile against the VNDK.
77 VendorVariation string = "vendor"
78
79 // ProductVariation is the variant name used for /product code that does not
80 // compile against the VNDK.
81 ProductVariation string = "product"
82
Colin Cross7228ecd2019-11-18 16:00:16 -080083 // CoreVariation is the variant used for framework-private libraries, or
84 // SDK libraries. (which framework-private libraries can use), which
85 // will be installed to the system image.
Colin Cross7113d202019-11-20 16:39:12 -080086 CoreVariation string = ""
Colin Cross7228ecd2019-11-18 16:00:16 -080087
88 // RecoveryVariation means a module to be installed to recovery image.
89 RecoveryVariation string = "recovery"
Yifan Hong1b3348d2020-01-21 15:53:22 -080090
91 // RamdiskVariation means a module to be installed to ramdisk image.
92 RamdiskVariation string = "ramdisk"
Yifan Hong60e0cfb2020-10-21 15:17:56 -070093
94 // VendorRamdiskVariation means a module to be installed to vendor ramdisk image.
95 VendorRamdiskVariation string = "vendor_ramdisk"
Inseob Kim08758f02021-04-08 21:13:22 +090096
97 // DebugRamdiskVariation means a module to be installed to debug ramdisk image.
98 DebugRamdiskVariation string = "debug_ramdisk"
Colin Cross7228ecd2019-11-18 16:00:16 -080099)
100
Cole Faust5b7635d2024-10-28 13:01:12 -0700101type imageInterfaceContextAdapter struct {
102 IncomingTransitionContext
103 kind moduleKind
104}
105
106var _ ImageInterfaceContext = (*imageInterfaceContextAdapter)(nil)
107
108func (e *imageInterfaceContextAdapter) Platform() bool {
109 return e.kind == platformModule
110}
111
112func (e *imageInterfaceContextAdapter) DeviceSpecific() bool {
113 return e.kind == deviceSpecificModule
114}
115
116func (e *imageInterfaceContextAdapter) SocSpecific() bool {
117 return e.kind == socSpecificModule
118}
119
120func (e *imageInterfaceContextAdapter) ProductSpecific() bool {
121 return e.kind == productSpecificModule
122}
123
124func (e *imageInterfaceContextAdapter) SystemExtSpecific() bool {
125 return e.kind == systemExtSpecificModule
126}
127
Cole Faust6ec8d4a2024-10-29 11:01:19 -0700128// imageMutatorBeginMutator calls ImageMutatorBegin on all modules that may have image variants.
129// This happens right before the imageTransitionMutator runs. It's needed to initialize these
130// modules so that they return the correct results for all the other ImageInterface methods,
131// which the imageTransitionMutator will call. Transition mutators should also not mutate modules
132// (except in their Mutate() function), which this method does, so we run it in a separate mutator
133// first.
Cole Faust5b7635d2024-10-28 13:01:12 -0700134func imageMutatorBeginMutator(ctx BottomUpMutatorContext) {
135 if m, ok := ctx.Module().(ImageInterface); ok && ctx.Os() == Android {
136 m.ImageMutatorBegin(ctx)
137 }
138}
139
Jihoon Kang5402bbd2024-07-31 18:37:49 +0000140// imageTransitionMutator creates variants for modules that implement the ImageInterface that
Colin Cross7228ecd2019-11-18 16:00:16 -0800141// allow them to build differently for each partition (recovery, core, vendor, etc.).
Jihoon Kang5402bbd2024-07-31 18:37:49 +0000142type imageTransitionMutator struct{}
Colin Cross7228ecd2019-11-18 16:00:16 -0800143
Cole Faust5b7635d2024-10-28 13:01:12 -0700144func getImageVariations(ctx ImageInterfaceContext) []string {
Jihoon Kang5402bbd2024-07-31 18:37:49 +0000145 var variations []string
146
147 if m, ok := ctx.Module().(ImageInterface); ctx.Os() == Android && ok {
Colin Cross7228ecd2019-11-18 16:00:16 -0800148 if m.CoreVariantNeeded(ctx) {
149 variations = append(variations, CoreVariation)
150 }
Yifan Hong1b3348d2020-01-21 15:53:22 -0800151 if m.RamdiskVariantNeeded(ctx) {
152 variations = append(variations, RamdiskVariation)
153 }
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700154 if m.VendorRamdiskVariantNeeded(ctx) {
155 variations = append(variations, VendorRamdiskVariation)
156 }
Inseob Kim08758f02021-04-08 21:13:22 +0900157 if m.DebugRamdiskVariantNeeded(ctx) {
158 variations = append(variations, DebugRamdiskVariation)
159 }
Colin Cross7228ecd2019-11-18 16:00:16 -0800160 if m.RecoveryVariantNeeded(ctx) {
161 variations = append(variations, RecoveryVariation)
162 }
Jihoon Kang47e91842024-06-19 00:51:16 +0000163 if m.VendorVariantNeeded(ctx) {
164 variations = append(variations, VendorVariation)
165 }
166 if m.ProductVariantNeeded(ctx) {
167 variations = append(variations, ProductVariation)
168 }
Colin Cross7228ecd2019-11-18 16:00:16 -0800169
170 extraVariations := m.ExtraImageVariations(ctx)
171 variations = append(variations, extraVariations...)
Jihoon Kang5402bbd2024-07-31 18:37:49 +0000172 }
Colin Cross7228ecd2019-11-18 16:00:16 -0800173
Jihoon Kang5402bbd2024-07-31 18:37:49 +0000174 if len(variations) == 0 {
175 variations = append(variations, "")
176 }
Colin Cross7228ecd2019-11-18 16:00:16 -0800177
Jihoon Kang5402bbd2024-07-31 18:37:49 +0000178 return variations
179}
180
Cole Faust5b7635d2024-10-28 13:01:12 -0700181func (imageTransitionMutator) Split(ctx BaseModuleContext) []string {
182 return getImageVariations(ctx)
183}
184
Jihoon Kang5402bbd2024-07-31 18:37:49 +0000185func (imageTransitionMutator) OutgoingTransition(ctx OutgoingTransitionContext, sourceVariation string) string {
186 return sourceVariation
187}
188
189func (imageTransitionMutator) IncomingTransition(ctx IncomingTransitionContext, incomingVariation string) string {
190 if _, ok := ctx.Module().(ImageInterface); ctx.Os() != Android || !ok {
191 return CoreVariation
192 }
Cole Faust5b7635d2024-10-28 13:01:12 -0700193 variations := getImageVariations(&imageInterfaceContextAdapter{
194 IncomingTransitionContext: ctx,
195 kind: determineModuleKind(ctx.Module().base(), ctx),
196 })
197 // If there's only 1 possible variation, use that. This is a holdover from when blueprint,
198 // when adding dependencies, would use the only variant of a module regardless of its variations
199 // if only 1 variant existed.
200 if len(variations) == 1 {
201 return variations[0]
202 }
Jihoon Kang5402bbd2024-07-31 18:37:49 +0000203 return incomingVariation
204}
205
206func (imageTransitionMutator) Mutate(ctx BottomUpMutatorContext, variation string) {
207 ctx.Module().base().setImageVariation(variation)
208 if m, ok := ctx.Module().(ImageInterface); ok {
209 m.SetImageVariation(ctx, variation)
Colin Cross7228ecd2019-11-18 16:00:16 -0800210 }
211}