Merge "sh_binary can be included in APEX"
diff --git a/java/aar.go b/java/aar.go
index d08e487..b96f127 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -26,6 +26,7 @@
 	Dependency
 	ExportPackage() android.Path
 	ExportedProguardFlagFiles() android.Paths
+	ExportedRRODirs() android.Paths
 	ExportedStaticPackages() android.Paths
 	ExportedManifest() android.Path
 }
@@ -80,6 +81,14 @@
 	return a.exportPackage
 }
 
+func (a *aapt) ExportedRRODirs() android.Paths {
+	return a.rroDirs
+}
+
+func (a *aapt) ExportedManifest() android.Path {
+	return a.manifestPath
+}
+
 func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext, manifestPath android.Path) (flags []string,
 	deps android.Paths, resDirs, overlayDirs []globbedResourceDir, rroDirs android.Paths) {
 
@@ -164,7 +173,7 @@
 }
 
 func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, extraLinkFlags ...string) {
-	transitiveStaticLibs, staticLibManifests, libDeps, libFlags := aaptLibs(ctx, sdkContext)
+	transitiveStaticLibs, staticLibManifests, staticRRODirs, libDeps, libFlags := aaptLibs(ctx, sdkContext)
 
 	// App manifest file
 	manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
@@ -174,6 +183,8 @@
 
 	linkFlags, linkDeps, resDirs, overlayDirs, rroDirs := a.aapt2Flags(ctx, sdkContext, manifestPath)
 
+	rroDirs = append(rroDirs, staticRRODirs...)
+
 	linkFlags = append(linkFlags, libFlags...)
 	linkDeps = append(linkDeps, libDeps...)
 	linkFlags = append(linkFlags, extraLinkFlags...)
@@ -235,7 +246,7 @@
 
 // aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
 func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStaticLibs, staticLibManifests,
-	deps android.Paths, flags []string) {
+	staticRRODirs, deps android.Paths, flags []string) {
 
 	var sharedLibs android.Paths
 
@@ -263,6 +274,7 @@
 				transitiveStaticLibs = append(transitiveStaticLibs, exportPackage)
 				transitiveStaticLibs = append(transitiveStaticLibs, aarDep.ExportedStaticPackages()...)
 				staticLibManifests = append(staticLibManifests, aarDep.ExportedManifest())
+				staticRRODirs = append(staticRRODirs, aarDep.ExportedRRODirs()...)
 			}
 		}
 	})
@@ -279,8 +291,9 @@
 	}
 
 	transitiveStaticLibs = android.FirstUniquePaths(transitiveStaticLibs)
+	staticRRODirs = android.FirstUniquePaths(staticRRODirs)
 
-	return transitiveStaticLibs, staticLibManifests, deps, flags
+	return transitiveStaticLibs, staticLibManifests, staticRRODirs, deps, flags
 }
 
 type AndroidLibrary struct {
@@ -303,10 +316,6 @@
 	return a.exportedStaticPackages
 }
 
-func (a *AndroidLibrary) ExportedManifest() android.Path {
-	return a.manifestPath
-}
-
 var _ AndroidLibraryDependency = (*AndroidLibrary)(nil)
 
 func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -426,6 +435,10 @@
 	return android.Paths{a.proguardFlags}
 }
 
+func (a *AARImport) ExportedRRODirs() android.Paths {
+	return nil
+}
+
 func (a *AARImport) ExportedStaticPackages() android.Paths {
 	return a.exportedStaticPackages
 }
@@ -518,9 +531,10 @@
 	linkFlags = append(linkFlags, "--manifest "+a.manifest.String())
 	linkDeps = append(linkDeps, a.manifest)
 
-	transitiveStaticLibs, staticLibManifests, libDeps, libFlags := aaptLibs(ctx, sdkContext(a))
+	transitiveStaticLibs, staticLibManifests, staticRRODirs, libDeps, libFlags := aaptLibs(ctx, sdkContext(a))
 
 	_ = staticLibManifests
+	_ = staticRRODirs
 
 	linkDeps = append(linkDeps, libDeps...)
 	linkFlags = append(linkFlags, libFlags...)
diff --git a/java/app.go b/java/app.go
index e9c12e0..08714f2 100644
--- a/java/app.go
+++ b/java/app.go
@@ -95,10 +95,6 @@
 	return nil
 }
 
-func (a *AndroidApp) ExportedManifest() android.Path {
-	return a.manifestPath
-}
-
 var _ AndroidLibraryDependency = (*AndroidApp)(nil)
 
 type Certificate struct {
diff --git a/java/app_test.go b/java/app_test.go
index 2455145..93d20d0 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -106,68 +106,86 @@
 	}
 }
 
