xref: /aosp_15_r20/build/soong/android/configured_jars.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2022 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage android
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"encoding/json"
19*333d2b36SAndroid Build Coastguard Worker	"errors"
20*333d2b36SAndroid Build Coastguard Worker	"fmt"
21*333d2b36SAndroid Build Coastguard Worker	"path/filepath"
22*333d2b36SAndroid Build Coastguard Worker	"strings"
23*333d2b36SAndroid Build Coastguard Worker)
24*333d2b36SAndroid Build Coastguard Worker
25*333d2b36SAndroid Build Coastguard Worker// The ConfiguredJarList struct provides methods for handling a list of (apex, jar) pairs.
26*333d2b36SAndroid Build Coastguard Worker// Such lists are used in the build system for things like bootclasspath jars or system server jars.
27*333d2b36SAndroid Build Coastguard Worker// The apex part is either an apex name, or a special names "platform" or "system_ext". Jar is a
28*333d2b36SAndroid Build Coastguard Worker// module name. The pairs come from Make product variables as a list of colon-separated strings.
29*333d2b36SAndroid Build Coastguard Worker//
30*333d2b36SAndroid Build Coastguard Worker// Examples:
31*333d2b36SAndroid Build Coastguard Worker//   - "com.android.art:core-oj"
32*333d2b36SAndroid Build Coastguard Worker//   - "platform:framework"
33*333d2b36SAndroid Build Coastguard Worker//   - "system_ext:foo"
34*333d2b36SAndroid Build Coastguard Workertype ConfiguredJarList struct {
35*333d2b36SAndroid Build Coastguard Worker	// A list of apex components, which can be an apex name,
36*333d2b36SAndroid Build Coastguard Worker	// or special names like "platform" or "system_ext".
37*333d2b36SAndroid Build Coastguard Worker	apexes []string
38*333d2b36SAndroid Build Coastguard Worker
39*333d2b36SAndroid Build Coastguard Worker	// A list of jar module name components.
40*333d2b36SAndroid Build Coastguard Worker	jars []string
41*333d2b36SAndroid Build Coastguard Worker}
42*333d2b36SAndroid Build Coastguard Worker
43*333d2b36SAndroid Build Coastguard Worker// Len returns the length of the list of jars.
44*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) Len() int {
45*333d2b36SAndroid Build Coastguard Worker	return len(l.jars)
46*333d2b36SAndroid Build Coastguard Worker}
47*333d2b36SAndroid Build Coastguard Worker
48*333d2b36SAndroid Build Coastguard Worker// Jar returns the idx-th jar component of (apex, jar) pairs.
49*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) Jar(idx int) string {
50*333d2b36SAndroid Build Coastguard Worker	return l.jars[idx]
51*333d2b36SAndroid Build Coastguard Worker}
52*333d2b36SAndroid Build Coastguard Worker
53*333d2b36SAndroid Build Coastguard Worker// Apex returns the idx-th apex component of (apex, jar) pairs.
54*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) Apex(idx int) string {
55*333d2b36SAndroid Build Coastguard Worker	return l.apexes[idx]
56*333d2b36SAndroid Build Coastguard Worker}
57*333d2b36SAndroid Build Coastguard Worker
58*333d2b36SAndroid Build Coastguard Worker// ContainsJar returns true if the (apex, jar) pairs contains a pair with the
59*333d2b36SAndroid Build Coastguard Worker// given jar module name.
60*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) ContainsJar(jar string) bool {
61*333d2b36SAndroid Build Coastguard Worker	return InList(jar, l.jars)
62*333d2b36SAndroid Build Coastguard Worker}
63*333d2b36SAndroid Build Coastguard Worker
64*333d2b36SAndroid Build Coastguard Worker// If the list contains the given (apex, jar) pair.
65*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) containsApexJarPair(apex, jar string) bool {
66*333d2b36SAndroid Build Coastguard Worker	for i := 0; i < l.Len(); i++ {
67*333d2b36SAndroid Build Coastguard Worker		if apex == l.apexes[i] && jar == l.jars[i] {
68*333d2b36SAndroid Build Coastguard Worker			return true
69*333d2b36SAndroid Build Coastguard Worker		}
70*333d2b36SAndroid Build Coastguard Worker	}
71*333d2b36SAndroid Build Coastguard Worker	return false
72*333d2b36SAndroid Build Coastguard Worker}
73*333d2b36SAndroid Build Coastguard Worker
74*333d2b36SAndroid Build Coastguard Worker// ApexOfJar returns the apex component of the first pair with the given jar name on the list, or
75*333d2b36SAndroid Build Coastguard Worker// an empty string if not found.
76*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) ApexOfJar(jar string) string {
77*333d2b36SAndroid Build Coastguard Worker	if idx := IndexList(jar, l.jars); idx != -1 {
78*333d2b36SAndroid Build Coastguard Worker		return l.Apex(IndexList(jar, l.jars))
79*333d2b36SAndroid Build Coastguard Worker	}
80*333d2b36SAndroid Build Coastguard Worker	return ""
81*333d2b36SAndroid Build Coastguard Worker}
82*333d2b36SAndroid Build Coastguard Worker
83*333d2b36SAndroid Build Coastguard Worker// IndexOfJar returns the first pair with the given jar name on the list, or -1
84*333d2b36SAndroid Build Coastguard Worker// if not found.
85*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) IndexOfJar(jar string) int {
86*333d2b36SAndroid Build Coastguard Worker	return IndexList(jar, l.jars)
87*333d2b36SAndroid Build Coastguard Worker}
88*333d2b36SAndroid Build Coastguard Worker
89*333d2b36SAndroid Build Coastguard Workerfunc copyAndAppend(list []string, item string) []string {
90*333d2b36SAndroid Build Coastguard Worker	// Create the result list to be 1 longer than the input.
91*333d2b36SAndroid Build Coastguard Worker	result := make([]string, len(list)+1)
92*333d2b36SAndroid Build Coastguard Worker
93*333d2b36SAndroid Build Coastguard Worker	// Copy the whole input list into the result.
94*333d2b36SAndroid Build Coastguard Worker	count := copy(result, list)
95*333d2b36SAndroid Build Coastguard Worker
96*333d2b36SAndroid Build Coastguard Worker	// Insert the extra item at the end.
97*333d2b36SAndroid Build Coastguard Worker	result[count] = item
98*333d2b36SAndroid Build Coastguard Worker
99*333d2b36SAndroid Build Coastguard Worker	return result
100*333d2b36SAndroid Build Coastguard Worker}
101*333d2b36SAndroid Build Coastguard Worker
102*333d2b36SAndroid Build Coastguard Worker// Append an (apex, jar) pair to the list.
103*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) Append(apex string, jar string) ConfiguredJarList {
104*333d2b36SAndroid Build Coastguard Worker	// Create a copy of the backing arrays before appending to avoid sharing backing
105*333d2b36SAndroid Build Coastguard Worker	// arrays that are mutated across instances.
106*333d2b36SAndroid Build Coastguard Worker	apexes := copyAndAppend(l.apexes, apex)
107*333d2b36SAndroid Build Coastguard Worker	jars := copyAndAppend(l.jars, jar)
108*333d2b36SAndroid Build Coastguard Worker
109*333d2b36SAndroid Build Coastguard Worker	return ConfiguredJarList{apexes, jars}
110*333d2b36SAndroid Build Coastguard Worker}
111*333d2b36SAndroid Build Coastguard Worker
112*333d2b36SAndroid Build Coastguard Worker// Append a list of (apex, jar) pairs to the list.
113*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) AppendList(other *ConfiguredJarList) ConfiguredJarList {
114*333d2b36SAndroid Build Coastguard Worker	apexes := make([]string, 0, l.Len()+other.Len())
115*333d2b36SAndroid Build Coastguard Worker	jars := make([]string, 0, l.Len()+other.Len())
116*333d2b36SAndroid Build Coastguard Worker
117*333d2b36SAndroid Build Coastguard Worker	apexes = append(apexes, l.apexes...)
118*333d2b36SAndroid Build Coastguard Worker	jars = append(jars, l.jars...)
119*333d2b36SAndroid Build Coastguard Worker
120*333d2b36SAndroid Build Coastguard Worker	apexes = append(apexes, other.apexes...)
121*333d2b36SAndroid Build Coastguard Worker	jars = append(jars, other.jars...)
122*333d2b36SAndroid Build Coastguard Worker
123*333d2b36SAndroid Build Coastguard Worker	return ConfiguredJarList{apexes, jars}
124*333d2b36SAndroid Build Coastguard Worker}
125*333d2b36SAndroid Build Coastguard Worker
126*333d2b36SAndroid Build Coastguard Worker// RemoveList filters out a list of (apex, jar) pairs from the receiving list of pairs.
127*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList {
128*333d2b36SAndroid Build Coastguard Worker	apexes := make([]string, 0, l.Len())
129*333d2b36SAndroid Build Coastguard Worker	jars := make([]string, 0, l.Len())
130*333d2b36SAndroid Build Coastguard Worker
131*333d2b36SAndroid Build Coastguard Worker	for i, jar := range l.jars {
132*333d2b36SAndroid Build Coastguard Worker		apex := l.apexes[i]
133*333d2b36SAndroid Build Coastguard Worker		if !list.containsApexJarPair(apex, jar) {
134*333d2b36SAndroid Build Coastguard Worker			apexes = append(apexes, apex)
135*333d2b36SAndroid Build Coastguard Worker			jars = append(jars, jar)
136*333d2b36SAndroid Build Coastguard Worker		}
137*333d2b36SAndroid Build Coastguard Worker	}
138*333d2b36SAndroid Build Coastguard Worker
139*333d2b36SAndroid Build Coastguard Worker	return ConfiguredJarList{apexes, jars}
140*333d2b36SAndroid Build Coastguard Worker}
141*333d2b36SAndroid Build Coastguard Worker
142*333d2b36SAndroid Build Coastguard Worker// Filter keeps the entries if a jar appears in the given list of jars to keep. Returns a new list
143*333d2b36SAndroid Build Coastguard Worker// and any remaining jars that are not on this list.
144*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) Filter(jarsToKeep []string) (ConfiguredJarList, []string) {
145*333d2b36SAndroid Build Coastguard Worker	var apexes []string
146*333d2b36SAndroid Build Coastguard Worker	var jars []string
147*333d2b36SAndroid Build Coastguard Worker
148*333d2b36SAndroid Build Coastguard Worker	for i, jar := range l.jars {
149*333d2b36SAndroid Build Coastguard Worker		if InList(jar, jarsToKeep) {
150*333d2b36SAndroid Build Coastguard Worker			apexes = append(apexes, l.apexes[i])
151*333d2b36SAndroid Build Coastguard Worker			jars = append(jars, jar)
152*333d2b36SAndroid Build Coastguard Worker		}
153*333d2b36SAndroid Build Coastguard Worker	}
154*333d2b36SAndroid Build Coastguard Worker
155*333d2b36SAndroid Build Coastguard Worker	return ConfiguredJarList{apexes, jars}, RemoveListFromList(jarsToKeep, jars)
156*333d2b36SAndroid Build Coastguard Worker}
157*333d2b36SAndroid Build Coastguard Worker
158*333d2b36SAndroid Build Coastguard Worker// CopyOfJars returns a copy of the list of strings containing jar module name
159*333d2b36SAndroid Build Coastguard Worker// components.
160*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) CopyOfJars() []string {
161*333d2b36SAndroid Build Coastguard Worker	return CopyOf(l.jars)
162*333d2b36SAndroid Build Coastguard Worker}
163*333d2b36SAndroid Build Coastguard Worker
164*333d2b36SAndroid Build Coastguard Worker// CopyOfApexJarPairs returns a copy of the list of strings with colon-separated
165*333d2b36SAndroid Build Coastguard Worker// (apex, jar) pairs.
166*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) CopyOfApexJarPairs() []string {
167*333d2b36SAndroid Build Coastguard Worker	pairs := make([]string, 0, l.Len())
168*333d2b36SAndroid Build Coastguard Worker
169*333d2b36SAndroid Build Coastguard Worker	for i, jar := range l.jars {
170*333d2b36SAndroid Build Coastguard Worker		apex := l.apexes[i]
171*333d2b36SAndroid Build Coastguard Worker		pairs = append(pairs, apex+":"+jar)
172*333d2b36SAndroid Build Coastguard Worker	}
173*333d2b36SAndroid Build Coastguard Worker
174*333d2b36SAndroid Build Coastguard Worker	return pairs
175*333d2b36SAndroid Build Coastguard Worker}
176*333d2b36SAndroid Build Coastguard Worker
177*333d2b36SAndroid Build Coastguard Worker// BuildPaths returns a list of build paths based on the given directory prefix.
178*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) BuildPaths(ctx PathContext, dir OutputPath) WritablePaths {
179*333d2b36SAndroid Build Coastguard Worker	paths := make(WritablePaths, l.Len())
180*333d2b36SAndroid Build Coastguard Worker	for i, jar := range l.jars {
181*333d2b36SAndroid Build Coastguard Worker		paths[i] = dir.Join(ctx, ModuleStem(ctx.Config(), l.Apex(i), jar)+".jar")
182*333d2b36SAndroid Build Coastguard Worker	}
183*333d2b36SAndroid Build Coastguard Worker	return paths
184*333d2b36SAndroid Build Coastguard Worker}
185*333d2b36SAndroid Build Coastguard Worker
186*333d2b36SAndroid Build Coastguard Worker// BuildPathsByModule returns a map from module name to build paths based on the given directory
187*333d2b36SAndroid Build Coastguard Worker// prefix.
188*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) BuildPathsByModule(ctx PathContext, dir OutputPath) map[string]WritablePath {
189*333d2b36SAndroid Build Coastguard Worker	paths := map[string]WritablePath{}
190*333d2b36SAndroid Build Coastguard Worker	for i, jar := range l.jars {
191*333d2b36SAndroid Build Coastguard Worker		paths[jar] = dir.Join(ctx, ModuleStem(ctx.Config(), l.Apex(i), jar)+".jar")
192*333d2b36SAndroid Build Coastguard Worker	}
193*333d2b36SAndroid Build Coastguard Worker	return paths
194*333d2b36SAndroid Build Coastguard Worker}
195*333d2b36SAndroid Build Coastguard Worker
196*333d2b36SAndroid Build Coastguard Worker// UnmarshalJSON converts JSON configuration from raw bytes into a
197*333d2b36SAndroid Build Coastguard Worker// ConfiguredJarList structure.
198*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) UnmarshalJSON(b []byte) error {
199*333d2b36SAndroid Build Coastguard Worker	// Try and unmarshal into a []string each item of which contains a pair
200*333d2b36SAndroid Build Coastguard Worker	// <apex>:<jar>.
201*333d2b36SAndroid Build Coastguard Worker	var list []string
202*333d2b36SAndroid Build Coastguard Worker	err := json.Unmarshal(b, &list)
203*333d2b36SAndroid Build Coastguard Worker	if err != nil {
204*333d2b36SAndroid Build Coastguard Worker		// Did not work so return
205*333d2b36SAndroid Build Coastguard Worker		return err
206*333d2b36SAndroid Build Coastguard Worker	}
207*333d2b36SAndroid Build Coastguard Worker
208*333d2b36SAndroid Build Coastguard Worker	apexes, jars, err := splitListOfPairsIntoPairOfLists(list)
209*333d2b36SAndroid Build Coastguard Worker	if err != nil {
210*333d2b36SAndroid Build Coastguard Worker		return err
211*333d2b36SAndroid Build Coastguard Worker	}
212*333d2b36SAndroid Build Coastguard Worker	l.apexes = apexes
213*333d2b36SAndroid Build Coastguard Worker	l.jars = jars
214*333d2b36SAndroid Build Coastguard Worker	return nil
215*333d2b36SAndroid Build Coastguard Worker}
216*333d2b36SAndroid Build Coastguard Worker
217*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) MarshalJSON() ([]byte, error) {
218*333d2b36SAndroid Build Coastguard Worker	if len(l.apexes) != len(l.jars) {
219*333d2b36SAndroid Build Coastguard Worker		return nil, errors.New(fmt.Sprintf("Inconsistent ConfiguredJarList: apexes: %q, jars: %q", l.apexes, l.jars))
220*333d2b36SAndroid Build Coastguard Worker	}
221*333d2b36SAndroid Build Coastguard Worker
222*333d2b36SAndroid Build Coastguard Worker	list := make([]string, 0, len(l.apexes))
223*333d2b36SAndroid Build Coastguard Worker
224*333d2b36SAndroid Build Coastguard Worker	for i := 0; i < len(l.apexes); i++ {
225*333d2b36SAndroid Build Coastguard Worker		list = append(list, l.apexes[i]+":"+l.jars[i])
226*333d2b36SAndroid Build Coastguard Worker	}
227*333d2b36SAndroid Build Coastguard Worker
228*333d2b36SAndroid Build Coastguard Worker	return json.Marshal(list)
229*333d2b36SAndroid Build Coastguard Worker}
230*333d2b36SAndroid Build Coastguard Worker
231*333d2b36SAndroid Build Coastguard Workerfunc OverrideConfiguredJarLocationFor(cfg Config, apex string, jar string) (newApex string, newJar string) {
232*333d2b36SAndroid Build Coastguard Worker	for _, entry := range cfg.productVariables.ConfiguredJarLocationOverrides {
233*333d2b36SAndroid Build Coastguard Worker		tuple := strings.Split(entry, ":")
234*333d2b36SAndroid Build Coastguard Worker		if len(tuple) != 4 {
235*333d2b36SAndroid Build Coastguard Worker			panic("malformed configured jar location override '%s', expected format: <old_apex>:<old_jar>:<new_apex>:<new_jar>")
236*333d2b36SAndroid Build Coastguard Worker		}
237*333d2b36SAndroid Build Coastguard Worker		if apex == tuple[0] && jar == tuple[1] {
238*333d2b36SAndroid Build Coastguard Worker			return tuple[2], tuple[3]
239*333d2b36SAndroid Build Coastguard Worker		}
240*333d2b36SAndroid Build Coastguard Worker	}
241*333d2b36SAndroid Build Coastguard Worker	return apex, jar
242*333d2b36SAndroid Build Coastguard Worker}
243*333d2b36SAndroid Build Coastguard Worker
244*333d2b36SAndroid Build Coastguard Worker// ModuleStem returns the overridden jar name.
245*333d2b36SAndroid Build Coastguard Workerfunc ModuleStem(cfg Config, apex string, jar string) string {
246*333d2b36SAndroid Build Coastguard Worker	_, newJar := OverrideConfiguredJarLocationFor(cfg, apex, jar)
247*333d2b36SAndroid Build Coastguard Worker	return newJar
248*333d2b36SAndroid Build Coastguard Worker}
249*333d2b36SAndroid Build Coastguard Worker
250*333d2b36SAndroid Build Coastguard Worker// DevicePaths computes the on-device paths for the list of (apex, jar) pairs,
251*333d2b36SAndroid Build Coastguard Worker// based on the operating system.
252*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) DevicePaths(cfg Config, ostype OsType) []string {
253*333d2b36SAndroid Build Coastguard Worker	paths := make([]string, l.Len())
254*333d2b36SAndroid Build Coastguard Worker	for i := 0; i < l.Len(); i++ {
255*333d2b36SAndroid Build Coastguard Worker		apex, jar := OverrideConfiguredJarLocationFor(cfg, l.Apex(i), l.Jar(i))
256*333d2b36SAndroid Build Coastguard Worker		name := jar + ".jar"
257*333d2b36SAndroid Build Coastguard Worker
258*333d2b36SAndroid Build Coastguard Worker		var subdir string
259*333d2b36SAndroid Build Coastguard Worker		if apex == "platform" {
260*333d2b36SAndroid Build Coastguard Worker			subdir = "system/framework"
261*333d2b36SAndroid Build Coastguard Worker		} else if apex == "system_ext" {
262*333d2b36SAndroid Build Coastguard Worker			subdir = "system_ext/framework"
263*333d2b36SAndroid Build Coastguard Worker		} else {
264*333d2b36SAndroid Build Coastguard Worker			subdir = filepath.Join("apex", apex, "javalib")
265*333d2b36SAndroid Build Coastguard Worker		}
266*333d2b36SAndroid Build Coastguard Worker
267*333d2b36SAndroid Build Coastguard Worker		if ostype.Class == Host {
268*333d2b36SAndroid Build Coastguard Worker			paths[i] = filepath.Join(cfg.Getenv("OUT_DIR"), "host", cfg.PrebuiltOS(), subdir, name)
269*333d2b36SAndroid Build Coastguard Worker		} else {
270*333d2b36SAndroid Build Coastguard Worker			paths[i] = filepath.Join("/", subdir, name)
271*333d2b36SAndroid Build Coastguard Worker		}
272*333d2b36SAndroid Build Coastguard Worker	}
273*333d2b36SAndroid Build Coastguard Worker	return paths
274*333d2b36SAndroid Build Coastguard Worker}
275*333d2b36SAndroid Build Coastguard Worker
276*333d2b36SAndroid Build Coastguard Workerfunc (l *ConfiguredJarList) String() string {
277*333d2b36SAndroid Build Coastguard Worker	var pairs []string
278*333d2b36SAndroid Build Coastguard Worker	for i := 0; i < l.Len(); i++ {
279*333d2b36SAndroid Build Coastguard Worker		pairs = append(pairs, l.apexes[i]+":"+l.jars[i])
280*333d2b36SAndroid Build Coastguard Worker	}
281*333d2b36SAndroid Build Coastguard Worker	return strings.Join(pairs, ",")
282*333d2b36SAndroid Build Coastguard Worker}
283*333d2b36SAndroid Build Coastguard Worker
284*333d2b36SAndroid Build Coastguard Workerfunc splitListOfPairsIntoPairOfLists(list []string) ([]string, []string, error) {
285*333d2b36SAndroid Build Coastguard Worker	// Now we need to populate this list by splitting each item in the slice of
286*333d2b36SAndroid Build Coastguard Worker	// pairs and appending them to the appropriate list of apexes or jars.
287*333d2b36SAndroid Build Coastguard Worker	apexes := make([]string, len(list))
288*333d2b36SAndroid Build Coastguard Worker	jars := make([]string, len(list))
289*333d2b36SAndroid Build Coastguard Worker
290*333d2b36SAndroid Build Coastguard Worker	for i, apexjar := range list {
291*333d2b36SAndroid Build Coastguard Worker		apex, jar, err := splitConfiguredJarPair(apexjar)
292*333d2b36SAndroid Build Coastguard Worker		if err != nil {
293*333d2b36SAndroid Build Coastguard Worker			return nil, nil, err
294*333d2b36SAndroid Build Coastguard Worker		}
295*333d2b36SAndroid Build Coastguard Worker		apexes[i] = apex
296*333d2b36SAndroid Build Coastguard Worker		jars[i] = jar
297*333d2b36SAndroid Build Coastguard Worker	}
298*333d2b36SAndroid Build Coastguard Worker
299*333d2b36SAndroid Build Coastguard Worker	return apexes, jars, nil
300*333d2b36SAndroid Build Coastguard Worker}
301*333d2b36SAndroid Build Coastguard Worker
302*333d2b36SAndroid Build Coastguard Worker// Expected format for apexJarValue = <apex name>:<jar name>
303*333d2b36SAndroid Build Coastguard Workerfunc splitConfiguredJarPair(str string) (string, string, error) {
304*333d2b36SAndroid Build Coastguard Worker	pair := strings.SplitN(str, ":", 2)
305*333d2b36SAndroid Build Coastguard Worker	if len(pair) == 2 {
306*333d2b36SAndroid Build Coastguard Worker		apex := pair[0]
307*333d2b36SAndroid Build Coastguard Worker		jar := pair[1]
308*333d2b36SAndroid Build Coastguard Worker		if apex == "" {
309*333d2b36SAndroid Build Coastguard Worker			return apex, jar, fmt.Errorf("invalid apex '%s' in <apex>:<jar> pair '%s', expected format: <apex>:<jar>", apex, str)
310*333d2b36SAndroid Build Coastguard Worker		}
311*333d2b36SAndroid Build Coastguard Worker		return apex, jar, nil
312*333d2b36SAndroid Build Coastguard Worker	} else {
313*333d2b36SAndroid Build Coastguard Worker		return "error-apex", "error-jar", fmt.Errorf("malformed (apex, jar) pair: '%s', expected format: <apex>:<jar>", str)
314*333d2b36SAndroid Build Coastguard Worker	}
315*333d2b36SAndroid Build Coastguard Worker}
316*333d2b36SAndroid Build Coastguard Worker
317*333d2b36SAndroid Build Coastguard Worker// EmptyConfiguredJarList returns an empty jar list.
318*333d2b36SAndroid Build Coastguard Workerfunc EmptyConfiguredJarList() ConfiguredJarList {
319*333d2b36SAndroid Build Coastguard Worker	return ConfiguredJarList{}
320*333d2b36SAndroid Build Coastguard Worker}
321*333d2b36SAndroid Build Coastguard Worker
322*333d2b36SAndroid Build Coastguard Worker// IsConfiguredJarForPlatform returns true if the given apex name is a special name for the platform.
323*333d2b36SAndroid Build Coastguard Workerfunc IsConfiguredJarForPlatform(apex string) bool {
324*333d2b36SAndroid Build Coastguard Worker	return apex == "platform" || apex == "system_ext"
325*333d2b36SAndroid Build Coastguard Worker}
326*333d2b36SAndroid Build Coastguard Worker
327*333d2b36SAndroid Build Coastguard Workervar earlyBootJarsKey = NewOnceKey("earlyBootJars")
328