Merge "Add --top_level_phony to catch more real-to-phony problems"
diff --git a/Android.bp b/Android.bp
index 62e276a..3215fa2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -71,6 +71,7 @@
         "android/env.go",
     ],
     testSrcs: [
+        "android/arch_test.go",
         "android/config_test.go",
         "android/expand_test.go",
         "android/namespace_test.go",
diff --git a/android/arch.go b/android/arch.go
index bb8cc02..6aeccb0 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -105,7 +105,6 @@
 
 var archVariants = map[ArchType][]string{
 	Arm: {
-		"armv7-a",
 		"armv7-a-neon",
 		"armv8-a",
 		"armv8-2a",
@@ -617,10 +616,10 @@
 	}
 }
 
-func filterArchStructFields(fields []reflect.StructField) []reflect.StructField {
-	var ret []reflect.StructField
+func filterArchStructFields(fields []reflect.StructField) (filteredFields []reflect.StructField, filtered bool) {
 	for _, field := range fields {
 		if !proptools.HasTag(field, "android", "arch_variant") {
+			filtered = true
 			continue
 		}
 
@@ -638,15 +637,17 @@
 		// Recurse into structs
 		switch field.Type.Kind() {
 		case reflect.Struct:
-			var ok bool
-			field.Type, ok = filterArchStruct(field.Type)
-			if !ok {
+			var subFiltered bool
+			field.Type, subFiltered = filterArchStruct(field.Type)
+			filtered = filtered || subFiltered
+			if field.Type == nil {
 				continue
 			}
 		case reflect.Ptr:
 			if field.Type.Elem().Kind() == reflect.Struct {
-				nestedType, ok := filterArchStruct(field.Type.Elem())
-				if !ok {
+				nestedType, subFiltered := filterArchStruct(field.Type.Elem())
+				filtered = filtered || subFiltered
+				if nestedType == nil {
 					continue
 				}
 				field.Type = reflect.PtrTo(nestedType)
@@ -655,13 +656,17 @@
 			panic("Interfaces are not supported in arch_variant properties")
 		}
 
-		ret = append(ret, field)
+		filteredFields = append(filteredFields, field)
 	}
 
-	return ret
+	return filteredFields, filtered
 }
 
-func filterArchStruct(prop reflect.Type) (reflect.Type, bool) {
+// filterArchStruct takes a reflect.Type that is either a sturct or a pointer to a struct, and returns a reflect.Type
+// that only contains the fields in the original type that have an `android:"arch_variant"` struct tag, and a bool
+// that is true if the new struct type has fewer fields than the original type.  If there are no fields in the
+// original type with the struct tag it returns nil and true.
+func filterArchStruct(prop reflect.Type) (filteredProp reflect.Type, filtered bool) {
 	var fields []reflect.StructField
 
 	ptr := prop.Kind() == reflect.Ptr
@@ -673,13 +678,20 @@
 		fields = append(fields, prop.Field(i))
 	}
 
-	fields = filterArchStructFields(fields)
+	filteredFields, filtered := filterArchStructFields(fields)
 
-	if len(fields) == 0 {
-		return nil, false
+	if len(filteredFields) == 0 {
+		return nil, true
 	}
 
-	ret := reflect.StructOf(fields)
+	if !filtered {
+		if ptr {
+			return reflect.PtrTo(prop), false
+		}
+		return prop, false
+	}
+
+	ret := reflect.StructOf(filteredFields)
 	if ptr {
 		ret = reflect.PtrTo(ret)
 	}
@@ -687,7 +699,13 @@
 	return ret, true
 }
 
-func filterArchStructSharded(prop reflect.Type) ([]reflect.Type, bool) {
+// filterArchStruct takes a reflect.Type that is either a sturct or a pointer to a struct, and returns a list of
+// reflect.Type that only contains the fields in the original type that have an `android:"arch_variant"` struct tag,
+// and a bool that is true if the new struct type has fewer fields than the original type.  If there are no fields in
+// the original type with the struct tag it returns nil and true.  Each returned struct type will have a maximum of
+// 10 top level fields in it to attempt to avoid hitting the reflect.StructOf name length limit, although the limit
+// can still be reached with a single struct field with many fields in it.
+func filterArchStructSharded(prop reflect.Type) (filteredProp []reflect.Type, filtered bool) {
 	var fields []reflect.StructField
 
 	ptr := prop.Kind() == reflect.Ptr
@@ -699,24 +717,29 @@
 		fields = append(fields, prop.Field(i))
 	}
 
-	fields = filterArchStructFields(fields)
+	fields, filtered = filterArchStructFields(fields)
+	if !filtered {
+		if ptr {
+			return []reflect.Type{reflect.PtrTo(prop)}, false
+		}
+		return []reflect.Type{prop}, false
+	}
 
 	if len(fields) == 0 {
-		return nil, false
+		return nil, true
 	}
 
 	shards := shardFields(fields, 10)
 
-	var ret []reflect.Type
 	for _, shard := range shards {
 		s := reflect.StructOf(shard)
 		if ptr {
 			s = reflect.PtrTo(s)
 		}
-		ret = append(ret, s)
+		filteredProp = append(filteredProp, s)
 	}
 
-	return ret, true
+	return filteredProp, true
 }
 
 func shardFields(fields []reflect.StructField, shardSize int) [][]reflect.StructField {
@@ -731,9 +754,12 @@
 	return ret
 }
 
+// createArchType takes a reflect.Type that is either a struct or a pointer to a struct, and returns a list of
+// reflect.Type that contains the arch-variant properties inside structs for each architecture, os, target, multilib,
+// etc.
 func createArchType(props reflect.Type) []reflect.Type {
-	propShards, ok := filterArchStructSharded(props)
-	if !ok {
+	propShards, _ := filterArchStructSharded(props)
+	if len(propShards) == 0 {
 		return nil
 	}
 
@@ -1269,7 +1295,6 @@
 
 func getMegaDeviceConfig() []archConfig {
 	return []archConfig{
-		{"arm", "armv7-a", "generic", []string{"armeabi-v7a"}},
 		{"arm", "armv7-a-neon", "generic", []string{"armeabi-v7a"}},
 		{"arm", "armv7-a-neon", "cortex-a7", []string{"armeabi-v7a"}},
 		{"arm", "armv7-a-neon", "cortex-a8", []string{"armeabi-v7a"}},
@@ -1321,7 +1346,7 @@
 
 func getNdkAbisConfig() []archConfig {
 	return []archConfig{
-		{"arm", "armv7-a", "", []string{"armeabi"}},
+		{"arm", "armv7-a-neon", "", []string{"armeabi"}},
 		{"arm64", "armv8-a", "", []string{"arm64-v8a"}},
 		{"x86", "", "", []string{"x86"}},
 		{"x86_64", "", "", []string{"x86_64"}},
diff --git a/android/arch_test.go b/android/arch_test.go
new file mode 100644
index 0000000..0589e6c
--- /dev/null
+++ b/android/arch_test.go
@@ -0,0 +1,232 @@
+// Copyright 2019 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 android
+
+import (
+	"reflect"
+	"testing"
+)
+
+type Named struct {
+	A *string `android:"arch_variant"`
+	B *string
+}
+
+type NamedAllFiltered struct {
+	A *string
+}
+
+type NamedNoneFiltered struct {
+	A *string `android:"arch_variant"`
+}
+
+func TestFilterArchStruct(t *testing.T) {
+	tests := []struct {
+		name     string
+		in       interface{}
+		out      interface{}
+		filtered bool
+	}{
+		// Property tests
+		{
+			name: "basic",
+			in: &struct {
+				A *string `android:"arch_variant"`
+				B *string
+			}{},
+			out: &struct {
+				A *string
+			}{},
+			filtered: true,
+		},
+		{
+			name: "all filtered",
+			in: &struct {
+				A *string
+			}{},
+			out:      nil,
+			filtered: true,
+		},
+		{
+			name: "none filtered",
+			in: &struct {
+				A *string `android:"arch_variant"`
+			}{},
+			out: &struct {
+				A *string `android:"arch_variant"`
+			}{},
+			filtered: false,
+		},
+
+		// Sub-struct tests
+		{
+			name: "substruct",
+			in: &struct {
+				A struct {
+					A *string `android:"arch_variant"`
+					B *string
+				} `android:"arch_variant"`
+			}{},
+			out: &struct {
+				A struct {
+					A *string
+				}
+			}{},
+			filtered: true,
+		},
+		{
+			name: "substruct all filtered",
+			in: &struct {
+				A struct {
+					A *string
+				} `android:"arch_variant"`
+			}{},
+			out:      nil,
+			filtered: true,
+		},
+		{
+			name: "substruct none filtered",
+			in: &struct {
+				A struct {
+					A *string `android:"arch_variant"`
+				} `android:"arch_variant"`
+			}{},
+			out: &struct {
+				A struct {
+					A *string `android:"arch_variant"`
+				} `android:"arch_variant"`
+			}{},
+			filtered: false,
+		},
+
+		// Named sub-struct tests
+		{
+			name: "named substruct",
+			in: &struct {
+				A Named `android:"arch_variant"`
+			}{},
+			out: &struct {
+				A struct {
+					A *string
+				}
+			}{},
+			filtered: true,
+		},
+		{
+			name: "substruct all filtered",
+			in: &struct {
+				A NamedAllFiltered `android:"arch_variant"`
+			}{},
+			out:      nil,
+			filtered: true,
+		},
+		{
+			name: "substruct none filtered",
+			in: &struct {
+				A NamedNoneFiltered `android:"arch_variant"`
+			}{},
+			out: &struct {
+				A NamedNoneFiltered `android:"arch_variant"`
+			}{},
+			filtered: false,
+		},
+
+		// Pointer to sub-struct tests
+		{
+			name: "pointer substruct",
+			in: &struct {
+				A *struct {
+					A *string `android:"arch_variant"`
+					B *string
+				} `android:"arch_variant"`
+			}{},
+			out: &struct {
+				A *struct {
+					A *string
+				}
+			}{},
+			filtered: true,
+		},
+		{
+			name: "pointer substruct all filtered",
+			in: &struct {
+				A *struct {
+					A *string
+				} `android:"arch_variant"`
+			}{},
+			out:      nil,
+			filtered: true,
+		},
+		{
+			name: "pointer substruct none filtered",
+			in: &struct {
+				A *struct {
+					A *string `android:"arch_variant"`
+				} `android:"arch_variant"`
+			}{},
+			out: &struct {
+				A *struct {
+					A *string `android:"arch_variant"`
+				} `android:"arch_variant"`
+			}{},
+			filtered: false,
+		},
+
+		// Pointer to named sub-struct tests
+		{
+			name: "pointer named substruct",
+			in: &struct {
+				A *Named `android:"arch_variant"`
+			}{},
+			out: &struct {
+				A *struct {
+					A *string
+				}
+			}{},
+			filtered: true,
+		},
+		{
+			name: "pointer substruct all filtered",
+			in: &struct {
+				A *NamedAllFiltered `android:"arch_variant"`
+			}{},
+			out:      nil,
+			filtered: true,
+		},
+		{
+			name: "pointer substruct none filtered",
+			in: &struct {
+				A *NamedNoneFiltered `android:"arch_variant"`
+			}{},
+			out: &struct {
+				A *NamedNoneFiltered `android:"arch_variant"`
+			}{},
+			filtered: false,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			out, filtered := filterArchStruct(reflect.TypeOf(test.in))
+			if filtered != test.filtered {
+				t.Errorf("expected filtered %v, got %v", test.filtered, filtered)
+			}
+			expected := reflect.TypeOf(test.out)
+			if out != expected {
+				t.Errorf("expected type %v, got %v", expected, out)
+			}
+		})
+	}
+}
diff --git a/android/config.go b/android/config.go
index 6d81a38..122b99b 100644
--- a/android/config.go
+++ b/android/config.go
@@ -918,6 +918,17 @@
 		"invalid override rule %q in PRODUCT_CERTIFICATE_OVERRIDES should be <module_name>:<certificate_module_name>")
 }
 
+func (c *deviceConfig) OverridePackageNameFor(name string) string {
+	newName, overridden := findOverrideValue(
+		c.config.productVariables.PackageNameOverrides,
+		name,
+		"invalid override rule %q in PRODUCT_PACKAGE_NAME_OVERRIDES should be <module_name>:<package_name>")
+	if overridden {
+		return newName
+	}
+	return name
+}
+
 func findOverrideValue(overrides []string, name string, errorMsg string) (newValue string, overridden bool) {
 	if overrides == nil || len(overrides) == 0 {
 		return "", false
diff --git a/android/paths.go b/android/paths.go
index 13b31c7..4b84c97 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -503,16 +503,9 @@
 		return ret, err
 	}
 
-	abs, err := filepath.Abs(ret.String())
-	if err != nil {
-		return ret, err
-	}
-	buildroot, err := filepath.Abs(ctx.Config().buildDir)
-	if err != nil {
-		return ret, err
-	}
-	if strings.HasPrefix(abs, buildroot) {
-		return ret, fmt.Errorf("source path %s is in output", abs)
+	// absolute path already checked by validateSafePath
+	if strings.HasPrefix(ret.String(), ctx.Config().buildDir) {
+		return ret, fmt.Errorf("source path %s is in output", ret.String())
 	}
 
 	return ret, err
@@ -526,16 +519,9 @@
 		return ret, err
 	}
 
-	abs, err := filepath.Abs(ret.String())
-	if err != nil {
-		return ret, err
-	}
-	buildroot, err := filepath.Abs(ctx.Config().buildDir)
-	if err != nil {
-		return ret, err
-	}
-	if strings.HasPrefix(abs, buildroot) {
-		return ret, fmt.Errorf("source path %s is in output", abs)
+	// absolute path already checked by validatePath
+	if strings.HasPrefix(ret.String(), ctx.Config().buildDir) {
+		return ret, fmt.Errorf("source path %s is in output", ret.String())
 	}
 
 	return ret, nil
diff --git a/android/paths_test.go b/android/paths_test.go
index c4332d2..1ed0734 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -630,3 +630,64 @@
 		})
 	}
 }
+
+func TestPathForSource(t *testing.T) {
+	testCases := []struct {
+		name     string
+		buildDir string
+		src      string
+		err      string
+	}{
+		{
+			name:     "normal",
+			buildDir: "out",
+			src:      "a/b/c",
+		},
+		{
+			name:     "abs",
+			buildDir: "out",
+			src:      "/a/b/c",
+			err:      "is outside directory",
+		},
+		{
+			name:     "in out dir",
+			buildDir: "out",
+			src:      "out/a/b/c",
+			err:      "is in output",
+		},
+	}
+
+	funcs := []struct {
+		name string
+		f    func(ctx PathContext, pathComponents ...string) (SourcePath, error)
+	}{
+		{"pathForSource", pathForSource},
+		{"safePathForSource", safePathForSource},
+	}
+
+	for _, f := range funcs {
+		t.Run(f.name, func(t *testing.T) {
+			for _, test := range testCases {
+				t.Run(test.name, func(t *testing.T) {
+					testConfig := TestConfig(test.buildDir, nil)
+					ctx := &configErrorWrapper{config: testConfig}
+					_, err := f.f(ctx, test.src)
+					if len(ctx.errors) > 0 {
+						t.Fatalf("unexpected errors %v", ctx.errors)
+					}
+					if err != nil {
+						if test.err == "" {
+							t.Fatalf("unexpected error %q", err.Error())
+						} else if !strings.Contains(err.Error(), test.err) {
+							t.Fatalf("incorrect error, want substring %q got %q", test.err, err.Error())
+						}
+					} else {
+						if test.err != "" {
+							t.Fatalf("missing error %q", test.err)
+						}
+					}
+				})
+			}
+		})
+	}
+}
diff --git a/android/testing.go b/android/testing.go
index d318839..b7a043e 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -190,14 +190,14 @@
 	return BuildParams{}, searchedOutputs
 }
 
-// MaybeOutput finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputspath whose String() or Rel()
+// MaybeOutput finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
 // value matches the provided string.  Returns an empty BuildParams if no rule is found.
 func (m TestingModule) MaybeOutput(file string) BuildParams {
 	p, _ := m.maybeOutput(file)
 	return p
 }
 
-// Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputspath whose String() or Rel()
+// Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
 // value matches the provided string.  Panics if no rule is found.
 func (m TestingModule) Output(file string) BuildParams {
 	p, searchedOutputs := m.maybeOutput(file)
@@ -208,6 +208,19 @@
 	return p
 }
 
+// AllOutputs returns all 'BuildParams.Output's and 'BuildParams.Outputs's in their full path string forms.
+func (m TestingModule) AllOutputs() []string {
+	var outputFullPaths []string
+	for _, p := range m.module.BuildParamsForTests() {
+		outputs := append(WritablePaths(nil), p.Outputs...)
+		if p.Output != nil {
+			outputs = append(outputs, p.Output)
+		}
+		outputFullPaths = append(outputFullPaths, outputs.Strings()...)
+	}
+	return outputFullPaths
+}
+
 func FailIfErrored(t *testing.T, errs []error) {
 	t.Helper()
 	if len(errs) > 0 {
diff --git a/android/variable.go b/android/variable.go
index 67e876a..2cccd50 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -271,6 +271,7 @@
 
 	ManifestPackageNameOverrides []string `json:",omitempty"`
 	CertificateOverrides         []string `json:",omitempty"`
+	PackageNameOverrides         []string `json:",omitempty"`
 
 	EnforceSystemCertificate          *bool    `json:",omitempty"`
 	EnforceSystemCertificateWhitelist []string `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index 0aedb1a..46c9dcf 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -570,6 +570,11 @@
 				}
 			case executableTag:
 				if cc, ok := child.(*cc.Module); ok {
+					if !cc.Arch().Native {
+						// There is only one 'bin' directory so we shouldn't bother copying in
+						// native-bridge'd binaries and only use main ones.
+						return true
+					}
 					fileToCopy, dirInApex := getCopyManifestForExecutable(cc)
 					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, cc.Arch().ArchType, dirInApex, nativeExecutable, cc})
 					return true
diff --git a/cc/binary.go b/cc/binary.go
index 9d0cf60..65e8eb5 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -363,8 +363,10 @@
 	var sharedLibs android.Paths
 	// Ignore shared libs for static executables.
 	if !binary.static() {
-		sharedLibs = deps.SharedLibs
+		sharedLibs = deps.EarlySharedLibs
+		sharedLibs = append(sharedLibs, deps.SharedLibs...)
 		sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
+		linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
 		linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
 		linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
 	}
diff --git a/cc/cc.go b/cc/cc.go
index ee6cd4e..baee70a 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -96,9 +96,9 @@
 
 type PathDeps struct {
 	// Paths to .so files
-	SharedLibs, LateSharedLibs android.Paths
+	SharedLibs, EarlySharedLibs, LateSharedLibs android.Paths
 	// Paths to the dependencies to use for .so files (.so.toc files)
-	SharedLibsDeps, LateSharedLibsDeps android.Paths
+	SharedLibsDeps, EarlySharedLibsDeps, LateSharedLibsDeps android.Paths
 	// Paths to .a files
 	StaticLibs, LateStaticLibs, WholeStaticLibs android.Paths
 
@@ -328,6 +328,7 @@
 var (
 	sharedDepTag          = dependencyTag{name: "shared", library: true}
 	sharedExportDepTag    = dependencyTag{name: "shared", library: true, reexportFlags: true}
+	earlySharedDepTag     = dependencyTag{name: "early_shared", library: true}
 	lateSharedDepTag      = dependencyTag{name: "late shared", library: true}
 	staticDepTag          = dependencyTag{name: "static", library: true}
 	staticExportDepTag    = dependencyTag{name: "static", library: true, reexportFlags: true}
@@ -1570,6 +1571,11 @@
 			depPtr = &depPaths.SharedLibsDeps
 			depFile = ccDep.linker.(libraryInterface).toc()
 			directSharedDeps = append(directSharedDeps, ccDep)
+		case earlySharedDepTag:
+			ptr = &depPaths.EarlySharedLibs
+			depPtr = &depPaths.EarlySharedLibsDeps
+			depFile = ccDep.linker.(libraryInterface).toc()
+			directSharedDeps = append(directSharedDeps, ccDep)
 		case lateSharedDepTag, ndkLateStubDepTag:
 			ptr = &depPaths.LateSharedLibs
 			depPtr = &depPaths.LateSharedLibsDeps
@@ -1663,7 +1669,7 @@
 
 		// Export the shared libs to Make.
 		switch depTag {
-		case sharedDepTag, sharedExportDepTag, lateSharedDepTag:
+		case sharedDepTag, sharedExportDepTag, lateSharedDepTag, earlySharedDepTag:
 			if dependentLibrary, ok := ccDep.linker.(*libraryDecorator); ok {
 				if dependentLibrary.buildStubs() && android.InAnyApex(depName) {
 					// Add the dependency to the APEX(es) providing the library so that
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index cd7c410..aee16eb 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -51,11 +51,6 @@
 	}
 
 	armClangArchVariantCflags = map[string][]string{
-		"armv7-a": []string{
-			"-march=armv7-a",
-			"-mfloat-abi=softfp",
-			"-mfpu=vfpv3-d16",
-		},
 		"armv7-a-neon": []string{
 			"-march=armv7-a",
 			"-mfloat-abi=softfp",
@@ -189,8 +184,6 @@
 	pctx.StaticVariable("ArmClangThumbCflags", strings.Join(ClangFilterUnknownCflags(armThumbCflags), " "))
 
 	// Clang arch variant cflags
-	pctx.StaticVariable("ArmClangArmv7ACflags",
-		strings.Join(armClangArchVariantCflags["armv7-a"], " "))
 	pctx.StaticVariable("ArmClangArmv7ANeonCflags",
 		strings.Join(armClangArchVariantCflags["armv7-a-neon"], " "))
 	pctx.StaticVariable("ArmClangArmv8ACflags",
@@ -219,7 +212,6 @@
 
 var (
 	armClangArchVariantCflagsVar = map[string]string{
-		"armv7-a":      "${config.ArmClangArmv7ACflags}",
 		"armv7-a-neon": "${config.ArmClangArmv7ANeonCflags}",
 		"armv8-a":      "${config.ArmClangArmv8ACflags}",
 		"armv8-2a":     "${config.ArmClangArmv82ACflags}",
@@ -335,8 +327,6 @@
 		default:
 			fixCortexA8 = "-Wl,--no-fix-cortex-a8"
 		}
-	case "armv7-a":
-		fixCortexA8 = "-Wl,--fix-cortex-a8"
 	case "armv8-a", "armv8-2a":
 		// Nothing extra for armv8-a/armv8-2a
 	default:
diff --git a/cc/library.go b/cc/library.go
index 4adb081..ad07db4 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -29,27 +29,23 @@
 	"android/soong/genrule"
 )
 
+type StaticSharedLibraryProperties struct {
+	Srcs   []string `android:"arch_variant"`
+	Cflags []string `android:"arch_variant"`
+
+	Enabled            *bool    `android:"arch_variant"`
+	Whole_static_libs  []string `android:"arch_variant"`
+	Static_libs        []string `android:"arch_variant"`
+	Shared_libs        []string `android:"arch_variant"`
+	System_shared_libs []string `android:"arch_variant"`
+
+	Export_shared_lib_headers []string `android:"arch_variant"`
+	Export_static_lib_headers []string `android:"arch_variant"`
+}
+
 type LibraryProperties struct {
-	Static struct {
-		Srcs   []string `android:"arch_variant"`
-		Cflags []string `android:"arch_variant"`
-
-		Enabled            *bool    `android:"arch_variant"`
-		Whole_static_libs  []string `android:"arch_variant"`
-		Static_libs        []string `android:"arch_variant"`
-		Shared_libs        []string `android:"arch_variant"`
-		System_shared_libs []string `android:"arch_variant"`
-	} `android:"arch_variant"`
-	Shared struct {
-		Srcs   []string `android:"arch_variant"`
-		Cflags []string `android:"arch_variant"`
-
-		Enabled            *bool    `android:"arch_variant"`
-		Whole_static_libs  []string `android:"arch_variant"`
-		Static_libs        []string `android:"arch_variant"`
-		Shared_libs        []string `android:"arch_variant"`
-		System_shared_libs []string `android:"arch_variant"`
-	} `android:"arch_variant"`
+	Static StaticSharedLibraryProperties `android:"arch_variant"`
+	Shared StaticSharedLibraryProperties `android:"arch_variant"`
 
 	// local file name to pass to the linker as -unexported_symbols_list
 	Unexported_symbols_list *string `android:"arch_variant"`
@@ -539,6 +535,9 @@
 			library.Properties.Static.Whole_static_libs...)
 		deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
 		deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
+
+		deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.Properties.Static.Export_shared_lib_headers...)
+		deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.Properties.Static.Export_static_lib_headers...)
 	} else if library.shared() {
 		if ctx.toolchain().Bionic() && !Bool(library.baseLinker.Properties.Nocrt) {
 			if !ctx.useSdk() {
@@ -560,6 +559,9 @@
 		deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
 		deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
 		deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
+
+		deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.Properties.Shared.Export_shared_lib_headers...)
+		deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.Properties.Shared.Export_static_lib_headers...)
 	}
 	if ctx.useVndk() {
 		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
@@ -696,9 +698,11 @@
 		}
 	}
 
-	sharedLibs := deps.SharedLibs
+	sharedLibs := deps.EarlySharedLibs
+	sharedLibs = append(sharedLibs, deps.SharedLibs...)
 	sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
 
+	linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
 	linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
 	linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
 	linkerDeps = append(linkerDeps, objs.tidyFiles...)
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 79fbd47..90656da 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -672,10 +672,10 @@
 
 // Add the dependency to the runtime library for each of the sanitizer variants
 func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
-	if mctx.Os() != android.Android {
-		return
-	}
 	if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
+		if !c.Enabled() {
+			return
+		}
 		var sanitizers []string
 		var diagSanitizers []string
 
@@ -809,7 +809,7 @@
 				mctx.AddFarVariationDependencies([]blueprint.Variation{
 					{Mutator: "link", Variation: "shared"},
 					{Mutator: "arch", Variation: mctx.Target().String()},
-				}, sharedDepTag, runtimeLibrary)
+				}, earlySharedDepTag, runtimeLibrary)
 			}
 			// static lib does not have dependency to the runtime library. The
 			// dependency will be added to the executables or shared libs using
diff --git a/java/aar.go b/java/aar.go
index a108ba0..d08e487 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -332,7 +332,7 @@
 
 	a.Module.compile(ctx, a.aaptSrcJar)
 
-	a.aarFile = android.PathForOutput(ctx, ctx.ModuleName()+".aar")
+	a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar")
 	var res android.Paths
 	if a.androidLibraryProperties.BuildAAR {
 		BuildAAR(ctx, a.aarFile, a.outputFile, a.manifestPath, a.rTxt, res)
diff --git a/java/app.go b/java/app.go
index 45ef489..cc863e6 100644
--- a/java/app.go
+++ b/java/app.go
@@ -82,6 +82,9 @@
 	installJniLibs []jniLib
 
 	bundleFile android.Path
+
+	// the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
+	installApkName string
 }
 
 func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
@@ -215,11 +218,11 @@
 		// framework-res.apk is installed as system/framework/framework-res.apk
 		installDir = "framework"
 	} else if Bool(a.appProperties.Privileged) {
-		installDir = filepath.Join("priv-app", ctx.ModuleName())
+		installDir = filepath.Join("priv-app", a.installApkName)
 	} else {
-		installDir = filepath.Join("app", ctx.ModuleName())
+		installDir = filepath.Join("app", a.installApkName)
 	}
-	a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, ctx.ModuleName()+".apk")
+	a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
 
 	if ctx.ModuleName() != "framework-res" {
 		a.Module.compile(ctx, a.aaptSrcJar)
@@ -276,6 +279,9 @@
 }
 
 func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
+	// Check if the install APK name needs to be overridden.
+	a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(ctx.ModuleName())
+
 	// Process all building blocks, from AAPT to certificates.
 	a.aaptBuildActions(ctx)
 
@@ -307,9 +313,9 @@
 		// framework-res.apk is installed as system/framework/framework-res.apk
 		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".apk", a.outputFile)
 	} else if Bool(a.appProperties.Privileged) {
-		ctx.InstallFile(android.PathForModuleInstall(ctx, "priv-app", ctx.ModuleName()), ctx.ModuleName()+".apk", a.outputFile)
+		ctx.InstallFile(android.PathForModuleInstall(ctx, "priv-app", a.installApkName), a.installApkName+".apk", a.outputFile)
 	} else {
-		ctx.InstallFile(android.PathForModuleInstall(ctx, "app", ctx.ModuleName()), ctx.ModuleName()+".apk", a.outputFile)
+		ctx.InstallFile(android.PathForModuleInstall(ctx, "app", a.installApkName), a.installApkName+".apk", a.outputFile)
 	}
 }
 
diff --git a/java/app_builder.go b/java/app_builder.go
index 28fc4c4..5b999d8 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -122,9 +122,10 @@
 	}
 
 	ctx.Build(pctx, android.BuildParams{
-		Rule:      buildAAR,
-		Implicits: deps,
-		Output:    outputFile,
+		Rule:        buildAAR,
+		Description: "aar",
+		Implicits:   deps,
+		Output:      outputFile,
 		Args: map[string]string{
 			"manifest":   manifest.String(),
 			"classesJar": classesJarPath,
diff --git a/java/app_test.go b/java/app_test.go
index 9e2bc23..7e06dba 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -110,57 +110,55 @@
 	name                       string
 	enforceRROTargets          []string
 	enforceRROExcludedOverlays []string
-	fooOverlayFiles            []string
-	fooRRODirs                 []string
-	barOverlayFiles            []string
-	barRRODirs                 []string
+	overlayFiles               map[string][]string
+	rroDirs                    map[string][]string
 }{
 	{
 		name:                       "no RRO",
 		enforceRROTargets:          nil,
 		enforceRROExcludedOverlays: nil,
-		fooOverlayFiles: []string{
-			"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
-			"device/vendor/blah/overlay/foo/res/values/strings.xml",
+		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",
+			},
 		},
-		fooRRODirs: nil,
-		barOverlayFiles: []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,
 		},
-		barRRODirs: nil,
 	},
 	{
 		name:                       "enforce RRO on foo",
 		enforceRROTargets:          []string{"foo"},
 		enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
-		fooOverlayFiles: []string{
-			"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
+		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",
+			},
 		},
-		fooRRODirs: []string{
-			"device/vendor/blah/overlay/foo/res",
+		rroDirs: map[string][]string{
+			"foo": []string{"device/vendor/blah/overlay/foo/res"},
+			"bar": nil,
 		},
-		barOverlayFiles: []string{
-			"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
-			"device/vendor/blah/overlay/bar/res/values/strings.xml",
-		},
-		barRRODirs: nil,
 	},
 	{
 		name:                       "enforce RRO on all",
 		enforceRROTargets:          []string{"*"},
 		enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
-		fooOverlayFiles: []string{
-			"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
+		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"},
 		},
-		fooRRODirs: []string{
-			"device/vendor/blah/overlay/foo/res",
-		},
-		barOverlayFiles: []string{
-			"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
-		},
-		barRRODirs: []string{
-			"device/vendor/blah/overlay/bar/res",
+		rroDirs: map[string][]string{
+			"foo": []string{"device/vendor/blah/overlay/foo/res"},
+			"bar": []string{"device/vendor/blah/overlay/bar/res"},
 		},
 	},
 }
@@ -222,27 +220,19 @@
 				return overlayFiles, rroDirs
 			}
 
-			fooOverlayFiles, fooRRODirs := getOverlays("foo")
-			barOverlayFiles, barRRODirs := getOverlays("bar")
+			apps := []string{"foo", "bar"}
+			for _, app := range apps {
+				overlayFiles, rroDirs := getOverlays(app)
 
-			if !reflect.DeepEqual(fooOverlayFiles, testCase.fooOverlayFiles) {
-				t.Errorf("expected foo overlay files:\n  %#v\n got:\n  %#v",
-					testCase.fooOverlayFiles, fooOverlayFiles)
+				if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[app]) {
+					t.Errorf("expected %s overlay files:\n  %#v\n got:\n  %#v",
+						app, testCase.overlayFiles[app], overlayFiles)
+				}
+				if !reflect.DeepEqual(rroDirs, testCase.rroDirs[app]) {
+					t.Errorf("expected %s rroDirs:  %#v\n got:\n  %#v",
+						app, testCase.rroDirs[app], rroDirs)
+				}
 			}
-			if !reflect.DeepEqual(fooRRODirs, testCase.fooRRODirs) {
-				t.Errorf("expected foo rroDirs:  %#v\n got:\n  %#v",
-					testCase.fooRRODirs, fooRRODirs)
-			}
-
-			if !reflect.DeepEqual(barOverlayFiles, testCase.barOverlayFiles) {
-				t.Errorf("expected bar overlay files:\n  %#v\n got:\n  %#v",
-					testCase.barOverlayFiles, barOverlayFiles)
-			}
-			if !reflect.DeepEqual(barRRODirs, testCase.barRRODirs) {
-				t.Errorf("expected bar rroDirs:  %#v\n got:\n  %#v",
-					testCase.barRRODirs, barRRODirs)
-			}
-
 		})
 	}
 }
@@ -540,3 +530,66 @@
 		})
 	}
 }
+
+func TestPackageNameOverride(t *testing.T) {
+	testCases := []struct {
+		name                string
+		bp                  string
+		packageNameOverride string
+		expected            []string
+	}{
+		{
+			name: "default",
+			bp: `
+				android_app {
+					name: "foo",
+					srcs: ["a.java"],
+				}
+			`,
+			packageNameOverride: "",
+			expected: []string{
+				buildDir + "/.intermediates/foo/android_common/foo.apk",
+				buildDir + "/target/product/test_device/system/app/foo/foo.apk",
+			},
+		},
+		{
+			name: "overridden",
+			bp: `
+				android_app {
+					name: "foo",
+					srcs: ["a.java"],
+				}
+			`,
+			packageNameOverride: "foo:bar",
+			expected: []string{
+				// The package apk should be still be the original name for test dependencies.
+				buildDir + "/.intermediates/foo/android_common/foo.apk",
+				buildDir + "/target/product/test_device/system/app/bar/bar.apk",
+			},
+		},
+	}
+
+	for _, test := range testCases {
+		t.Run(test.name, func(t *testing.T) {
+			config := testConfig(nil)
+			if test.packageNameOverride != "" {
+				config.TestProductVariables.PackageNameOverrides = []string{test.packageNameOverride}
+			}
+			ctx := testAppContext(config, test.bp, nil)
+
+			run(t, ctx, config)
+			foo := ctx.ModuleForTests("foo", "android_common")
+
+			outputs := foo.AllOutputs()
+			outputMap := make(map[string]bool)
+			for _, o := range outputs {
+				outputMap[o] = true
+			}
+			for _, e := range test.expected {
+				if _, exist := outputMap[e]; !exist {
+					t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
+				}
+			}
+		})
+	}
+}
diff --git a/java/builder.go b/java/builder.go
index df17f7b..7aac881 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -47,7 +47,8 @@
 				`$processorpath $processor $javacFlags $bootClasspath $classpath ` +
 				`-source $javaVersion -target $javaVersion ` +
 				`-d $outDir -s $annoDir @$out.rsp @$srcJarDir/list ; fi ) && ` +
-				`${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir`,
+				`${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir && ` +
+				`rm -rf "$srcJarDir"`,
 			CommandDeps: []string{
 				"${config.JavacCmd}",
 				"${config.SoongZipCmd}",
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 0d2842a..01e2989 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -34,7 +34,9 @@
 				`$opts $bootclasspathArgs $classpathArgs $sourcepathArgs ` +
 				`-d $outDir -quiet  && ` +
 				`${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
-				`${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir $postDoclavaCmds`,
+				`${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir $postDoclavaCmds && ` +
+				`rm -rf "$srcJarDir"`,
+
 			CommandDeps: []string{
 				"${config.ZipSyncCmd}",
 				"${config.JavadocCmd}",
@@ -74,7 +76,8 @@
 				`${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
 				`$bootclasspathArgs $classpathArgs $sourcepathArgs --no-banner --color --quiet --format=v2 ` +
 				`$opts && ` +
-				`${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir`,
+				`${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir && ` +
+				`rm -rf "$srcJarDir"`,
 			CommandDeps: []string{
 				"${config.ZipSyncCmd}",
 				"${config.JavaCmd}",
@@ -94,7 +97,7 @@
 				`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
 				`${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
 				`$bootclasspathArgs $classpathArgs $sourcepathArgs --no-banner --color --quiet --format=v2 ` +
-				`$opts && touch $out ) || ` +
+				`$opts && touch $out && rm -rf "$srcJarDir") || ` +
 				`( echo -e "$msg" ; exit 38 )`,
 			CommandDeps: []string{
 				"${config.ZipSyncCmd}",
@@ -120,7 +123,8 @@
 				`${config.JavaCmd} -jar ${config.DokkaJar} $srcJarDir ` +
 				`$classpathArgs -format dac -dacRoot /reference/kotlin -output $outDir $opts && ` +
 				`${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
-				`${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir`,
+				`${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir && ` +
+				`rm -rf "$srcJarDir"`,
 			CommandDeps: []string{
 				"${config.ZipSyncCmd}",
 				"${config.DokkaJar}",
@@ -1500,7 +1504,7 @@
 					}
 				}
 				*implicits = append(*implicits, androidJars...)
-				flags += " --android-jar-pattern " + t.dir.String() + "/%/android.jar "
+				flags += " --android-jar-pattern " + t.dir.String() + "/%/public/android.jar "
 			} else {
 				ctx.PropertyErrorf("api_levels_annotations_dirs",
 					"module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
@@ -1570,7 +1574,7 @@
 
 func (d *Droidstubs) transformCheckApi(ctx android.ModuleContext,
 	apiFile, removedApiFile android.Path, implicits android.Paths,
-	javaVersion, bootclasspathArgs, classpathArgs, sourcepathArgs, opts, msg string,
+	javaVersion, bootclasspathArgs, classpathArgs, sourcepathArgs, opts, subdir, msg string,
 	output android.WritablePath) {
 	ctx.Build(pctx, android.BuildParams{
 		Rule:        metalavaApiCheck,
@@ -1580,7 +1584,7 @@
 		Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
 			implicits...),
 		Args: map[string]string{
-			"srcJarDir":         android.PathForModuleOut(ctx, "apicheck-srcjars").String(),
+			"srcJarDir":         android.PathForModuleOut(ctx, subdir, "srcjars").String(),
 			"srcJars":           strings.Join(d.Javadoc.srcJars.Strings(), " "),
 			"javaVersion":       javaVersion,
 			"bootclasspathArgs": bootclasspathArgs,
@@ -1669,7 +1673,7 @@
 			flags.metalavaInclusionAnnotationsFlags + flags.metalavaMergeAnnoDirFlags + " "
 
 		d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
-			javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts,
+			javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "current-apicheck",
 			fmt.Sprintf(`\n******************************\n`+
 				`You have tried to change the API from what has been previously approved.\n\n`+
 				`To make these errors go away, you have two choices:\n`+
@@ -1700,7 +1704,7 @@
 			removedApiFile.String() + flags.metalavaMergeAnnoDirFlags + " "
 
 		d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
-			javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts,
+			javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "last-apicheck",
 			`\n******************************\n`+
 				`You have tried to change the API from what has been previously released in\n`+
 				`an SDK.  Please fix the errors listed above.\n`+
diff --git a/java/java.go b/java/java.go
index b070639..230e8f2 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1421,10 +1421,10 @@
 }
 
 func (j *Library) shouldUncompressDex(ctx android.ModuleContext) bool {
-	// Store uncompressed (and do not strip) dex files from boot class path jars that are not
-	// part of the boot image.
+	// Store uncompressed (and do not strip) dex files from boot class path jars that are
+	// in an apex.
 	if inList(ctx.ModuleName(), ctx.Config().BootJars()) &&
-		!inList(ctx.ModuleName(), ctx.Config().PreoptBootJars()) {
+		android.DirectlyInAnyApex(ctx, ctx.ModuleName()) {
 		return true
 	}
 	return false
diff --git a/java/kotlin.go b/java/kotlin.go
index 9c47f98..81b89f9 100644
--- a/java/kotlin.go
+++ b/java/kotlin.go
@@ -32,7 +32,8 @@
 			`${config.GenKotlinBuildFileCmd} $classpath $classesDir $out.rsp $srcJarDir/list > $kotlinBuildFile &&` +
 			`${config.KotlincCmd} ${config.JavacHeapFlags} $kotlincFlags ` +
 			`-jvm-target $kotlinJvmTarget -Xbuild-file=$kotlinBuildFile && ` +
-			`${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir`,
+			`${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir && ` +
+			`rm -rf "$srcJarDir"`,
 		CommandDeps: []string{
 			"${config.KotlincCmd}",
 			"${config.KotlinCompilerJar}",
@@ -89,7 +90,8 @@
 			`$kaptProcessorPath ` +
 			`$kaptProcessor ` +
 			`-Xbuild-file=$kotlinBuildFile && ` +
-			`${config.SoongZipCmd} -jar -o $out -C $kaptDir/sources -D $kaptDir/sources`,
+			`${config.SoongZipCmd} -jar -o $out -C $kaptDir/sources -D $kaptDir/sources && ` +
+			`rm -rf "$srcJarDir"`,
 		CommandDeps: []string{
 			"${config.KotlincCmd}",
 			"${config.KotlinCompilerJar}",
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 531c5d5..17decd0 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -78,7 +78,6 @@
 	"bash":      Allowed,
 	"bc":        Allowed,
 	"bzip2":     Allowed,
-	"cp":        Allowed,
 	"date":      Allowed,
 	"dd":        Allowed,
 	"diff":      Allowed,
@@ -90,7 +89,6 @@
 	"grep":      Allowed,
 	"gzip":      Allowed,
 	"hexdump":   Allowed,
-	"hostname":  Allowed,
 	"jar":       Allowed,
 	"java":      Allowed,
 	"javap":     Allowed,
@@ -133,6 +131,7 @@
 	"cat":       Toybox,
 	"chmod":     Toybox,
 	"cmp":       Toybox,
+	"cp":        Toybox,
 	"comm":      Toybox,
 	"cut":       Toybox,
 	"dirname":   Toybox,
@@ -142,6 +141,7 @@
 	"expr":      Toybox,
 	"head":      Toybox,
 	"getconf":   Toybox,
+	"hostname":  Toybox,
 	"id":        Toybox,
 	"ln":        Toybox,
 	"ls":        Toybox,