-var testEnforceRROTests = []struct {
-	name                       string
-	enforceRROTargets          []string
-	enforceRROExcludedOverlays []string
-	overlayFiles               map[string][]string
-	rroDirs                    map[string][]string
-}{
-	{
-		name:                       "no RRO",
-		enforceRROTargets:          nil,
-		enforceRROExcludedOverlays: nil,
-		overlayFiles: map[string][]string{
-			"foo": []string{
-				"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
-				"device/vendor/blah/overlay/foo/res/values/strings.xml",
-			},
-			"bar": []string{
-				"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
-				"device/vendor/blah/overlay/bar/res/values/strings.xml",
-			},
-		},
-		rroDirs: map[string][]string{
-			"foo": nil,
-			"bar": nil,
-		},
-	},
-	{
-		name:                       "enforce RRO on foo",
-		enforceRROTargets:          []string{"foo"},
-		enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
-		overlayFiles: map[string][]string{
-			"foo": []string{"device/vendor/blah/static_overlay/foo/res/values/strings.xml"},
-			"bar": []string{
-				"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
-				"device/vendor/blah/overlay/bar/res/values/strings.xml",
-			},
-		},
-		rroDirs: map[string][]string{
-			"foo": []string{"device/vendor/blah/overlay/foo/res"},
-			"bar": nil,
-		},
-	},
-	{
-		name:              "enforce RRO on all",
-		enforceRROTargets: []string{"*"},
-		enforceRROExcludedOverlays: []string{
-			// Excluding specific apps/res directories also allowed.
-			"device/vendor/blah/static_overlay/foo",
-			"device/vendor/blah/static_overlay/bar/res",
-		},
-		overlayFiles: map[string][]string{
-			"foo": []string{"device/vendor/blah/static_overlay/foo/res/values/strings.xml"},
-			"bar": []string{"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
-		},
-		rroDirs: map[string][]string{
-			"foo": []string{"device/vendor/blah/overlay/foo/res"},
-			"bar": []string{"device/vendor/blah/overlay/bar/res"},
-		},
-	},
-}
-
 func TestEnforceRRO(t *testing.T) {
+	testCases := []struct {
+		name                       string
+		enforceRROTargets          []string
+		enforceRROExcludedOverlays []string
+		overlayFiles               map[string][]string
+		rroDirs                    map[string][]string
+	}{
+		{
+			name:                       "no RRO",
+			enforceRROTargets:          nil,
+			enforceRROExcludedOverlays: nil,
+			overlayFiles: map[string][]string{
+				"foo": []string{
+					buildDir + "/.intermediates/lib/android_common/package-res.apk",
+					"foo/res/res/values/strings.xml",
+					"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
+					"device/vendor/blah/overlay/foo/res/values/strings.xml",
+				},
+				"bar": []string{
+					"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
+					"device/vendor/blah/overlay/bar/res/values/strings.xml",
+				},
+			},
+			rroDirs: map[string][]string{
+				"foo": nil,
+				"bar": nil,
+			},
+		},
+		{
+			name:                       "enforce RRO on foo",
+			enforceRROTargets:          []string{"foo"},
+			enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
+			overlayFiles: map[string][]string{
+				"foo": []string{
+					buildDir + "/.intermediates/lib/android_common/package-res.apk",
+					"foo/res/res/values/strings.xml",
+					"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
+				},
+				"bar": []string{
+					"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
+					"device/vendor/blah/overlay/bar/res/values/strings.xml",
+				},
+			},
+
+			rroDirs: map[string][]string{
+				"foo": []string{
+					"device/vendor/blah/overlay/foo/res",
+					// Enforce RRO on "foo" could imply RRO on static dependencies, but for now it doesn't.
+					// "device/vendor/blah/overlay/lib/res",
+				},
+				"bar": nil,
+			},
+		},
+		{
+			name:              "enforce RRO on all",
+			enforceRROTargets: []string{"*"},
+			enforceRROExcludedOverlays: []string{
+				// Excluding specific apps/res directories also allowed.
+				"device/vendor/blah/static_overlay/foo",
+				"device/vendor/blah/static_overlay/bar/res",
+			},
+			overlayFiles: map[string][]string{
+				"foo": []string{
+					buildDir + "/.intermediates/lib/android_common/package-res.apk",
+					"foo/res/res/values/strings.xml",
+					"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
+				},
+				"bar": []string{"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
+			},
+			rroDirs: map[string][]string{
+				"foo": []string{
+					"device/vendor/blah/overlay/foo/res",
+					"device/vendor/blah/overlay/lib/res",
+				},
+				"bar": []string{"device/vendor/blah/overlay/bar/res"},
+			},
+		},
+	}
+
 	resourceOverlays := []string{
 		"device/vendor/blah/overlay",
 		"device/vendor/blah/overlay2",
@@ -177,8 +195,10 @@
 	fs := map[string][]byte{
 		"foo/res/res/values/strings.xml":                               nil,
 		"bar/res/res/values/strings.xml":                               nil,
+		"lib/res/res/values/strings.xml":                               nil,
 		"device/vendor/blah/overlay/foo/res/values/strings.xml":        nil,
 		"device/vendor/blah/overlay/bar/res/values/strings.xml":        nil,
+		"device/vendor/blah/overlay/lib/res/values/strings.xml":        nil,
 		"device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
 		"device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
 		"device/vendor/blah/overlay2/res/values/strings.xml":           nil,
@@ -188,15 +208,21 @@
 			android_app {
 				name: "foo",
 				resource_dirs: ["foo/res"],
+				static_libs: ["lib"],
 			}
 
 			android_app {
 				name: "bar",
 				resource_dirs: ["bar/res"],
 			}
+
+			android_library {
+				name: "lib",
+				resource_dirs: ["lib/res"],
+			}
 		`
 
-	for _, testCase := range testEnforceRROTests {
+	for _, testCase := range testCases {
 		t.Run(testCase.name, func(t *testing.T) {
 			config := testConfig(nil)
 			config.TestProductVariables.ResourceOverlays = resourceOverlays
@@ -216,7 +242,15 @@
 				var overlayFiles []string
 				if overlayFile.Rule != nil {
 					for _, o := range overlayFile.Inputs.Strings() {
-						overlayFiles = append(overlayFiles, module.Output(o).Inputs.Strings()...)
+						overlayOutput := module.MaybeOutput(o)
+						if overlayOutput.Rule != nil {
+							// If the overlay is compiled as part of this module (i.e. a .arsc.flat file),
+							// verify the inputs to the .arsc.flat rule.
+							overlayFiles = append(overlayFiles, overlayOutput.Inputs.Strings()...)
+						} else {
+							// Otherwise, verify the full path to the output of the other module
+							overlayFiles = append(overlayFiles, o)
+						}
 					}
 				}