Merge "Add updatable_media_stubs to prevent private API use."
diff --git a/Android.bp b/Android.bp
index ad2447c..f356fce 100644
--- a/Android.bp
+++ b/Android.bp
@@ -61,6 +61,7 @@
         "android/prebuilt_etc.go",
         "android/proto.go",
         "android/register.go",
+        "android/sh_binary.go",
         "android/singleton.go",
         "android/testing.go",
         "android/util.go",
diff --git a/OWNERS b/OWNERS
index 7983c19..85c70df 100644
--- a/OWNERS
+++ b/OWNERS
@@ -3,4 +3,3 @@
 per-file clang.go,global.go = srhines@google.com, chh@google.com, pirama@google.com, yikong@google.com
 per-file tidy.go = srhines@google.com, chh@google.com
 per-file lto.go,pgo.go = srhines@google.com, pirama@google.com, yikong@google.com
-per-file apex.go = jiyong@google.com
diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go
index 46d128e..42c7c2c 100644
--- a/android/prebuilt_etc.go
+++ b/android/prebuilt_etc.go
@@ -125,7 +125,8 @@
 	p.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
 	p.installDirPath = PathForModuleInstall(ctx, "etc", String(p.properties.Sub_dir))
 
-	// This ensures that outputFilePath has the same name as this module.
+	// This ensures that outputFilePath has the correct name for others to
+	// use, as the source file may have a different name.
 	ctx.Build(pctx, BuildParams{
 		Rule:   Cp,
 		Output: p.outputFilePath,
diff --git a/android/sh_binary.go b/android/sh_binary.go
new file mode 100644
index 0000000..3915193
--- /dev/null
+++ b/android/sh_binary.go
@@ -0,0 +1,141 @@
+// 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"
+)
+
+// sh_binary is for shell scripts (and batch files) that are installed as
+// executable files into .../bin/
+//
+// Do not use them for prebuilt C/C++/etc files.  Use cc_prebuilt_binary
+// instead.
+
+func init() {
+	RegisterModuleType("sh_binary", ShBinaryFactory)
+	RegisterModuleType("sh_binary_host", ShBinaryHostFactory)
+}
+
+type shBinaryProperties struct {
+	// Source file of this prebuilt.
+	Src *string `android:"arch_variant"`
+
+	// optional subdirectory under which this file is installed into
+	Sub_dir *string `android:"arch_variant"`
+
+	// optional name for the installed file. If unspecified, name of the module is used as the file name
+	Filename *string `android:"arch_variant"`
+
+	// when set to true, and filename property is not set, the name for the installed file
+	// is the same as the file name of the source file.
+	Filename_from_src *bool `android:"arch_variant"`
+
+	// Whether this module is directly installable to one of the partitions. Default: true.
+	Installable *bool
+}
+
+type ShBinary struct {
+	ModuleBase
+
+	properties shBinaryProperties
+
+	sourceFilePath Path
+	outputFilePath OutputPath
+}
+
+func (s *ShBinary) DepsMutator(ctx BottomUpMutatorContext) {
+	if s.properties.Src == nil {
+		ctx.PropertyErrorf("src", "missing prebuilt source file")
+	}
+
+	// To support ":modulename" in src
+	ExtractSourceDeps(ctx, s.properties.Src)
+}
+
+func (s *ShBinary) SourceFilePath(ctx ModuleContext) Path {
+	return ctx.ExpandSource(String(s.properties.Src), "src")
+}
+
+func (s *ShBinary) OutputFile() OutputPath {
+	return s.outputFilePath
+}
+
+func (s *ShBinary) SubDir() string {
+	return String(s.properties.Sub_dir)
+}
+
+func (s *ShBinary) Installable() bool {
+	return s.properties.Installable == nil || Bool(s.properties.Installable)
+}
+
+func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) {
+	s.sourceFilePath = ctx.ExpandSource(String(s.properties.Src), "src")
+	filename := String(s.properties.Filename)
+	filename_from_src := Bool(s.properties.Filename_from_src)
+	if filename == "" {
+		if filename_from_src {
+			filename = s.sourceFilePath.Base()
+		} else {
+			filename = ctx.ModuleName()
+		}
+	} else if filename_from_src {
+		ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
+		return
+	}
+	s.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
+
+	// This ensures that outputFilePath has the correct name for others to
+	// use, as the source file may have a different name.
+	ctx.Build(pctx, BuildParams{
+		Rule:   CpExecutable,
+		Output: s.outputFilePath,
+		Input:  s.sourceFilePath,
+	})
+}
+
+func (s *ShBinary) AndroidMk() AndroidMkData {
+	return AndroidMkData{
+		Class:      "EXECUTABLES",
+		OutputFile: OptionalPathForPath(s.outputFilePath),
+		Include:    "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
+		Extra: []AndroidMkExtraFunc{
+			func(w io.Writer, outputFile Path) {
+				fmt.Fprintln(w, "LOCAL_MODULE_RELATIVE_PATH :=", String(s.properties.Sub_dir))
+				fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX :=")
+				fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", s.outputFilePath.Rel())
+			},
+		},
+	}
+}
+
+func InitShBinaryModule(s *ShBinary) {
+	s.AddProperties(&s.properties)
+}
+
+func ShBinaryFactory() Module {
+	module := &ShBinary{}
+	InitShBinaryModule(module)
+	InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst)
+	return module
+}
+
+func ShBinaryHostFactory() Module {
+	module := &ShBinary{}
+	InitShBinaryModule(module)
+	InitAndroidArchModule(module, HostSupported, MultilibFirst)
+	return module
+}
diff --git a/apex/OWNERS b/apex/OWNERS
new file mode 100644
index 0000000..a382ae8
--- /dev/null
+++ b/apex/OWNERS
@@ -0,0 +1 @@
+per-file * = jiyong@google.com
\ No newline at end of file
diff --git a/apex/apex.go b/apex/apex.go
index aeeff78..f6daf9b 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -177,6 +177,29 @@
 	}
 }
 
