Merge "fix: Override vndk-ext lib name with original lib"
diff --git a/Android.bp b/Android.bp
index dd53818..20d45e5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -45,6 +45,7 @@
         "android/api_levels.go",
         "android/arch.go",
         "android/config.go",
+        "android/csuite_config.go",
         "android/defaults.go",
         "android/defs.go",
         "android/expand.go",
@@ -85,6 +86,7 @@
         "android/androidmk_test.go",
         "android/arch_test.go",
         "android/config_test.go",
+        "android/csuite_config_test.go",
         "android/expand_test.go",
         "android/module_test.go",
         "android/mutator_test.go",
@@ -294,6 +296,7 @@
         "java/support_libraries.go",
         "java/system_modules.go",
         "java/testing.go",
+        "java/tradefed.go",
     ],
     testSrcs: [
         "java/androidmk_test.go",
@@ -338,6 +341,7 @@
         "rust/config/global.go",
         "rust/config/toolchain.go",
         "rust/config/whitelist.go",
+        "rust/config/x86_darwin_host.go",
         "rust/config/x86_linux_host.go",
         "rust/config/x86_64_device.go",
     ],
diff --git a/android/csuite_config.go b/android/csuite_config.go
new file mode 100644
index 0000000..15c518a
--- /dev/null
+++ b/android/csuite_config.go
@@ -0,0 +1,70 @@
+// 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 (
+	"fmt"
+	"io"
+)
+
+func init() {
+	RegisterModuleType("csuite_config", CSuiteConfigFactory)
+}
+
+type csuiteConfigProperties struct {
+	// Override the default (AndroidTest.xml) test manifest file name.
+	Test_config *string
+}
+
+type CSuiteConfig struct {
+	ModuleBase
+	properties     csuiteConfigProperties
+	OutputFilePath OutputPath
+}
+
+func (me *CSuiteConfig) GenerateAndroidBuildActions(ctx ModuleContext) {
+	me.OutputFilePath = PathForModuleOut(ctx, me.BaseModuleName()).OutputPath
+}
+
+func (me *CSuiteConfig) AndroidMk() AndroidMkData {
+	androidMkData := AndroidMkData{
+		Class:      "FAKE",
+		Include:    "$(BUILD_SYSTEM)/suite_host_config.mk",
+		OutputFile: OptionalPathForPath(me.OutputFilePath),
+	}
+	androidMkData.Extra = []AndroidMkExtraFunc{
+		func(w io.Writer, outputFile Path) {
+			if me.properties.Test_config != nil {
+				fmt.Fprintf(w, "LOCAL_TEST_CONFIG := %s\n",
+					*me.properties.Test_config)
+			}
+			fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE := csuite")
+		},
+	}
+	return androidMkData
+}
+
+func InitCSuiteConfigModule(me *CSuiteConfig) {
+	me.AddProperties(&me.properties)
+}
+
+// csuite_config generates an App Compatibility Test Suite (C-Suite) configuration file from the
+// <test_config> xml file and stores it in a subdirectory of $(HOST_OUT).
+func CSuiteConfigFactory() Module {
+	module := &CSuiteConfig{}
+	InitCSuiteConfigModule(module)
+	InitAndroidArchModule(module, HostSupported, MultilibFirst)
+	return module
+}
diff --git a/android/csuite_config_test.go b/android/csuite_config_test.go
new file mode 100644
index 0000000..e534bb7
--- /dev/null
+++ b/android/csuite_config_test.go
@@ -0,0 +1,53 @@
+// 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 (
+	"testing"
+)
+
+func testCSuiteConfig(test *testing.T, bpFileContents string) *TestContext {
+	config := TestArchConfig(buildDir, nil)
+
+	ctx := NewTestArchContext()
+	ctx.RegisterModuleType("csuite_config", ModuleFactoryAdaptor(CSuiteConfigFactory))
+	ctx.Register()
+	mockFiles := map[string][]byte{
+		"Android.bp": []byte(bpFileContents),
+	}
+	ctx.MockFileSystem(mockFiles)
+	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+	FailIfErrored(test, errs)
+	_, errs = ctx.PrepareBuildActions(config)
+	FailIfErrored(test, errs)
+	return ctx
+}
+
+func TestCSuiteConfig(t *testing.T) {
+	ctx := testCSuiteConfig(t, `
+csuite_config { name: "plain"}
+csuite_config { name: "with_manifest", test_config: "manifest.xml" }
+`)
+
+	variants := ctx.ModuleVariantsForTests("plain")
+	if len(variants) > 1 {
+		t.Errorf("expected 1, got %d", len(variants))
+	}
+	expectedOutputFilename := ctx.ModuleForTests(
+		"plain", variants[0]).Module().(*CSuiteConfig).OutputFilePath.Base()
+	if expectedOutputFilename != "plain" {
+		t.Errorf("expected plain, got %q", expectedOutputFilename)
+	}
+}
diff --git a/android/vts_config.go b/android/vts_config.go
index c44b3a3..86f6e72 100644
--- a/android/vts_config.go
+++ b/android/vts_config.go
@@ -41,16 +41,17 @@
 func (me *VtsConfig) AndroidMk() AndroidMkData {
 	androidMkData := AndroidMkData{
 		Class:      "FAKE",
-		Include:    "$(BUILD_SYSTEM)/android_vts_host_config.mk",
+		Include:    "$(BUILD_SYSTEM)/suite_host_config.mk",
 		OutputFile: OptionalPathForPath(me.OutputFilePath),
 	}
-	if me.properties.Test_config != nil {
-		androidMkData.Extra = []AndroidMkExtraFunc{
-			func(w io.Writer, outputFile Path) {
+	androidMkData.Extra = []AndroidMkExtraFunc{
+		func(w io.Writer, outputFile Path) {
+			if me.properties.Test_config != nil {
 				fmt.Fprintf(w, "LOCAL_TEST_CONFIG := %s\n",
 					*me.properties.Test_config)
-			},
-		}
+			}
+			fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE := vts")
+		},
 	}
 	return androidMkData
 }
diff --git a/cc/config/x86_darwin_host.go b/cc/config/x86_darwin_host.go
index 1026370..63b9d48 100644
--- a/cc/config/x86_darwin_host.go
+++ b/cc/config/x86_darwin_host.go
@@ -63,6 +63,7 @@
 		"10.12",
 		"10.13",
 		"10.14",
+		"10.15",
 	}
 
 	darwinAvailableLibraries = append(
diff --git a/cc/object.go b/cc/object.go
index 1f1ac8e..31729a5 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -104,7 +104,7 @@
 	var outputFile android.Path
 	builderFlags := flagsToBuilderFlags(flags)
 
-	if len(objs.objFiles) == 1 {
+	if len(objs.objFiles) == 1 && String(object.Properties.Linker_script) == "" {
 		outputFile = objs.objFiles[0]
 
 		if String(object.Properties.Prefix_symbols) != "" {
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index f39ec4a..9215eff 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -24,8 +24,6 @@
 
 // GlobalConfig stores the configuration for dex preopting set by the product
 type GlobalConfig struct {
-	DefaultNoStripping bool // don't strip dex files by default
-
 	DisablePreopt        bool     // disable preopt for all modules
 	DisablePreoptModules []string // modules with preopt disabled by product-specific config
 
@@ -55,8 +53,7 @@
 	DefaultCompilerFilter      string // default compiler filter to pass to dex2oat, overridden by --compiler-filter= in module-specific dex2oat flags
 	SystemServerCompilerFilter string // default compiler filter to pass to dex2oat for system server jars
 
-	GenerateDMFiles     bool // generate Dex Metadata files
-	NeverAllowStripping bool // whether stripping should not be done - used as build time check to make sure dex files are always available
+	GenerateDMFiles bool // generate Dex Metadata files
 
 	NoDebugInfo                 bool // don't generate debug info by default
 	DontResolveStartupStrings   bool // don't resolve string literals loaded during application startup.
@@ -133,10 +130,6 @@
 	ForceCreateAppImage bool
 
 	PresignedPrebuilt bool
-
-	NoStripping     bool
-	StripInputPath  android.Path
-	StripOutputPath android.WritablePath
 }
 
 func constructPath(ctx android.PathContext, path string) android.Path {
@@ -233,8 +226,6 @@
 		LibraryPaths                map[string]string
 		DexPreoptImages             []string
 		PreoptBootClassPathDexFiles []string
-		StripInputPath              string
-		StripOutputPath             string
 	}
 
 	config := ModuleJSONConfig{}
@@ -252,8 +243,6 @@
 	config.ModuleConfig.LibraryPaths = constructPathMap(ctx, config.LibraryPaths)
 	config.ModuleConfig.DexPreoptImages = constructPaths(ctx, config.DexPreoptImages)
 	config.ModuleConfig.PreoptBootClassPathDexFiles = constructPaths(ctx, config.PreoptBootClassPathDexFiles)
-	config.ModuleConfig.StripInputPath = constructPath(ctx, config.StripInputPath)
-	config.ModuleConfig.StripOutputPath = constructWritablePath(ctx, config.StripOutputPath)
 
 	// This needs to exist, but dependencies are already handled in Make, so we don't need to pass them through JSON.
 	config.ModuleConfig.DexPreoptImagesDeps = make([]android.Paths, len(config.ModuleConfig.DexPreoptImages))
@@ -283,7 +272,6 @@
 
 func GlobalConfigForTests(ctx android.PathContext) GlobalConfig {
 	return GlobalConfig{
-		DefaultNoStripping:                 false,
 		DisablePreopt:                      false,
 		DisablePreoptModules:               nil,
 		OnlyPreoptBootImageAndSystemServer: false,
@@ -302,7 +290,6 @@
 		DefaultCompilerFilter:              "",
 		SystemServerCompilerFilter:         "",
 		GenerateDMFiles:                    false,
-		NeverAllowStripping:                false,
 		NoDebugInfo:                        false,
 		DontResolveStartupStrings:          false,
 		AlwaysSystemServerDebugInfo:        false,
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 511b840..46e0f0a 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 // The dexpreopt package converts a global dexpreopt config and a module dexpreopt config into rules to perform
-// dexpreopting and to strip the dex files from the APK or JAR.
+// dexpreopting.
 //
 // It is used in two places; in the dexpeopt_gen binary for modules defined in Make, and directly linked into Soong.
 //
@@ -22,8 +22,7 @@
 // changed.  One script takes an APK or JAR as an input and produces a zip file containing any outputs of preopting,
 // in the location they should be on the device.  The Make build rules will unzip the zip file into $(PRODUCT_OUT) when
 // installing the APK, which will install the preopt outputs into $(PRODUCT_OUT)/system or $(PRODUCT_OUT)/system_other
-// as necessary.  The zip file may be empty if preopting was disabled for any reason.  The second script takes an APK or
-// JAR as an input and strips the dex files in it as necessary.
+// as necessary.  The zip file may be empty if preopting was disabled for any reason.
 //
 // The intermediate shell scripts allow changes to this package or to the global config to regenerate the shell scripts
 // but only require re-executing preopting if the script has changed.
@@ -48,45 +47,6 @@
 const SystemPartition = "/system/"
 const SystemOtherPartition = "/system_other/"
 
-// GenerateStripRule generates a set of commands that will take an APK or JAR as an input and strip the dex files if
-// they are no longer necessary after preopting.
-func GenerateStripRule(global GlobalConfig, module ModuleConfig) (rule *android.RuleBuilder, err error) {
-	defer func() {
-		if r := recover(); r != nil {
-			if _, ok := r.(runtime.Error); ok {
-				panic(r)
-			} else if e, ok := r.(error); ok {
-				err = e
-				rule = nil
-			} else {
-				panic(r)
-			}
-		}
-	}()
-
-	tools := global.Tools
-
-	rule = android.NewRuleBuilder()
-
-	strip := shouldStripDex(module, global)
-
-	if strip {
-		if global.NeverAllowStripping {
-			panic(fmt.Errorf("Stripping requested on %q, though the product does not allow it", module.DexLocation))
-		}
-		// Only strips if the dex files are not already uncompressed
-		rule.Command().
-			Textf(`if (zipinfo %s '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, module.StripInputPath).
-			Tool(tools.Zip2zip).FlagWithInput("-i ", module.StripInputPath).FlagWithOutput("-o ", module.StripOutputPath).
-			FlagWithArg("-x ", `"classes*.dex"`).
-			Textf(`; else cp -f %s %s; fi`, module.StripInputPath, module.StripOutputPath)
-	} else {
-		rule.Command().Text("cp -f").Input(module.StripInputPath).Output(module.StripOutputPath)
-	}
-
-	return rule, nil
-}
-
 // GenerateDexpreoptRule generates a set of commands that will preopt a module based on a GlobalConfig and a
 // ModuleConfig.  The produced files and their install locations will be available through rule.Installs().
 func GenerateDexpreoptRule(ctx android.PathContext,
@@ -120,7 +80,6 @@
 
 	if !dexpreoptDisabled(global, module) {
 		// Don't preopt individual boot jars, they will be preopted together.
-		// This check is outside dexpreoptDisabled because they still need to be stripped.
 		if !contains(global.BootJars, module.Name) {
 			appImage := (generateProfile || module.ForceCreateAppImage || global.DefaultAppImages) &&
 				!module.NoCreateAppImage
@@ -515,51 +474,6 @@
 	rule.Install(vdexPath, vdexInstallPath)
 }
 
-// Return if the dex file in the APK should be stripped.  If an APK is found to contain uncompressed dex files at
-// dex2oat time it will not be stripped even if strip=true.
-func shouldStripDex(module ModuleConfig, global GlobalConfig) bool {
-	strip := !global.DefaultNoStripping
-
-	if dexpreoptDisabled(global, module) {
-		strip = false
-	}
-
-	if module.NoStripping {
-		strip = false
-	}
-
-	// Don't strip modules that are not on the system partition in case the oat/vdex version in system ROM
-	// doesn't match the one in other partitions. It needs to be able to fall back to the APK for that case.
-	if !strings.HasPrefix(module.DexLocation, SystemPartition) {
-		strip = false
-	}
-
-	// system_other isn't there for an OTA, so don't strip if module is on system, and odex is on system_other.
-	if odexOnSystemOther(module, global) {
-		strip = false
-	}
-
-	if module.HasApkLibraries {
-		strip = false
-	}
-
-	// Don't strip with dex files we explicitly uncompress (dexopt will not store the dex code).
-	if module.UncompressedDex {
-		strip = false
-	}
-
-	if shouldGenerateDM(module, global) {
-		strip = false
-	}
-
-	if module.PresignedPrebuilt {
-		// Only strip out files if we can re-sign the package.
-		strip = false
-	}
-
-	return strip
-}
-
 func shouldGenerateDM(module ModuleConfig, global GlobalConfig) bool {
 	// Generating DM files only makes sense for verify, avoid doing for non verify compiler filter APKs.
 	// No reason to use a dm file if the dex is already uncompressed.
diff --git a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
index d54ddb1..009e906 100644
--- a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
+++ b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
@@ -31,7 +31,6 @@
 
 var (
 	dexpreoptScriptPath = flag.String("dexpreopt_script", "", "path to output dexpreopt script")
-	stripScriptPath     = flag.String("strip_script", "", "path to output strip script")
 	globalConfigPath    = flag.String("global", "", "path to global configuration file")
 	moduleConfigPath    = flag.String("module", "", "path to module configuration file")
 	outDir              = flag.String("out_dir", "", "path to output directory")
@@ -64,10 +63,6 @@
 		usage("path to output dexpreopt script is required")
 	}
 
-	if *stripScriptPath == "" {
-		usage("path to output strip script is required")
-	}
-
 	if *globalConfigPath == "" {
 		usage("path to global configuration file is required")
 	}
@@ -90,10 +85,6 @@
 		os.Exit(2)
 	}
 
-	// This shouldn't be using *PathForTesting, but it's outside of soong_build so its OK for now.
-	moduleConfig.StripInputPath = android.PathForTesting("$1")
-	moduleConfig.StripOutputPath = android.WritablePathForTesting("$2")
-
 	moduleConfig.DexPath = android.PathForTesting("$1")
 
 	defer func() {
@@ -110,11 +101,11 @@
 		}
 	}()
 
-	writeScripts(ctx, globalConfig, moduleConfig, *dexpreoptScriptPath, *stripScriptPath)
+	writeScripts(ctx, globalConfig, moduleConfig, *dexpreoptScriptPath)
 }
 
 func writeScripts(ctx android.PathContext, global dexpreopt.GlobalConfig, module dexpreopt.ModuleConfig,
-	dexpreoptScriptPath, stripScriptPath string) {
+	dexpreoptScriptPath string) {
 	dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, global, module)
 	if err != nil {
 		panic(err)
@@ -135,11 +126,6 @@
 		FlagWithArg("-C ", installDir.String()).
 		FlagWithArg("-D ", installDir.String())
 
-	stripRule, err := dexpreopt.GenerateStripRule(global, module)
-	if err != nil {
-		panic(err)
-	}
-
 	write := func(rule *android.RuleBuilder, file string) {
 		script := &bytes.Buffer{}
 		script.WriteString(scriptHeader)
@@ -180,15 +166,8 @@
 	if module.DexPath.String() != "$1" {
 		panic(fmt.Errorf("module.DexPath must be '$1', was %q", module.DexPath))
 	}
-	if module.StripInputPath.String() != "$1" {
-		panic(fmt.Errorf("module.StripInputPath must be '$1', was %q", module.StripInputPath))
-	}
-	if module.StripOutputPath.String() != "$2" {
-		panic(fmt.Errorf("module.StripOutputPath must be '$2', was %q", module.StripOutputPath))
-	}
 
 	write(dexpreoptRule, dexpreoptScriptPath)
-	write(stripRule, stripScriptPath)
 }
 
 const scriptHeader = `#!/bin/bash
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index bf692fe..6f8120e 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -17,8 +17,6 @@
 import (
 	"android/soong/android"
 	"fmt"
-	"reflect"
-	"strings"
 	"testing"
 )
 
@@ -58,9 +56,6 @@
 		NoCreateAppImage:                false,
 		ForceCreateAppImage:             false,
 		PresignedPrebuilt:               false,
-		NoStripping:                     false,
-		StripInputPath:                  android.PathForOutput(ctx, fmt.Sprintf("unstripped/%s.apk", name)),
-		StripOutputPath:                 android.PathForOutput(ctx, fmt.Sprintf("stripped/%s.apk", name)),
 	}
 }
 
@@ -83,20 +78,6 @@
 	}
 }
 
-func TestDexPreoptStrip(t *testing.T) {
-	// Test that we panic if we strip in a configuration where stripping is not allowed.
-	ctx := android.PathContextForTesting(android.TestConfig("out", nil), nil)
-	global, module := GlobalConfigForTests(ctx), testSystemModuleConfig(ctx, "test")
-
-	global.NeverAllowStripping = true
-	module.NoStripping = false
-
-	_, err := GenerateStripRule(global, module)
-	if err == nil {
-		t.Errorf("Expected an error when calling GenerateStripRule on a stripped module")
-	}
-}
-
 func TestDexPreoptSystemOther(t *testing.T) {
 	ctx := android.PathContextForTesting(android.TestConfig("out", nil), nil)
 	global := GlobalConfigForTests(ctx)
@@ -176,56 +157,3 @@
 		t.Errorf("\nwant installs:\n   %v\ngot:\n   %v", wantInstalls, rule.Installs())
 	}
 }
-
-func TestStripDex(t *testing.T) {
-	tests := []struct {
-		name  string
-		setup func(global *GlobalConfig, module *ModuleConfig)
-		strip bool
-	}{
-		{
-			name:  "default strip",
-			setup: func(global *GlobalConfig, module *ModuleConfig) {},
-			strip: true,
-		},
-		{
-			name:  "global no stripping",
-			setup: func(global *GlobalConfig, module *ModuleConfig) { global.DefaultNoStripping = true },
-			strip: false,
-		},
-		{
-			name:  "module no stripping",
-			setup: func(global *GlobalConfig, module *ModuleConfig) { module.NoStripping = true },
-			strip: false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-
-			ctx := android.PathContextForTesting(android.TestConfig("out", nil), nil)
-			global, module := GlobalConfigForTests(ctx), testSystemModuleConfig(ctx, "test")
-
-			test.setup(&global, &module)
-
-			rule, err := GenerateStripRule(global, module)
-			if err != nil {
-				t.Fatal(err)
-			}
-
-			if test.strip {
-				want := `zip2zip -i out/unstripped/test.apk -o out/stripped/test.apk -x "classes*.dex"`
-				if len(rule.Commands()) < 1 || !strings.Contains(rule.Commands()[0], want) {
-					t.Errorf("\nwant commands[0] to have:\n   %v\ngot:\n   %v", want, rule.Commands()[0])
-				}
-			} else {
-				wantCommands := []string{
-					"cp -f out/unstripped/test.apk out/stripped/test.apk",
-				}
-				if !reflect.DeepEqual(rule.Commands(), wantCommands) {
-					t.Errorf("\nwant commands:\n   %v\ngot:\n   %v", wantCommands, rule.Commands())
-				}
-			}
-		})
-	}
-}
diff --git a/java/androidmk.go b/java/androidmk.go
index 7927acf..9e9b277 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -534,6 +534,9 @@
 				if dstubs.jdiffDocZip != nil {
 					entries.SetPath("LOCAL_DROIDDOC_JDIFF_DOC_ZIP", dstubs.jdiffDocZip)
 				}
+				if dstubs.metadataZip != nil {
+					entries.SetPath("LOCAL_DROIDDOC_METADATA_ZIP", dstubs.metadataZip)
+				}
 				apiFilePrefix := "INTERNAL_PLATFORM_"
 				if String(dstubs.properties.Api_tag_name) != "" {
 					apiFilePrefix += String(dstubs.properties.Api_tag_name) + "_"
diff --git a/java/app_test.go b/java/app_test.go
index f2aaec3..05ab856 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1149,13 +1149,7 @@
 		variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
 		t.Errorf("can't find dexpreopt outputs")
 	}
-	// Make sure stripping wasn't done.
-	stripRule := variant.Output("dexpreopt/foo.apk")
-	if !strings.HasPrefix(stripRule.RuleParams.Command, "cp -f") {
-		t.Errorf("unexpected, non-skipping strip command: %q", stripRule.RuleParams.Command)
-	}
-
-	// Make sure signing was skipped and aligning was done instead.
+	// Make sure signing was skipped and aligning was done.
 	if variant.MaybeOutput("signed/foo.apk").Rule != nil {
 		t.Errorf("signing rule shouldn't be included.")
 	}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index b48871e..2b1c994 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -40,13 +40,9 @@
 
 type DexpreoptProperties struct {
 	Dex_preopt struct {
-		// If false, prevent dexpreopting and stripping the dex file from the final jar.  Defaults to
-		// true.
+		// If false, prevent dexpreopting.  Defaults to true.
 		Enabled *bool
 
-		// If true, never strip the dex files from the final jar when dexpreopting.  Defaults to false.
-		No_stripping *bool
-
 		// If true, generate an app image (.art file) for this module.
 		App_image *bool
 
@@ -136,8 +132,6 @@
 
 	dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath)
 
-	strippedDexJarFile := android.PathForModuleOut(ctx, "dexpreopt", dexJarFile.Base())
-
 	var profileClassListing android.OptionalPath
 	var profileBootListing android.OptionalPath
 	profileIsTextListing := false
@@ -191,10 +185,6 @@
 		ForceCreateAppImage: BoolDefault(d.dexpreoptProperties.Dex_preopt.App_image, false),
 
 		PresignedPrebuilt: d.isPresignedPrebuilt,
-
-		NoStripping:     Bool(d.dexpreoptProperties.Dex_preopt.No_stripping),
-		StripInputPath:  dexJarFile,
-		StripOutputPath: strippedDexJarFile.OutputPath,
 	}
 
 	dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, global, dexpreoptConfig)
@@ -207,13 +197,5 @@
 
 	d.builtInstalled = dexpreoptRule.Installs().String()
 
-	stripRule, err := dexpreopt.GenerateStripRule(global, dexpreoptConfig)
-	if err != nil {
-		ctx.ModuleErrorf("error generating dexpreopt strip rule: %s", err.Error())
-		return dexJarFile
-	}
-
-	stripRule.Build(pctx, ctx, "dexpreopt_strip", "dexpreopt strip")
-
-	return strippedDexJarFile
+	return dexJarFile
 }
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 043f9da..429bbdb 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -96,80 +96,9 @@
 	return targets
 }
 
