summaryrefslogtreecommitdiff
path: root/java/android_resources.go
blob: 3bb3eb554c6e07961aff3e4a3fbe04957f59c13f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright 2018 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package java

import (
	"path/filepath"
	"strings"

	"android/soong/android"
)

var androidResourceIgnoreFilenames = []string{
	".svn",
	".git",
	".ds_store",
	"*.scc",
	".*",
	"CVS",
	"thumbs.db",
	"picasa.ini",
	"*~",
}

// androidResourceGlob returns the list of files in the given directory, using the standard
// exclusion patterns for Android resources.
func androidResourceGlob(ctx android.EarlyModuleContext, dir android.Path) android.Paths {
	return ctx.GlobFiles(filepath.Join(dir.String(), "**/*"), androidResourceIgnoreFilenames)
}

type overlayType int

const (
	device overlayType = iota + 1
	product
)

type rroDir struct {
	path        android.Path
	overlayType overlayType
}

type overlayGlobResult struct {
	dir         string
	paths       android.DirectorySortedPaths
	overlayType overlayType
}

var overlayDataKey = android.NewOnceKey("overlayDataKey")

type globbedResourceDir struct {
	dir   android.Path
	files android.Paths
}

func overlayResourceGlob(ctx android.ModuleContext, a *aapt, dir android.Path) (res []globbedResourceDir,
	rroDirs []rroDir) {

	overlayData := ctx.Config().Once(overlayDataKey, func() interface{} {
		var overlayData []overlayGlobResult

		appendOverlayData := func(overlayDirs []string, t overlayType) {
			for i := range overlayDirs {
				// Iterate backwards through the list of overlay directories so that the later, lower-priority
				// directories in the list show up earlier in the command line to aapt2.
				overlay := overlayDirs[len(overlayDirs)-1-i]
				var result overlayGlobResult
				result.dir = overlay
				result.overlayType = t

				files, err := ctx.GlobWithDeps(filepath.Join(overlay, "**/*"), androidResourceIgnoreFilenames)
				if err != nil {
					ctx.ModuleErrorf("failed to glob resource dir %q: %s", overlay, err.Error())
					continue
				}
				var paths android.Paths
				for _, f := range files {
					if !strings.HasSuffix(f, "/") {
						paths = append(paths, android.PathForSource(ctx, f))
					}
				}
				result.paths = android.PathsToDirectorySortedPaths(paths)
				overlayData = append(overlayData, result)
			}
		}

		appendOverlayData(ctx.Config().DeviceResourceOverlays(), device)
		appendOverlayData(ctx.Config().ProductResourceOverlays(), product)
		return overlayData
	}).([]overlayGlobResult)

	// Runtime resource overlays (RRO) may be turned on by the product config for some modules
	rroEnabled := a.IsRROEnforced(ctx)

	for _, data := range overlayData {
		files := data.paths.PathsInDirectory(filepath.Join(data.dir, dir.String()))
		if len(files) > 0 {
			overlayModuleDir := android.PathForSource(ctx, data.dir, dir.String())

			// If enforce RRO is enabled for this module and this overlay is not in the
			// exclusion list, ignore the overlay.  The list of ignored overlays will be
			// passed to Make to be turned into an RRO package.
			if rroEnabled && !ctx.Config().EnforceRROExcludedOverlay(overlayModuleDir.String()) {
				rroDirs = append(rroDirs, rroDir{overlayModuleDir, data.overlayType})
			} else {
				res = append(res, globbedResourceDir{
					dir:   overlayModuleDir,
					files: files,
				})
			}
		}
	}

	return res, rroDirs
}