1// 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
17// ImageInterface is implemented by modules that need to be split by the imageMutator.
18type ImageInterface interface {
19	// ImageMutatorBegin is called before any other method in the ImageInterface.
20	ImageMutatorBegin(ctx BaseModuleContext)
21
22	// CoreVariantNeeded should return true if the module needs a core variant (installed on the system image).
23	CoreVariantNeeded(ctx BaseModuleContext) bool
24
25	// RamdiskVariantNeeded should return true if the module needs a ramdisk variant (installed on the
26	// ramdisk partition).
27	RamdiskVariantNeeded(ctx BaseModuleContext) bool
28
29	// VendorRamdiskVariantNeeded should return true if the module needs a vendor ramdisk variant (installed on the
30	// vendor ramdisk partition).
31	VendorRamdiskVariantNeeded(ctx BaseModuleContext) bool
32
33	// DebugRamdiskVariantNeeded should return true if the module needs a debug ramdisk variant (installed on the
34	// debug ramdisk partition: $(PRODUCT_OUT)/debug_ramdisk).
35	DebugRamdiskVariantNeeded(ctx BaseModuleContext) bool
36
37	// RecoveryVariantNeeded should return true if the module needs a recovery variant (installed on the
38	// recovery partition).
39	RecoveryVariantNeeded(ctx BaseModuleContext) bool
40
41	// ExtraImageVariations should return a list of the additional variations needed for the module.  After the
42	// variants are created the SetImageVariation method will be called on each newly created variant with the
43	// its variation.
44	ExtraImageVariations(ctx BaseModuleContext) []string
45
46	// SetImageVariation will be passed a newly created recovery variant of the module.  ModuleBase implements
47	// SetImageVariation, most module types will not need to override it, and those that do must call the
48	// overridden method.  Implementors of SetImageVariation must be careful to modify the module argument
49	// and not the receiver.
50	SetImageVariation(ctx BaseModuleContext, variation string, module Module)
51}
52
53const (
54	// CoreVariation is the variant used for framework-private libraries, or
55	// SDK libraries. (which framework-private libraries can use), which
56	// will be installed to the system image.
57	CoreVariation string = ""
58
59	// RecoveryVariation means a module to be installed to recovery image.
60	RecoveryVariation string = "recovery"
61
62	// RamdiskVariation means a module to be installed to ramdisk image.
63	RamdiskVariation string = "ramdisk"
64
65	// VendorRamdiskVariation means a module to be installed to vendor ramdisk image.
66	VendorRamdiskVariation string = "vendor_ramdisk"
67
68	// DebugRamdiskVariation means a module to be installed to debug ramdisk image.
69	DebugRamdiskVariation string = "debug_ramdisk"
70)
71
72// imageMutator creates variants for modules that implement the ImageInterface that
73// allow them to build differently for each partition (recovery, core, vendor, etc.).
74func imageMutator(ctx BottomUpMutatorContext) {
75	if ctx.Os() != Android {
76		return
77	}
78
79	if m, ok := ctx.Module().(ImageInterface); ok {
80		m.ImageMutatorBegin(ctx)
81
82		var variations []string
83
84		if m.CoreVariantNeeded(ctx) {
85			variations = append(variations, CoreVariation)
86		}
87		if m.RamdiskVariantNeeded(ctx) {
88			variations = append(variations, RamdiskVariation)
89		}
90		if m.VendorRamdiskVariantNeeded(ctx) {
91			variations = append(variations, VendorRamdiskVariation)
92		}
93		if m.DebugRamdiskVariantNeeded(ctx) {
94			variations = append(variations, DebugRamdiskVariation)
95		}
96		if m.RecoveryVariantNeeded(ctx) {
97			variations = append(variations, RecoveryVariation)
98		}
99
100		extraVariations := m.ExtraImageVariations(ctx)
101		variations = append(variations, extraVariations...)
102
103		if len(variations) == 0 {
104			return
105		}
106
107		mod := ctx.CreateVariations(variations...)
108		for i, v := range variations {
109			mod[i].base().setImageVariation(v)
110			m.SetImageVariation(ctx, v, mod[i])
111		}
112	}
113}
114