-// defaultBootImageConfig returns the bootImageConfig that will be used to dexpreopt modules.  It is computed once the
-// first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same
-// ctx.Config().
-func defaultBootImageConfig(ctx android.PathContext) bootImageConfig {
-	return ctx.Config().Once(defaultBootImageConfigKey, func() interface{} {
-		global := dexpreoptGlobalConfig(ctx)
-
-		artModules := global.ArtApexJars
-		nonFrameworkModules := concat(artModules, global.ProductUpdatableBootModules)
-		frameworkModules := android.RemoveListFromList(global.BootJars, nonFrameworkModules)
-
-		var nonUpdatableBootModules []string
-		var nonUpdatableBootLocations []string
-
-		for _, m := range artModules {
-			nonUpdatableBootModules = append(nonUpdatableBootModules, m)
-			nonUpdatableBootLocations = append(nonUpdatableBootLocations,
-				filepath.Join("/apex/com.android.art/javalib", m+".jar"))
-		}
-
-		for _, m := range frameworkModules {
-			nonUpdatableBootModules = append(nonUpdatableBootModules, m)
-			nonUpdatableBootLocations = append(nonUpdatableBootLocations,
-				filepath.Join("/system/framework", m+".jar"))
-		}
-
-		// The path to bootclasspath dex files needs to be known at module GenerateAndroidBuildAction time, before
-		// the bootclasspath modules have been compiled.  Set up known paths for them, the singleton rules will copy
-		// them there.
-		// TODO: use module dependencies instead
-		var nonUpdatableBootDexPaths android.WritablePaths
-		for _, m := range nonUpdatableBootModules {
-			nonUpdatableBootDexPaths = append(nonUpdatableBootDexPaths,
-				android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars_input", m+".jar"))
-		}
-
-		dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars")
-		symbolsDir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars_unstripped")
-		zip := dir.Join(ctx, "boot.zip")
-
-		targets := dexpreoptTargets(ctx)
-
-		imageConfig := bootImageConfig{
-			name:         "boot",
-			modules:      nonUpdatableBootModules,
-			dexLocations: nonUpdatableBootLocations,
-			dexPaths:     nonUpdatableBootDexPaths,
-			dir:          dir,
-			symbolsDir:   symbolsDir,
-			images:       make(map[android.ArchType]android.OutputPath),
-			imagesDeps:   make(map[android.ArchType]android.Paths),
-			targets:      targets,
-			zip:          zip,
-		}
-
-		for _, target := range targets {
-			imageDir := dir.Join(ctx, "system/framework", target.Arch.ArchType.String())
-			imageConfig.images[target.Arch.ArchType] = imageDir.Join(ctx, "boot.art")
-
-			imagesDeps := make([]android.Path, 0, len(imageConfig.modules)*3)
-			for _, dep := range imageConfig.moduleFiles(ctx, imageDir, ".art", ".oat", ".vdex") {
-				imagesDeps = append(imagesDeps, dep)
-			}
-			imageConfig.imagesDeps[target.Arch.ArchType] = imagesDeps
-		}
-
-		return imageConfig
-	}).(bootImageConfig)
-}
-
-var defaultBootImageConfigKey = android.NewOnceKey("defaultBootImageConfig")
-
-func apexBootImageConfig(ctx android.PathContext) bootImageConfig {
-	return ctx.Config().Once(apexBootImageConfigKey, func() interface{} {
+func getBootImageConfig(ctx android.PathContext, key android.OnceKey, name string,
+	needZip bool) bootImageConfig {
+	return ctx.Config().Once(key, func() interface{} {
 		global := dexpreoptGlobalConfig(ctx)
 
 		artModules := global.ArtApexJars
@@ -196,16 +125,21 @@
 		var bootDexPaths android.WritablePaths
 		for _, m := range imageModules {
 			bootDexPaths = append(bootDexPaths,
-				android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars_input", m+".jar"))
+				android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_"+name+"jars_input", m+".jar"))
 		}
 
-		dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars")
-		symbolsDir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars_unstripped")
+		dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_"+name+"jars")
+		symbolsDir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_"+name+"jars_unstripped")
+
+		var zip android.WritablePath
+		if needZip {
+			zip = dir.Join(ctx, name+".zip")
+		}
 
 		targets := dexpreoptTargets(ctx)
 
 		imageConfig := bootImageConfig{
-			name:         "apex",
+			name:         name,
 			modules:      imageModules,
 			dexLocations: bootLocations,
 			dexPaths:     bootDexPaths,
@@ -214,11 +148,12 @@
 			targets:      targets,
 			images:       make(map[android.ArchType]android.OutputPath),
 			imagesDeps:   make(map[android.ArchType]android.Paths),
+			zip:          zip,
 		}
 
 		for _, target := range targets {
 			imageDir := dir.Join(ctx, "system/framework", target.Arch.ArchType.String())
-			imageConfig.images[target.Arch.ArchType] = imageDir.Join(ctx, "apex.art")
+			imageConfig.images[target.Arch.ArchType] = imageDir.Join(ctx, name+".art")
 
 			imagesDeps := make([]android.Path, 0, len(imageConfig.modules)*3)
 			for _, dep := range imageConfig.moduleFiles(ctx, imageDir, ".art", ".oat", ".vdex") {
@@ -231,8 +166,17 @@
 	}).(bootImageConfig)
 }
 
+var defaultBootImageConfigKey = android.NewOnceKey("defaultBootImageConfig")
 var apexBootImageConfigKey = android.NewOnceKey("apexBootImageConfig")
 
+func defaultBootImageConfig(ctx android.PathContext) bootImageConfig {
+	return getBootImageConfig(ctx, defaultBootImageConfigKey, "boot", true)
+}
+
+func apexBootImageConfig(ctx android.PathContext) bootImageConfig {
+	return getBootImageConfig(ctx, apexBootImageConfigKey, "apex", false)
+}
+
 func defaultBootclasspath(ctx android.PathContext) []string {
 	return ctx.Config().OnceStringSlice(defaultBootclasspathKey, func() []string {
 		global := dexpreoptGlobalConfig(ctx)
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 3b581cb..12335ff 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -1193,6 +1193,9 @@
 
 	jdiffDocZip      android.WritablePath
 	jdiffStubsSrcJar android.WritablePath
+
+	metadataZip android.WritablePath
+	metadataDir android.WritablePath
 }
 
 // droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
@@ -1304,7 +1307,8 @@
 	}
 
 	if Bool(d.properties.Write_sdk_values) {
-		cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
+		d.metadataDir = android.PathForModuleOut(ctx, "metadata")
+		cmd.FlagWithArg("--sdk-values ", d.metadataDir.String())
 	}
 
 	if Bool(d.properties.Create_doc_stubs) {
@@ -1511,6 +1515,18 @@
 		FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
 		FlagWithArg("-C ", stubsDir.String()).
 		FlagWithArg("-D ", stubsDir.String())
+
+	if Bool(d.properties.Write_sdk_values) {
+		d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip")
+		rule.Command().
+			BuiltTool(ctx, "soong_zip").
+			Flag("-write_if_changed").
+			Flag("-d").
+			FlagWithOutput("-o ", d.metadataZip).
+			FlagWithArg("-C ", d.metadataDir.String()).
+			FlagWithArg("-D ", d.metadataDir.String())
+	}
+
 	rule.Restat()
 
 	zipSyncCleanupCmd(rule, srcJarDir)
diff --git a/java/java.go b/java/java.go
index 0aef69e..be48256 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1577,6 +1577,8 @@
 
 type Library struct {
 	Module
+
+	InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths)
 }
 
 func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool {
@@ -1607,8 +1609,12 @@
 
 	exclusivelyForApex := android.InAnyApex(ctx.ModuleName()) && !j.IsForPlatform()
 	if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex {
+		var extraInstallDeps android.Paths
+		if j.InstallMixin != nil {
+			extraInstallDeps = j.InstallMixin(ctx, j.outputFile)
+		}
 		j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
-			ctx.ModuleName()+".jar", j.outputFile)
+			ctx.ModuleName()+".jar", j.outputFile, extraInstallDeps...)
 	}
 }
 
diff --git a/java/java_test.go b/java/java_test.go
index a3499cc..3767d1b 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1073,32 +1073,32 @@
 }
 
 func TestPatchModule(t *testing.T) {
-	bp := `
-		java_library {
-			name: "foo",
-			srcs: ["a.java"],
-		}
-
-		java_library {
-			name: "bar",
-			srcs: ["b.java"],
-			sdk_version: "none",
-			system_modules: "none",
-			patch_module: "java.base",
-		}
-
-		java_library {
-			name: "baz",
-			srcs: ["c.java"],
-			patch_module: "java.base",
-		}
-	`
-
 	t.Run("Java language level 8", func(t *testing.T) {
 		// Test with legacy javac -source 1.8 -target 1.8
-		config := testConfig(map[string]string{"EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9": "false"})
-		ctx := testContext(bp, nil)
-		run(t, ctx, config)
+		bp := `
+			java_library {
+				name: "foo",
+				srcs: ["a.java"],
+				java_version: "1.8",
+			}
+
+			java_library {
+				name: "bar",
+				srcs: ["b.java"],
+				sdk_version: "none",
+				system_modules: "none",
+				patch_module: "java.base",
+				java_version: "1.8",
+			}
+
+			java_library {
+				name: "baz",
+				srcs: ["c.java"],
+				patch_module: "java.base",
+				java_version: "1.8",
+			}
+		`
+		ctx, _ := testJava(t, bp)
 
 		checkPatchModuleFlag(t, ctx, "foo", "")
 		checkPatchModuleFlag(t, ctx, "bar", "")
@@ -1107,6 +1107,26 @@
 
 	t.Run("Java language level 9", func(t *testing.T) {
 		// Test with default javac -source 9 -target 9
+		bp := `
+			java_library {
+				name: "foo",
+				srcs: ["a.java"],
+			}
+
+			java_library {
+				name: "bar",
+				srcs: ["b.java"],
+				sdk_version: "none",
+				system_modules: "none",
+				patch_module: "java.base",
+			}
+
+			java_library {
+				name: "baz",
+				srcs: ["c.java"],
+				patch_module: "java.base",
+			}
+		`
 		ctx, _ := testJava(t, bp)
 
 		checkPatchModuleFlag(t, ctx, "foo", "")
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 5e0e592..fd47d81 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -206,7 +206,7 @@
 				moduleType = testcase.moduleType
 			}
 
-			bp := moduleType + ` {
+			props := `
 				name: "foo",
 				srcs: ["a.java"],
 				target: {
@@ -214,6 +214,10 @@
 						srcs: ["bar-doc/IFoo.aidl"],
 					},
 				},
+				`
+			bp := moduleType + " {" + props + testcase.properties + `
+			}`
+			bpJava8 := moduleType + " {" + props + `java_version: "1.8",
 				` + testcase.properties + `
 			}`
 
@@ -233,45 +237,64 @@
 			bootclasspath := convertModulesToPaths(testcase.bootclasspath)
 			classpath := convertModulesToPaths(testcase.classpath)
 
-			bc := strings.Join(bootclasspath, ":")
-			if bc != "" {
-				bc = "-bootclasspath " + bc
+			bc := ""
+			var bcDeps []string
+			if len(bootclasspath) > 0 {
+				bc = "-bootclasspath " + strings.Join(bootclasspath, ":")
+				if bootclasspath[0] != `""` {
+					bcDeps = bootclasspath
+				}
 			}
 
-			c := strings.Join(classpath, ":")
-			if c != "" {
-				c = "-classpath " + c
+			c := ""
+			if len(classpath) > 0 {
+				c = "-classpath " + strings.Join(classpath, ":")
 			}
+
 			system := ""
+			var systemDeps []string
 			if testcase.system == "none" {
 				system = "--system=none"
+			} else if testcase.system == "bootclasspath" {
+				system = bc
+				systemDeps = bcDeps
 			} else if testcase.system != "" {
 				system = "--system=" + filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system")
+				// The module-relative parts of these paths are hardcoded in system_modules.go:
+				systemDeps = []string{
+					filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system", "lib", "modules"),
+					filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system", "lib", "jrt-fs.jar"),
+					filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system", "release"),
+				}
 			}
 
-			checkClasspath := func(t *testing.T, ctx *android.TestContext) {
+			checkClasspath := func(t *testing.T, ctx *android.TestContext, isJava8 bool) {
 				foo := ctx.ModuleForTests("foo", variant)
 				javac := foo.Rule("javac")
+				var deps []string
 
 				aidl := foo.MaybeRule("aidl")
+				if aidl.Rule != nil {
+					deps = append(deps, aidl.Output.String())
+				}
 
 				got := javac.Args["bootClasspath"]
-				if got != bc {
-					t.Errorf("bootclasspath expected %q != got %q", bc, got)
+				expected := ""
+				if isJava8 {
+					expected = bc
+					deps = append(deps, bcDeps...)
+				} else {
+					expected = system
+					deps = append(deps, systemDeps...)
+				}
+				if got != expected {
+					t.Errorf("bootclasspath expected %q != got %q", expected, got)
 				}
 
 				got = javac.Args["classpath"]
 				if got != c {
 					t.Errorf("classpath expected %q != got %q", c, got)
 				}
-
-				var deps []string
-				if aidl.Rule != nil {
-					deps = append(deps, aidl.Output.String())
-				}
-				if len(bootclasspath) > 0 && bootclasspath[0] != `""` {
-					deps = append(deps, bootclasspath...)
-				}
 				deps = append(deps, classpath...)
 
 				if !reflect.DeepEqual(javac.Implicits.Strings(), deps) {
@@ -281,17 +304,17 @@
 
 			// Test with legacy javac -source 1.8 -target 1.8
 			t.Run("Java language level 8", func(t *testing.T) {
-				config := testConfig(map[string]string{"EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9": "false"})
+				config := testConfig(nil)
 				if testcase.unbundled {
 					config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
 				}
 				if testcase.pdk {
 					config.TestProductVariables.Pdk = proptools.BoolPtr(true)
 				}
-				ctx := testContext(bp, nil)
+				ctx := testContext(bpJava8, nil)
 				run(t, ctx, config)
 
-				checkClasspath(t, ctx)
+				checkClasspath(t, ctx, true /* isJava8 */)
 
 				if testcase.host != android.Host {
 					aidl := ctx.ModuleForTests("foo", variant).Rule("aidl")
@@ -314,21 +337,20 @@
 				ctx := testContext(bp, nil)
 				run(t, ctx, config)
 
-				javac := ctx.ModuleForTests("foo", variant).Rule("javac")
-				got := javac.Args["bootClasspath"]
-				expected := system
-				if testcase.system == "bootclasspath" {
-					expected = bc
-				}
-				if got != expected {
-					t.Errorf("bootclasspath expected %q != got %q", expected, got)
+				checkClasspath(t, ctx, false /* isJava8 */)
+
+				if testcase.host != android.Host {
+					aidl := ctx.ModuleForTests("foo", variant).Rule("aidl")
+
+					if g, w := aidl.RuleParams.Command, testcase.aidl+" -I."; !strings.Contains(g, w) {
+						t.Errorf("want aidl command to contain %q, got %q", w, g)
+					}
 				}
 			})
 
-			// Test again with PLATFORM_VERSION_CODENAME=REL
-			t.Run("REL", func(t *testing.T) {
-				// TODO(b/115604102): This test should be rewritten with language level 9
-				config := testConfig(map[string]string{"EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9": "false"})
+			// Test again with PLATFORM_VERSION_CODENAME=REL, javac -source 8 -target 8
+			t.Run("REL + Java language level 8", func(t *testing.T) {
+				config := testConfig(nil)
 				config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("REL")
 				config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(true)
 
@@ -338,11 +360,13 @@
 				if testcase.pdk {
 					config.TestProductVariables.Pdk = proptools.BoolPtr(true)
 				}
-				ctx := testContext(bp, nil)
+				ctx := testContext(bpJava8, nil)
 				run(t, ctx, config)
 
-				checkClasspath(t, ctx)
+				checkClasspath(t, ctx, true /* isJava8 */)
 			})
+
+			// TODO(b/142896162): Add a with PLATFORM_VERSION_CODENAME=REL, javac -source 9 -target 9, when that all works.
 		})
 	}
 
diff --git a/java/tradefed.go b/java/tradefed.go
new file mode 100644
index 0000000..ebbdec1
--- /dev/null
+++ b/java/tradefed.go
@@ -0,0 +1,37 @@
+// 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 java
+
+import (
+	"android/soong/android"
+)
+
+func init() {
+	android.RegisterModuleType("tradefed_java_library_host", tradefedJavaLibraryFactory)
+}
+
+// tradefed_java_library_factory wraps java_library and installs an additional
+// copy of the output jar to $HOST_OUT/tradefed.
+func tradefedJavaLibraryFactory() android.Module {
+	module := LibraryHostFactory().(*Library)
+	module.InstallMixin = tradefedJavaLibraryInstall
+	return module
+}
+
+func tradefedJavaLibraryInstall(ctx android.ModuleContext, path android.Path) android.Paths {
+	installedPath := ctx.InstallFile(android.PathForModuleInstall(ctx, "tradefed"),
+		ctx.ModuleName()+".jar", path)
+	return android.Paths{installedPath}
+}
diff --git a/rust/config/x86_darwin_host.go b/rust/config/x86_darwin_host.go
new file mode 100644
index 0000000..7cfc59c
--- /dev/null
+++ b/rust/config/x86_darwin_host.go
@@ -0,0 +1,81 @@
+// Copyright 2019 The Android Open Source Project
+//
+// 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 config
+
+import (
+	"strings"
+
+	"android/soong/android"
+)
+
+var (
+	DarwinRustFlags      = []string{}
+	DarwinRustLinkFlags  = []string{}
+	darwinX8664Rustflags = []string{}
+	darwinX8664Linkflags = []string{}
+)
+
+func init() {
+	registerToolchainFactory(android.Darwin, android.X86_64, darwinX8664ToolchainFactory)
+	pctx.StaticVariable("DarwinToolchainRustFlags", strings.Join(DarwinRustFlags, " "))
+	pctx.StaticVariable("DarwinToolchainLinkFlags", strings.Join(DarwinRustLinkFlags, " "))
+	pctx.StaticVariable("DarwinToolchainX8664RustFlags", strings.Join(darwinX8664Rustflags, " "))
+	pctx.StaticVariable("DarwinToolchainX8664LinkFlags", strings.Join(darwinX8664Linkflags, " "))
+
+}
+
+type toolchainDarwin struct {
+	toolchainRustFlags string
+	toolchainLinkFlags string
+}
+
+type toolchainDarwinX8664 struct {
+	toolchain64Bit
+	toolchainDarwin
+}
+
+func (toolchainDarwinX8664) Supported() bool {
+	return true
+}
+
+func (toolchainDarwinX8664) Bionic() bool {
+	return false
+}
+
+func (t *toolchainDarwinX8664) Name() string {
+	return "x86_64"
+}
+
+func (t *toolchainDarwinX8664) RustTriple() string {
+	return "x86_64-apple-darwin"
+}
+
+func (t *toolchainDarwin) ShlibSuffix() string {
+	return ".dylib"
+}
+
+func (t *toolchainDarwinX8664) ToolchainLinkFlags() string {
+	return "${config.DarwinToolchainLinkFlags} ${config.DarwinToolchainX8664LinkFlags}"
+}
+
+func (t *toolchainDarwinX8664) ToolchainRustFlags() string {
+	return "${config.DarwinToolchainRustFlags} ${config.DarwinToolchainX8664RustFlags}"
+}
+
+func darwinX8664ToolchainFactory(arch android.Arch) Toolchain {
+	return toolchainDarwinX8664Singleton
+}
+
+var toolchainDarwinX8664Singleton Toolchain = &toolchainDarwinX8664{}
diff --git a/rust/rust.go b/rust/rust.go
index 4f5e7fb..707de4b 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -164,15 +164,11 @@
 	android.AddLoadHook(mod, func(ctx android.LoadHookContext) {
 		disableTargets := struct {
 			Target struct {
-				Darwin struct {
-					Enabled *bool
-				}
 				Linux_bionic struct {
 					Enabled *bool
 				}
 			}
 		}{}
-		disableTargets.Target.Darwin.Enabled = proptools.BoolPtr(false)
 		disableTargets.Target.Linux_bionic.Enabled = proptools.BoolPtr(false)
 
 		ctx.AppendProperties(&disableTargets)
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 1af816b..1bd3c98 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -80,7 +80,6 @@
 	"diff":     Allowed,
 	"dlv":      Allowed,
 	"expr":     Allowed,
-	"find":     Allowed,
 	"fuser":    Allowed,
 	"getopt":   Allowed,
 	"git":      Allowed,