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