1// Copyright 2018 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 java 16 17import ( 18 "path/filepath" 19 "strings" 20 21 "android/soong/android" 22) 23 24func init() { 25 registerOverlayBuildComponents(android.InitRegistrationContext) 26} 27 28func registerOverlayBuildComponents(ctx android.RegistrationContext) { 29 ctx.RegisterPreSingletonType("overlay", OverlaySingletonFactory) 30} 31 32var androidResourceIgnoreFilenames = []string{ 33 ".svn", 34 ".git", 35 ".ds_store", 36 "*.scc", 37 ".*", 38 "CVS", 39 "thumbs.db", 40 "picasa.ini", 41 "*~", 42} 43 44// androidResourceGlob returns the list of files in the given directory, using the standard 45// exclusion patterns for Android resources. 46func androidResourceGlob(ctx android.ModuleContext, dir android.Path) android.Paths { 47 return ctx.GlobFiles(filepath.Join(dir.String(), "**/*"), androidResourceIgnoreFilenames) 48} 49 50// androidResourceGlobList creates a rule to write the list of files in the given directory, using 51// the standard exclusion patterns for Android resources, to the given output file. 52func androidResourceGlobList(ctx android.ModuleContext, dir android.Path, 53 fileListFile android.WritablePath) { 54 55 android.GlobToListFileRule(ctx, filepath.Join(dir.String(), "**/*"), 56 androidResourceIgnoreFilenames, fileListFile) 57} 58 59type overlayType int 60 61const ( 62 device overlayType = iota + 1 63 product 64) 65 66type rroDir struct { 67 path android.Path 68 overlayType overlayType 69} 70 71type overlayGlobResult struct { 72 dir string 73 paths android.DirectorySortedPaths 74 overlayType overlayType 75} 76 77var overlayDataKey = android.NewOnceKey("overlayDataKey") 78 79type globbedResourceDir struct { 80 dir android.Path 81 files android.Paths 82} 83 84func overlayResourceGlob(ctx android.ModuleContext, a *aapt, dir android.Path) (res []globbedResourceDir, 85 rroDirs []rroDir) { 86 87 overlayData := ctx.Config().Get(overlayDataKey).([]overlayGlobResult) 88 89 // Runtime resource overlays (RRO) may be turned on by the product config for some modules 90 rroEnabled := a.IsRROEnforced(ctx) 91 92 for _, data := range overlayData { 93 files := data.paths.PathsInDirectory(filepath.Join(data.dir, dir.String())) 94 if len(files) > 0 { 95 overlayModuleDir := android.PathForSource(ctx, data.dir, dir.String()) 96 97 // If enforce RRO is enabled for this module and this overlay is not in the 98 // exclusion list, ignore the overlay. The list of ignored overlays will be 99 // passed to Make to be turned into an RRO package. 100 if rroEnabled && !ctx.Config().EnforceRROExcludedOverlay(overlayModuleDir.String()) { 101 rroDirs = append(rroDirs, rroDir{overlayModuleDir, data.overlayType}) 102 } else { 103 res = append(res, globbedResourceDir{ 104 dir: overlayModuleDir, 105 files: files, 106 }) 107 } 108 } 109 } 110 111 return res, rroDirs 112} 113 114func OverlaySingletonFactory() android.Singleton { 115 return overlaySingleton{} 116} 117 118type overlaySingleton struct{} 119 120func (overlaySingleton) GenerateBuildActions(ctx android.SingletonContext) { 121 var overlayData []overlayGlobResult 122 123 appendOverlayData := func(overlayDirs []string, t overlayType) { 124 for i := range overlayDirs { 125 // Iterate backwards through the list of overlay directories so that the later, lower-priority 126 // directories in the list show up earlier in the command line to aapt2. 127 overlay := overlayDirs[len(overlayDirs)-1-i] 128 var result overlayGlobResult 129 result.dir = overlay 130 result.overlayType = t 131 132 files, err := ctx.GlobWithDeps(filepath.Join(overlay, "**/*"), androidResourceIgnoreFilenames) 133 if err != nil { 134 ctx.Errorf("failed to glob resource dir %q: %s", overlay, err.Error()) 135 continue 136 } 137 var paths android.Paths 138 for _, f := range files { 139 if !strings.HasSuffix(f, "/") { 140 paths = append(paths, android.PathForSource(ctx, f)) 141 } 142 } 143 result.paths = android.PathsToDirectorySortedPaths(paths) 144 overlayData = append(overlayData, result) 145 } 146 } 147 148 appendOverlayData(ctx.Config().DeviceResourceOverlays(), device) 149 appendOverlayData(ctx.Config().ProductResourceOverlays(), product) 150 ctx.Config().Once(overlayDataKey, func() interface{} { 151 return overlayData 152 }) 153} 154