+type apexNativeDependencies struct {
+	// List of native libraries
+	Native_shared_libs []string
+	// List of native executables
+	Binaries []string
+}
+type apexMultilibProperties struct {
+	// Native dependencies whose compile_multilib is "first"
+	First apexNativeDependencies
+
+	// Native dependencies whose compile_multilib is "both"
+	Both apexNativeDependencies
+
+	// Native dependencies whose compile_multilib is "prefer32"
+	Prefer32 apexNativeDependencies
+
+	// Native dependencies whose compile_multilib is "32"
+	Lib32 apexNativeDependencies
+
+	// Native dependencies whose compile_multilib is "64"
+	Lib64 apexNativeDependencies
+}
+
 type apexBundleProperties struct {
 	// Json manifest file describing meta info of this APEX bundle. Default:
 	// "apex_manifest.json"
@@ -218,36 +241,29 @@
 	// Default is false.
 	Use_vendor *bool
 
-	Multilib struct {
-		First struct {
-			// List of native libraries whose compile_multilib is "first"
-			Native_shared_libs []string
-			// List of native executables whose compile_multilib is "first"
-			Binaries []string
+	// For telling the apex to ignore special handling for system libraries such as bionic. Default is false.
+	Ignore_system_library_special_case *bool
+
+	Multilib apexMultilibProperties
+}
+
+type apexTargetBundleProperties struct {
+	Target struct {
+		// Multilib properties only for android.
+		Android struct {
+			Multilib apexMultilibProperties
 		}
-		Both struct {
-			// List of native libraries whose compile_multilib is "both"
-			Native_shared_libs []string
-			// List of native executables whose compile_multilib is "both"
-			Binaries []string
+		// Multilib properties only for host.
+		Host struct {
+			Multilib apexMultilibProperties
 		}
-		Prefer32 struct {
-			// List of native libraries whose compile_multilib is "prefer32"
-			Native_shared_libs []string
-			// List of native executables whose compile_multilib is "prefer32"
-			Binaries []string
+		// Multilib properties only for host linux_bionic.
+		Linux_bionic struct {
+			Multilib apexMultilibProperties
 		}
-		Lib32 struct {
-			// List of native libraries whose compile_multilib is "32"
-			Native_shared_libs []string
-			// List of native executables whose compile_multilib is "32"
-			Binaries []string
-		}
-		Lib64 struct {
-			// List of native libraries whose compile_multilib is "64"
-			Native_shared_libs []string
-			// List of native executables whose compile_multilib is "64"
-			Binaries []string
+		// Multilib properties only for host linux_glibc.
+		Linux_glibc struct {
+			Multilib apexMultilibProperties
 		}
 	}
 }
@@ -339,7 +355,8 @@
 	android.ModuleBase
 	android.DefaultableModuleBase
 
-	properties apexBundleProperties
+	properties       apexBundleProperties
+	targetProperties apexTargetBundleProperties
 
 	apexTypes apexPackaging
 
@@ -372,9 +389,26 @@
 	}, executableTag, binaries...)
 }
 
+func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
+	if ctx.Os().Class == android.Device {
+		proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
+	} else {
+		proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
+		if ctx.Os().Bionic() {
+			proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
+		} else {
+			proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
+		}
+	}
+}
+
 func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
+
 	targets := ctx.MultiTargets()
 	config := ctx.DeviceConfig()
+
+	a.combineProperties(ctx)
+
 	has32BitTarget := false
 	for _, target := range targets {
 		if target.Arch.ArchType.Multilib == "lib32" {
@@ -497,7 +531,7 @@
 	return android.InList(sanitizerName, globalSanitizerNames)
 }
 
-func getCopyManifestForNativeLibrary(cc *cc.Module) (fileToCopy android.Path, dirInApex string) {
+func getCopyManifestForNativeLibrary(cc *cc.Module, handleSpecialLibs bool) (fileToCopy android.Path, dirInApex string) {
 	// Decide the APEX-local directory by the multilib of the library
 	// In the future, we may query this to the module.
 	switch cc.Arch().ArchType.Multilib {
@@ -509,18 +543,20 @@
 	if !cc.Arch().Native {
 		dirInApex = filepath.Join(dirInApex, cc.Arch().ArchType.String())
 	}
-	switch cc.Name() {
-	case "libc", "libm", "libdl":
-		// Special case for bionic libs. This is to prevent the bionic libs
-		// from being included in the search path /apex/com.android.apex/lib.
-		// This exclusion is required because bionic libs in the runtime APEX
-		// are available via the legacy paths /system/lib/libc.so, etc. By the
-		// init process, the bionic libs in the APEX are bind-mounted to the
-		// legacy paths and thus will be loaded into the default linker namespace.
-		// If the bionic libs are directly in /apex/com.android.apex/lib then
-		// the same libs will be again loaded to the runtime linker namespace,
-		// which will result double loading of bionic libs that isn't supported.
-		dirInApex = filepath.Join(dirInApex, "bionic")
+	if handleSpecialLibs {
+		switch cc.Name() {
+		case "libc", "libm", "libdl":
+			// Special case for bionic libs. This is to prevent the bionic libs
+			// from being included in the search path /apex/com.android.apex/lib.
+			// This exclusion is required because bionic libs in the runtime APEX
+			// are available via the legacy paths /system/lib/libc.so, etc. By the
+			// init process, the bionic libs in the APEX are bind-mounted to the
+			// legacy paths and thus will be loaded into the default linker namespace.
+			// If the bionic libs are directly in /apex/com.android.apex/lib then
+			// the same libs will be again loaded to the runtime linker namespace,
+			// which will result double loading of bionic libs that isn't supported.
+			dirInApex = filepath.Join(dirInApex, "bionic")
+		}
 	}
 
 	fileToCopy = cc.OutputFile().Path()
@@ -563,6 +599,8 @@
 		return
 	}
 
+	handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
+
 	ctx.WalkDeps(func(child, parent android.Module) bool {
 		if _, ok := parent.(*apexBundle); ok {
 			// direct dependencies
@@ -571,7 +609,7 @@
 			switch depTag {
 			case sharedLibTag:
 				if cc, ok := child.(*cc.Module); ok {
-					fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc)
+					fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc, handleSpecialLibs)
 					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, nativeSharedLib, cc, nil})
 					return true
 				} else {
@@ -639,7 +677,7 @@
 						return false
 					}
 					depName := ctx.OtherModuleName(child)
-					fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc)
+					fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc, handleSpecialLibs)
 					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, nativeSharedLib, cc, nil})
 					return true
 				}
