1// 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 java 16 17import ( 18 "android/soong/android" 19 "github.com/google/blueprint" 20) 21 22// MonolithicHiddenAPIInfo contains information needed/provided by the hidden API generation of the 23// monolithic hidden API files. 24// 25// Each list of paths includes all the equivalent paths from each of the bootclasspath_fragment 26// modules that contribute to the platform-bootclasspath. 27type MonolithicHiddenAPIInfo struct { 28 // FlagsFilesByCategory maps from the flag file category to the paths containing information for 29 // that category. 30 FlagsFilesByCategory FlagFilesByCategory 31 32 // The paths to the generated stub-flags.csv files. 33 StubFlagsPaths android.Paths 34 35 // The paths to the generated annotation-flags.csv files. 36 AnnotationFlagsPaths android.Paths 37 38 // The paths to the generated metadata.csv files. 39 MetadataPaths android.Paths 40 41 // The paths to the generated index.csv files. 42 IndexPaths android.Paths 43 44 // The paths to the generated all-flags.csv files. 45 AllFlagsPaths android.Paths 46 47 // The classes jars from the libraries on the platform bootclasspath. 48 ClassesJars android.Paths 49} 50 51// newMonolithicHiddenAPIInfo creates a new MonolithicHiddenAPIInfo from the flagFilesByCategory 52// plus information provided by each of the fragments. 53func newMonolithicHiddenAPIInfo(ctx android.ModuleContext, flagFilesByCategory FlagFilesByCategory, classpathElements ClasspathElements) MonolithicHiddenAPIInfo { 54 monolithicInfo := MonolithicHiddenAPIInfo{} 55 56 monolithicInfo.FlagsFilesByCategory = flagFilesByCategory 57 58 // Merge all the information from the classpathElements. The fragments form a DAG so it is possible that 59 // this will introduce duplicates so they will be resolved after processing all the classpathElements. 60 for _, element := range classpathElements { 61 var classesJars android.Paths 62 switch e := element.(type) { 63 case *ClasspathLibraryElement: 64 classesJars = retrieveClassesJarsFromModule(e.Module()) 65 66 case *ClasspathFragmentElement: 67 fragment := e.Module() 68 if ctx.OtherModuleHasProvider(fragment, HiddenAPIInfoProvider) { 69 info := ctx.OtherModuleProvider(fragment, HiddenAPIInfoProvider).(HiddenAPIInfo) 70 monolithicInfo.append(&info) 71 72 // If the bootclasspath fragment actually perform hidden API processing itself then use the 73 // CSV files it provides and do not bother processing the classesJars files. This ensures 74 // consistent behavior between source and prebuilt as prebuilt modules do not provide 75 // classesJars. 76 if info.AllFlagsPath != nil { 77 continue 78 } 79 } 80 81 classesJars = extractClassesJarsFromModules(e.Contents) 82 } 83 84 monolithicInfo.ClassesJars = append(monolithicInfo.ClassesJars, classesJars...) 85 } 86 87 // Dedup paths. 88 monolithicInfo.dedup() 89 90 return monolithicInfo 91} 92 93// append appends all the files from the supplied info to the corresponding files in this struct. 94func (i *MonolithicHiddenAPIInfo) append(other *HiddenAPIInfo) { 95 i.FlagsFilesByCategory.append(other.FlagFilesByCategory) 96 97 // The output may not be set if the bootclasspath_fragment has not yet been updated to support 98 // hidden API processing. 99 // TODO(b/179354495): Switch back to append once all bootclasspath_fragment modules have been 100 // updated to support hidden API processing properly. 101 appendIfNotNil := func(paths android.Paths, path android.Path) android.Paths { 102 if path == nil { 103 return paths 104 } 105 return append(paths, path) 106 } 107 i.StubFlagsPaths = appendIfNotNil(i.StubFlagsPaths, other.StubFlagsPath) 108 i.AnnotationFlagsPaths = appendIfNotNil(i.AnnotationFlagsPaths, other.AnnotationFlagsPath) 109 i.MetadataPaths = appendIfNotNil(i.MetadataPaths, other.MetadataPath) 110 i.IndexPaths = appendIfNotNil(i.IndexPaths, other.IndexPath) 111 i.AllFlagsPaths = appendIfNotNil(i.AllFlagsPaths, other.AllFlagsPath) 112} 113 114// dedup removes duplicates in all the paths, while maintaining the order in which they were 115// appended. 116func (i *MonolithicHiddenAPIInfo) dedup() { 117 i.FlagsFilesByCategory.dedup() 118 i.StubFlagsPaths = android.FirstUniquePaths(i.StubFlagsPaths) 119 i.AnnotationFlagsPaths = android.FirstUniquePaths(i.AnnotationFlagsPaths) 120 i.MetadataPaths = android.FirstUniquePaths(i.MetadataPaths) 121 i.IndexPaths = android.FirstUniquePaths(i.IndexPaths) 122 i.AllFlagsPaths = android.FirstUniquePaths(i.AllFlagsPaths) 123} 124 125var MonolithicHiddenAPIInfoProvider = blueprint.NewProvider(MonolithicHiddenAPIInfo{}) 126