Merge "Update paths for libnative{bridge,loader}"
diff --git a/android/module.go b/android/module.go
index 70b602b..a6b8d53 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1195,9 +1195,9 @@
 func (m *moduleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
 	argNames ...string) blueprint.Rule {
 
-	if m.config.UseGoma() && params.Pool == nil {
-		// When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the
-		// local parallelism value
+	if (m.config.UseGoma() || m.config.UseRBE()) && params.Pool == nil {
+		// When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict
+		// jobs to the local parallelism value
 		params.Pool = localPool
 	}
 
diff --git a/android/package_ctx.go b/android/package_ctx.go
index 548450e..cf8face 100644
--- a/android/package_ctx.go
+++ b/android/package_ctx.go
@@ -115,9 +115,9 @@
 		if len(ctx.errors) > 0 {
 			return params, ctx.errors[0]
 		}
-		if ctx.Config().UseGoma() && params.Pool == nil {
-			// When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the
-			// local parallelism value
+		if (ctx.Config().UseGoma() || ctx.Config().UseRBE()) && params.Pool == nil {
+			// When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by
+			// goma/RBE, restrict jobs to the local parallelism value
 			params.Pool = localPool
 		}
 		return params, nil
@@ -254,9 +254,35 @@
 	}, argNames...)
 }
 
-// AndroidGomaStaticRule wraps blueprint.StaticRule but uses goma's parallelism if goma is enabled
-func (p PackageContext) AndroidGomaStaticRule(name string, params blueprint.RuleParams,
+// RemoteRuleSupports selects if a AndroidRemoteStaticRule supports goma, RBE, or both.
+type RemoteRuleSupports int
+
+const (
+	SUPPORTS_NONE = 0
+	SUPPORTS_GOMA = 1 << iota
+	SUPPORTS_RBE  = 1 << iota
+	SUPPORTS_BOTH = SUPPORTS_GOMA | SUPPORTS_RBE
+)
+
+// AndroidRemoteStaticRule wraps blueprint.StaticRule but uses goma or RBE's parallelism if goma or RBE are enabled
+// and the appropriate SUPPORTS_* flag is set.
+func (p PackageContext) AndroidRemoteStaticRule(name string, supports RemoteRuleSupports, params blueprint.RuleParams,
 	argNames ...string) blueprint.Rule {
-	// bypass android.PackageContext.StaticRule so that Pool does not get set to local_pool.
-	return p.PackageContext.StaticRule(name, params, argNames...)
+
+	return p.PackageContext.RuleFunc(name, func(config interface{}) (blueprint.RuleParams, error) {
+		ctx := &configErrorWrapper{p, config.(Config), nil}
+		if ctx.Config().UseGoma() && supports&SUPPORTS_GOMA == 0 {
+			// When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the
+			// local parallelism value
+			params.Pool = localPool
+		}
+
+		if ctx.Config().UseRBE() && supports&SUPPORTS_RBE == 0 {
+			// When USE_RBE=true is set and the rule is not supported by RBE, restrict jobs to the
+			// local parallelism value
+			params.Pool = localPool
+		}
+
+		return params, nil
+	}, argNames...)
 }
diff --git a/android/singleton.go b/android/singleton.go
index 33bc6d1..5519ca0 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -131,9 +131,9 @@
 }
 
 func (s *singletonContextAdaptor) Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule {
-	if s.Config().UseGoma() && params.Pool == nil {
-		// When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the
-		// local parallelism value
+	if (s.Config().UseGoma() || s.Config().UseRBE()) && params.Pool == nil {
+		// When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict
+		// jobs to the local parallelism value
 		params.Pool = localPool
 	}
 	rule := s.SingletonContext.Rule(pctx.PackageContext, name, params, argNames...)
diff --git a/bpf/bpf.go b/bpf/bpf.go
index 90ec963..024fcbc 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -33,7 +33,7 @@
 var (
 	pctx = android.NewPackageContext("android/soong/bpf")
 
-	ccRule = pctx.AndroidGomaStaticRule("ccRule",
+	ccRule = pctx.AndroidRemoteStaticRule("ccRule", android.SUPPORTS_GOMA,
 		blueprint.RuleParams{
 			Depfile:     "${out}.d",
 			Deps:        blueprint.DepsGCC,
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index 9cba80a..4633aa6 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -116,6 +116,10 @@
 		Name: "rewriteAndroidAppImport",
 		Fix:  rewriteAndroidAppImport,
 	},
+	{
+		Name: "removeEmptyLibDependencies",
+		Fix:  removeEmptyLibDependencies,
+	},
 }
 
 func NewFixRequest() FixRequest {
@@ -650,6 +654,50 @@
 	return nil
 }
 
+// Removes library dependencies which are empty (and restricted from usage in Soong)
+func removeEmptyLibDependencies(f *Fixer) error {
+	emptyLibraries := []string{
+		"libhidltransport",
+		"libhwbinder",
+	}
+	relevantFields := []string{
+		"export_shared_lib_headers",
+		"export_static_lib_headers",
+		"static_libs",
+		"whole_static_libs",
+		"shared_libs",
+	}
+	for _, def := range f.tree.Defs {
+		mod, ok := def.(*parser.Module)
+		if !ok {
+			continue
+		}
+		for _, field := range relevantFields {
+			listValue, ok := getLiteralListProperty(mod, field)
+			if !ok {
+				continue
+			}
+			newValues := []parser.Expression{}
+			for _, v := range listValue.Values {
+				stringValue, ok := v.(*parser.String)
+				if !ok {
+					return fmt.Errorf("Expecting string for %s.%s fields", mod.Type, field)
+				}
+				if inList(stringValue.Value, emptyLibraries) {
+					continue
+				}
+				newValues = append(newValues, stringValue)
+			}
+			if len(newValues) == 0 && len(listValue.Values) != 0 {
+				removeProperty(mod, field)
+			} else {
+				listValue.Values = newValues
+			}
+		}
+	}
+	return nil
+}
+
 // Converts the default source list property, 'srcs', to a single source property with a given name.
 // "LOCAL_MODULE" reference is also resolved during the conversion process.
 func convertToSingleSource(mod *parser.Module, srcPropertyName string) {
@@ -1084,3 +1132,12 @@
 	}
 	mod.Properties = newList
 }
+
+func inList(s string, list []string) bool {
+	for _, v := range list {
+		if s == v {
+			return true
+		}
+	}
+	return false
+}
diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go
index 5e0b817..032282f 100644
--- a/bpfix/bpfix/bpfix_test.go
+++ b/bpfix/bpfix/bpfix_test.go
@@ -833,3 +833,57 @@
 		})
 	}
 }