@@ -1028,6 +1066,7 @@
 		outputFiles: map[apexPackaging]android.WritablePath{},
 	}
 	module.AddProperties(&module.properties)
+	module.AddProperties(&module.targetProperties)
 	module.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool {
 		return class == android.Device && ctx.Config().DevicePrefer32BitExecutables()
 	})
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 7ae49f6..9d33060 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -864,3 +864,83 @@
 	// Ensure that the include path of the header lib is exported to 'otherlib'
 	ensureContains(t, cFlags, "-Imy_include")
 }
+
+func TestApexWithTarget(t *testing.T) {
+	ctx := testApex(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			multilib: {
+				first: {
+					native_shared_libs: ["mylib_common"],
+				}
+			},
+			target: {
+				android: {
+					multilib: {
+						first: {
+							native_shared_libs: ["mylib"],
+						}
+					}
+				},
+				host: {
+					multilib: {
+						first: {
+							native_shared_libs: ["mylib2"],
+						}
+					}
+				}
+			}
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "mylib",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+		}
+
+		cc_library {
+			name: "mylib_common",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+			compile_multilib: "first",
+		}
+
+		cc_library {
+			name: "mylib2",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+			compile_multilib: "first",
+		}
+	`)
+
+	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+
+	// Ensure that main rule creates an output
+	ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
+
+	// Ensure that apex variant is created for the direct dep
+	ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_core_shared_myapex")
+	ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_core_shared_myapex")
+	ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_core_shared_myapex")
+
+	// Ensure that both direct and indirect deps are copied into apex
+	ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
+	ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so")
+	ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
+
+	// Ensure that the platform variant ends with _core_shared
+	ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_core_shared")
+	ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_core_shared")
+	ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_core_shared")
+}
diff --git a/cc/xom.go b/cc/xom.go
index 182069f..9337990 100644
--- a/cc/xom.go
+++ b/cc/xom.go
@@ -50,7 +50,7 @@
 	// If any static dependencies have XOM disabled, we should disable XOM in this module,
 	// the assumption being if it's been explicitly disabled then there's probably incompatible
 	// code in the library which may get pulled in.
-	if !ctx.static() && !disableXom {
+	if !disableXom {
 		ctx.VisitDirectDeps(func(m android.Module) {
 			cc, ok := m.(*Module)
 			if !ok || cc.xom == nil || !cc.static() {