Merge "Support package_splits"
diff --git a/android/util.go b/android/util.go
index 8fc159d..f9dce6f 100644
--- a/android/util.go
+++ b/android/util.go
@@ -15,6 +15,8 @@
 package android
 
 import (
+	"fmt"
+	"regexp"
 	"runtime"
 	"sort"
 	"strings"
@@ -164,12 +166,17 @@
 			panic("not called from an init func")
 		}
 
-		if funcName == "init" || strings.HasPrefix(funcName, "init·") {
+		if funcName == "init" || strings.HasPrefix(funcName, "init·") ||
+			strings.HasPrefix(funcName, "init.") {
 			return
 		}
 	}
 }
 
+// A regex to find a package path within a function name. It finds the shortest string that is
+// followed by '.' and doesn't have any '/'s left.
+var pkgPathRe = regexp.MustCompile(`^(.*?)\.([^/]+)$`)
+
 // callerName returns the package path and function name of the calling
 // function.  The skip argument has the same meaning as the skip argument of
 // runtime.Callers.
@@ -180,25 +187,13 @@
 		return "", "", false
 	}
 
-	f := runtime.FuncForPC(pc[0])
-	fullName := f.Name()
-
-	lastDotIndex := strings.LastIndex(fullName, ".")
-	if lastDotIndex == -1 {
-		panic("unable to distinguish function name from package")
+	f := runtime.FuncForPC(pc[0]).Name()
+	s := pkgPathRe.FindStringSubmatch(f)
+	if len(s) < 3 {
+		panic(fmt.Errorf("failed to extract package path and function name from %q", f))
 	}
 
-	if fullName[lastDotIndex-1] == ')' {
-		// The caller is a method on some type, so it's name looks like
-		// "pkg/path.(type).method".  We need to go back one dot farther to get
-		// to the package name.
-		lastDotIndex = strings.LastIndex(fullName[:lastDotIndex], ".")
-	}
-
-	pkgPath = fullName[:lastDotIndex]
-	funcName = fullName[lastDotIndex+1:]
-	ok = true
-	return
+	return s[1], s[2], true
 }
 
 func GetNumericSdkVersion(v string) string {
diff --git a/androidmk/cmd/androidmk/androidmk_test.go b/androidmk/cmd/androidmk/androidmk_test.go
index e3499d2..b2c3fab 100644
--- a/androidmk/cmd/androidmk/androidmk_test.go
+++ b/androidmk/cmd/androidmk/androidmk_test.go
@@ -1095,7 +1095,7 @@
 `,
 	},
 	{
-		desc: "blah",
+		desc: "LOCAL_JACK_ENABLED and LOCAL_JACK_FLAGS skipped",
 		in: `
 include $(CLEAR_VARS)
 LOCAL_MODULE := foo
diff --git a/apex/apex.go b/apex/apex.go
index a70a37b..04b70d4 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -218,6 +218,10 @@
 	// If unspecified, a default one is automatically generated.
 	AndroidManifest *string `android:"path"`
 
+	// Canonical name of the APEX bundle in the manifest file.
+	// If unspecified, defaults to the value of name
+	Apex_name *string
+
 	// Determines the file contexts file for setting security context to each file in this APEX bundle.
 	// Specifically, when this is set to <value>, /system/sepolicy/apex/<value>_file_contexts file is
 	// used.
@@ -1063,17 +1067,19 @@
 		fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
 		fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
 		fmt.Fprintln(w, "LOCAL_MODULE :=", fi.moduleName)
+		// /apex/<name>/{lib|framework|...}
+		pathWhenActivated := filepath.Join("$(PRODUCT_OUT)", "apex",
+			proptools.StringDefault(a.properties.Apex_name, name), fi.installDir)
 		if a.flattened && apexType.image() {
 			// /system/apex/<name>/{lib|framework|...}
 			fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join("$(OUT_DIR)",
 				a.installDir.RelPathString(), name, fi.installDir))
+			fmt.Fprintln(w, "LOCAL_SOONG_SYMBOL_PATH :=", pathWhenActivated)
 			if len(fi.symlinks) > 0 {
 				fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS :=", strings.Join(fi.symlinks, " "))
 			}
 		} else {
-			// /apex/<name>/{lib|framework|...}
-			fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join("$(PRODUCT_OUT)",
-				"apex", name, fi.installDir))
+			fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", pathWhenActivated)
 		}
 		fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", fi.builtFile.String())
 		fmt.Fprintln(w, "LOCAL_MODULE_CLASS :=", fi.class.NameInMake())
diff --git a/cc/config/clang.go b/cc/config/clang.go
index a57bbf8..22969eb 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -97,6 +97,10 @@
 	pctx.StaticVariable("ClangExtraCflags", strings.Join([]string{
 		"-D__compiler_offsetof=__builtin_offsetof",
 
+		// Emit address-significance table which allows linker to perform safe ICF. Clang does
+		// not emit the table by default on Android since NDK still uses GNU binutils.
+		"-faddrsig",
+
 		// -Wimplicit-fallthrough is not enabled by -Wall.
 		"-Wimplicit-fallthrough",
 
diff --git a/java/config/config.go b/java/config/config.go
index 2762a4d..3452a1d 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -41,6 +41,7 @@
 		"services",
 		"android.car",
 		"android.car7",
+		"conscrypt",
 		"core-oj",
 		"core-libart",
 	}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 6441c63..18866d5 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -675,6 +675,34 @@
 	if module.sdkLibraryProperties.Api_packages == nil {
 		mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
 	}
+
+	missing_current_api := false
+
+	for _, scope := range []string{"", "system-", "test-"} {
+		for _, api := range []string{"current.txt", "removed.txt"} {
+			path := path.Join(mctx.ModuleDir(), "api", scope+api)
+			p := android.ExistentPathForSource(mctx, path)
+			if !p.Valid() {
+				mctx.ModuleErrorf("Current api file %#v doesn't exist", path)
+				missing_current_api = true
+			}
+		}
+	}
+
+	if missing_current_api {
+		script := "build/soong/scripts/gen-java-current-api-files.sh"
+		p := android.ExistentPathForSource(mctx, script)
+
+		if !p.Valid() {
+			panic(fmt.Sprintf("script file %s doesn't exist", script))
+		}
+
+		mctx.ModuleErrorf("One or more current api files are missing. "+
+			"You can update them by:\n"+
+			"%s %q && m update-api", script, mctx.ModuleDir())
+		return
+	}
+
 	// for public API stubs
 	module.createStubsLibrary(mctx, apiScopePublic)
 	module.createDocs(mctx, apiScopePublic)
diff --git a/scripts/gen-java-current-api-files.sh b/scripts/gen-java-current-api-files.sh
new file mode 100755
index 0000000..517d391
--- /dev/null
+++ b/scripts/gen-java-current-api-files.sh
@@ -0,0 +1,33 @@
+#!/bin/bash -e
+
+# Copyright (C) 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.
+
+if [[ -z "$1" ]]; then
+  echo "usage: $0 <modulePath>" >&2
+  exit 1
+fi
+
+api_dir=$1/api
+
+mkdir -p "$api_dir"
+
+scopes=("" system- test-)
+apis=(current removed)
+
+for scope in "${scopes[@]}"; do
+  for api in "${apis[@]}"; do
+    touch "${api_dir}/${scope}${api}.txt"
+  done
+done