+
+func TestRemoveEmptyLibDependencies(t *testing.T) {
+	tests := []struct {
+		name string
+		in   string
+		out  string
+	}{
+		{
+			name: "remove sole shared lib",
+			in: `
+				cc_library {
+					name: "foo",
+					shared_libs: ["libhwbinder"],
+				}
+			`,
+			out: `
+				cc_library {
+					name: "foo",
+
+				}
+			`,
+		},
+		{
+			name: "remove a shared lib",
+			in: `
+				cc_library {
+					name: "foo",
+					shared_libs: [
+						"libhwbinder",
+						"libfoo",
+						"libhidltransport",
+					],
+				}
+			`,
+			out: `
+				cc_library {
+					name: "foo",
+					shared_libs: [
+
+						"libfoo",
+
+					],
+				}
+			`,
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			runPass(t, test.in, test.out, func(fixer *Fixer) error {
+				return removeEmptyLibDependencies(fixer)
+			})
+		})
+	}
+}
diff --git a/cc/builder.go b/cc/builder.go
index 491ebc5..068c930 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -46,7 +46,7 @@
 var (
 	pctx = android.NewPackageContext("android/soong/cc")
 
-	cc = pctx.AndroidGomaStaticRule("cc",
+	cc = pctx.AndroidRemoteStaticRule("cc", android.SUPPORTS_BOTH,
 		blueprint.RuleParams{
 			Depfile:     "${out}.d",
 			Deps:        blueprint.DepsGCC,
@@ -55,7 +55,7 @@
 		},
 		"ccCmd", "cFlags")
 
-	ccNoDeps = pctx.AndroidGomaStaticRule("ccNoDeps",
+	ccNoDeps = pctx.AndroidRemoteStaticRule("ccNoDeps", android.SUPPORTS_GOMA,
 		blueprint.RuleParams{
 			Command:     "$relPwd ${config.CcWrapper}$ccCmd -c $cFlags -o $out $in",
 			CommandDeps: []string{"$ccCmd"},
diff --git a/cc/cmakelists.go b/cc/cmakelists.go
index 7b4f89b..be18ab9 100644
--- a/cc/cmakelists.go
+++ b/cc/cmakelists.go
@@ -306,6 +306,20 @@
 	return flag
 }
 
+// Flattens a list of strings potentially containing space characters into a list of string containing no
+// spaces.
+func normalizeParameters(params []string) []string {
+	var flatParams []string
+	for _, s := range params {
+		s = strings.Trim(s, " ")
+		if len(s) == 0 {
+			continue
+		}
+		flatParams = append(flatParams, strings.Split(s, " ")...)
+	}
+	return flatParams
+}
+
 func parseCompilerParameters(params []string, ctx android.SingletonContext, f *os.File) compilerParameters {
 	var compilerParameters = makeCompilerParameters()
 
@@ -313,6 +327,15 @@
 		f.WriteString(fmt.Sprintf("# Raw param [%d] = '%s'\n", i, str))
 	}
 
+	// Soong does not guarantee that each flag will be in an individual string. e.g: The
+	// input received could be:
+	// params = {"-isystem", "path/to/system"}
+	// or it could be
+	// params = {"-isystem path/to/system"}
+	// To normalize the input, we split all strings with the "space" character and consolidate
+	// all tokens into a flattened parameters list
+	params = normalizeParameters(params)
+
 	for i := 0; i < len(params); i++ {
 		param := params[i]
 		if param == "" {
diff --git a/java/androidmk.go b/java/androidmk.go
index cd91b46..63c7d9a 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -612,10 +612,15 @@
 
 					fmt.Fprintln(w, ".PHONY: checkapi")
 					fmt.Fprintln(w, "checkapi:",
-						dstubs.apiLintTimestamp.String())
+						dstubs.Name()+"-api-lint")
 
 					fmt.Fprintln(w, ".PHONY: droidcore")
 					fmt.Fprintln(w, "droidcore: checkapi")
+
+					if dstubs.apiLintReport != nil {
+						fmt.Fprintf(w, "$(call dist-for-goals,%s,%s:%s)\n", dstubs.Name()+"-api-lint",
+							dstubs.apiLintReport.String(), "apilint/"+dstubs.Name()+"-lint-report.txt")
+					}
 				}
 				if dstubs.checkNullabilityWarningsTimestamp != nil {
 					fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-check-nullability-warnings")
diff --git a/java/app.go b/java/app.go
index bd8556e..58b7721 100644
--- a/java/app.go
+++ b/java/app.go
@@ -165,7 +165,6 @@
 		a.aapt.deps(ctx, sdkDep)
 	}
 
-	embedJni := a.shouldEmbedJnis(ctx)
 	for _, jniTarget := range ctx.MultiTargets() {
 		variation := append(jniTarget.Variations(),
 			blueprint.Variation{Mutator: "link", Variation: "shared"})
@@ -174,7 +173,7 @@
 		}
 		ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs...)
 		if String(a.appProperties.Stl) == "c++_shared" {
-			if embedJni {
+			if a.shouldEmbedJnis(ctx) {
 				ctx.AddFarVariationDependencies(variation, tag, "ndk_libc++_shared")
 			}
 		}
diff --git a/java/builder.go b/java/builder.go
index 5d36acd..b5dc88a 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -38,7 +38,7 @@
 	// this, all java rules write into separate directories and then are combined into a .jar file
 	// (if the rule produces .class files) or a .srcjar file (if the rule produces .java files).
 	// .srcjar files are unzipped into a temporary directory when compiled with javac.
-	javac = pctx.AndroidGomaStaticRule("javac",
+	javac = pctx.AndroidRemoteStaticRule("javac", android.SUPPORTS_GOMA,
 		blueprint.RuleParams{
 			Command: `rm -rf "$outDir" "$annoDir" "$srcJarDir" && mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` +
 				`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 6f3b152..5d01b54 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -1182,6 +1182,7 @@
 	updateCurrentApiTimestamp     android.WritablePath
 	checkLastReleasedApiTimestamp android.WritablePath
 	apiLintTimestamp              android.WritablePath
+	apiLintReport                 android.WritablePath
 
 	checkNullabilityWarningsTimestamp android.WritablePath
 
@@ -1552,6 +1553,8 @@
 		} else {
 			cmd.Flag("--api-lint")
 		}
+		d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt")
+		cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport)
 
 		d.inclusionAnnotationsFlags(ctx, cmd)
 		d.mergeAnnoDirFlags(ctx, cmd)
diff --git a/java/kotlin.go b/java/kotlin.go
index f8ae229..aa65314 100644
--- a/java/kotlin.go
+++ b/java/kotlin.go
@@ -26,7 +26,7 @@
 	"github.com/google/blueprint"
 )
 
-var kotlinc = pctx.AndroidGomaStaticRule("kotlinc",
+var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.SUPPORTS_GOMA,
 	blueprint.RuleParams{
 		Command: `rm -rf "$classesDir" "$srcJarDir" "$kotlinBuildFile" "$emptyDir" && ` +
 			`mkdir -p "$classesDir" "$srcJarDir" "$emptyDir" && ` +
@@ -88,7 +88,7 @@
 	})
 }
 
-var kapt = pctx.AndroidGomaStaticRule("kapt",
+var kapt = pctx.AndroidRemoteStaticRule("kapt", android.SUPPORTS_GOMA,
 	blueprint.RuleParams{
 		Command: `rm -rf "$srcJarDir" "$kotlinBuildFile" "$kaptDir" && mkdir -p "$srcJarDir" "$kaptDir" && ` +
 			`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
diff --git a/python/python.go b/python/python.go
index 1b606cb..c67c577 100644
--- a/python/python.go
+++ b/python/python.go
@@ -326,9 +326,24 @@
 				p.properties.Version.Py3.Libs)...)
 
 		if p.bootstrapper != nil && p.isEmbeddedLauncherEnabled(pyVersion3) {
-			//TODO(nanzhang): Add embedded launcher for Python3.
-			ctx.PropertyErrorf("version.py3.embedded_launcher",
-				"is not supported yet for Python3.")
+			ctx.AddVariationDependencies(nil, pythonLibTag, "py3-stdlib")
+
+			launcherModule := "py3-launcher"
+			if p.bootstrapper.autorun() {
+				launcherModule = "py3-launcher-autorun"
+			}
+			ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherTag, launcherModule)
+
+			// Add py3-launcher shared lib dependencies. Ideally, these should be
+			// derived from the `shared_libs` property of "py3-launcher". However, we
+			// cannot read the property at this stage and it will be too late to add
+			// dependencies later.
+			ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag, "libsqlite")
+
+			if ctx.Target().Os.Bionic() {
+				ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag,
+					"libc", "libdl", "libm")
+			}
 		}
 	default:
 		panic(fmt.Errorf("unknown Python Actual_version: %q for module: %q.",
@@ -370,11 +385,11 @@
 	// Only Python binaries and test has non-empty bootstrapper.
 	if p.bootstrapper != nil {
 		p.walkTransitiveDeps(ctx)
-		// TODO(nanzhang): Since embedded launcher is not supported for Python3 for now,
-		// so we initialize "embedded_launcher" to false.
 		embeddedLauncher := false
 		if p.properties.Actual_version == pyVersion2 {
 			embeddedLauncher = p.isEmbeddedLauncherEnabled(pyVersion2)
+		} else {
+			embeddedLauncher = p.isEmbeddedLauncherEnabled(pyVersion3)
 		}
 		p.installSource = p.bootstrapper.bootstrap(ctx, p.properties.Actual_version,
 			embeddedLauncher, p.srcsPathMappings, p.srcsZip, p.depsSrcsZips)
diff --git a/python/tests/Android.bp b/python/tests/Android.bp
index 1f4305c..c8bf420 100644
--- a/python/tests/Android.bp
+++ b/python/tests/Android.bp
@@ -27,6 +27,22 @@
         },
         py3: {
             enabled: false,
+            embedded_launcher: true,
+        },
+    },
+}
+
+python_test_host {
+    name: "par_test3",
+    main: "par_test.py",
+    srcs: [
+        "par_test.py",
+        "testpkg/par_test.py",
+    ],
+
+    version: {
+        py3: {
+            embedded_launcher: true,
         },
     },
 }
diff --git a/python/tests/runtest.sh b/python/tests/runtest.sh
index a319558..1ecdebc 100755
--- a/python/tests/runtest.sh
+++ b/python/tests/runtest.sh
@@ -23,8 +23,8 @@
   exit 1
 fi
 
-if [ ! -f $ANDROID_HOST_OUT/nativetest64/par_test/par_test ]; then
-  echo "Run 'm par_test' first"
+if [[ ( ! -f $ANDROID_HOST_OUT/nativetest64/par_test/par_test ) || ( ! -f $ANDROID_HOST_OUT/nativetest64/par_test3/par_test3 ) ]]; then
+  echo "Run 'm par_test par_test3' first"
   exit 1
 fi
 
@@ -36,4 +36,8 @@
 PYTHONHOME=/usr $ANDROID_HOST_OUT/nativetest64/par_test/par_test
 PYTHONPATH=/usr $ANDROID_HOST_OUT/nativetest64/par_test/par_test
 
+PYTHONHOME= PYTHONPATH= $ANDROID_HOST_OUT/nativetest64/par_test3/par_test3
+PYTHONHOME=/usr $ANDROID_HOST_OUT/nativetest64/par_test3/par_test3
+PYTHONPATH=/usr $ANDROID_HOST_OUT/nativetest64/par_test3/par_test3
+
 echo "Passed!"
diff --git a/python/tests/testpkg/par_test.py b/python/tests/testpkg/par_test.py
index 22dd095..ffad430 100644
--- a/python/tests/testpkg/par_test.py
+++ b/python/tests/testpkg/par_test.py
@@ -29,7 +29,13 @@
 
 assert_equal("__name__", __name__, "testpkg.par_test")
 assert_equal("__file__", __file__, os.path.join(archive, "testpkg/par_test.py"))
-assert_equal("__package__", __package__, "testpkg")
+
+# Python3 is returning None here for me, and I haven't found any problems caused by this.
+if sys.version_info[0] == 2:
+  assert_equal("__package__", __package__, "testpkg")
+else:
+  assert_equal("__package__", __package__, None)
+
 assert_equal("__loader__.archive", __loader__.archive, archive)
 assert_equal("__loader__.prefix", __loader__.prefix, "testpkg/")
 
diff --git a/sdk/sdk.go b/sdk/sdk.go
index 002fb5d..cb81a14 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -19,6 +19,7 @@
 	"strconv"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
 	// This package doesn't depend on the apex package, but import it to make its mutators to be
@@ -60,6 +61,13 @@
 	s.AddProperties(&s.properties)
 	android.InitAndroidMultiTargetsArchModule(s, android.HostAndDeviceSupported, android.MultilibCommon)
 	android.InitDefaultableModule(s)
+	android.AddLoadHook(s, func(ctx android.LoadHookContext) {
+		type props struct {
+			Compile_multilib *string
+		}
+		p := &props{Compile_multilib: proptools.StringPtr("both")}
+		ctx.AppendProperties(p)
+	})
 	return s
 }
 
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index 664bb7c..96129b8 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -377,6 +377,35 @@
 	`)
 }
 
+func TestSdkIsCompileMultilibBoth(t *testing.T) {
+	ctx, _ := testSdk(t, `
+		sdk {
+			name: "mysdk",
+			native_shared_libs: ["sdkmember"],
+		}
+
+		cc_library_shared {
+			name: "sdkmember",
+			srcs: ["Test.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+		}
+	`)
+
+	armOutput := ctx.ModuleForTests("sdkmember", "android_arm_armv7-a-neon_core_shared").Module().(*cc.Module).OutputFile()
+	arm64Output := ctx.ModuleForTests("sdkmember", "android_arm64_armv8-a_core_shared").Module().(*cc.Module).OutputFile()
+
+	var inputs []string
+	buildParams := ctx.ModuleForTests("mysdk", "android_common").Module().BuildParamsForTests()
+	for _, bp := range buildParams {
+		inputs = append(inputs, bp.Implicits.Strings()...)
+	}
+
+	// ensure that both 32/64 outputs are inputs of the sdk snapshot
+	ensureListContains(t, inputs, armOutput.String())
+	ensureListContains(t, inputs, arm64Output.String())
+}
+
 var buildDir string
 
 func setUp() {