Merge "Soong: Add mk2bp conversion for prebuilt_usr_share."
diff --git a/androidmk/cmd/androidmk/androidmk_test.go b/androidmk/cmd/androidmk/androidmk_test.go
index 34e673c..88c5304 100644
--- a/androidmk/cmd/androidmk/androidmk_test.go
+++ b/androidmk/cmd/androidmk/androidmk_test.go
@@ -879,7 +879,6 @@
 }
 `,
 	},
-
 	{
 		desc: "prebuilt_etc_PRODUCT_OUT/system/etc",
 		in: `
@@ -1065,6 +1064,80 @@
 `,
 	},
 	{
+		desc: "prebuilt_usr_share",
+		in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/usr/share
+LOCAL_SRC_FILES := foo.txt
+include $(BUILD_PREBUILT)
+`,
+		expected: `
+prebuilt_usr_share {
+	name: "foo",
+
+	src: "foo.txt",
+}
+`,
+	},
+	{
+		desc: "prebuilt_usr_share subdir_bar",
+		in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/usr/share/bar
+LOCAL_SRC_FILES := foo.txt
+include $(BUILD_PREBUILT)
+`,
+		expected: `
+prebuilt_usr_share {
+	name: "foo",
+
+	src: "foo.txt",
+	sub_dir: "bar",
+}
+`,
+	},
+	{
+		desc: "prebuilt_usr_share_host",
+		in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(HOST_OUT)/usr/share
+LOCAL_SRC_FILES := foo.txt
+include $(BUILD_PREBUILT)
+`,
+		expected: `
+prebuilt_usr_share_host {
+	name: "foo",
+
+	src: "foo.txt",
+}
+`,
+	},
+	{
+		desc: "prebuilt_usr_share_host subdir_bar",
+		in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(HOST_OUT)/usr/share/bar
+LOCAL_SRC_FILES := foo.txt
+include $(BUILD_PREBUILT)
+`,
+		expected: `
+prebuilt_usr_share_host {
+	name: "foo",
+
+	src: "foo.txt",
+	sub_dir: "bar",
+}
+`,
+	},
+	{
 		desc: "vts_config",
 		in: `
 include $(CLEAR_VARS)
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index 706c0ec..f217da6 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -431,14 +431,6 @@
 	return ""
 }
 
-// Create sub_dir: attribute for the given path
-func makePrebuiltEtcDestination(mod *parser.Module, path string) {
-	mod.Properties = append(mod.Properties, &parser.Property{
-		Name:  "sub_dir",
-		Value: &parser.String{Value: path},
-	})
-}
-
 // Set the value of the given attribute to the error message
 func indicateAttributeError(mod *parser.Module, attributeName string, format string, a ...interface{}) error {
 	msg := fmt.Sprintf(format, a...)
@@ -464,16 +456,52 @@
 	return val
 }
 
-// A prefix to strip before setting 'filename' attribute and an array of boolean attributes to set.
-type filenamePrefixToFlags struct {
+// etcPrebuiltModuleUpdate contains information on updating certain parts of a defined module such as:
+//    * changing the module type from prebuilt_etc to a different one
+//    * stripping the prefix of the install path based on the module type
+//    * appending additional boolean properties to the prebuilt module
+type etcPrebuiltModuleUpdate struct {
+	// The prefix of the install path defined in local_module_path. The prefix is removed from local_module_path
+	// before setting the 'filename' attribute.
 	prefix string
-	flags  []string
+
+	// There is only one prebuilt module type in makefiles. In Soong, there are multiple versions  of
+	// prebuilts based on local_module_path. By default, it is "prebuilt_etc" if modType is blank. An
+	// example is if the local_module_path contains $(TARGET_OUT)/usr/share, the module type is
+	// considered as prebuilt_usr_share.
+	modType string
+
+	// Additional boolean attributes to be added in the prebuilt module. Each added boolean attribute
+	// has a value of true.
+	flags []string
 }
 
-var localModulePathRewrite = map[string][]filenamePrefixToFlags{
-	"HOST_OUT":                        {{prefix: "/etc"}},
+func (f etcPrebuiltModuleUpdate) update(m *parser.Module, path string) bool {
+	updated := false
+	if path == f.prefix {
+		updated = true
+	} else if trimmedPath := strings.TrimPrefix(path, f.prefix+"/"); trimmedPath != path {
+		m.Properties = append(m.Properties, &parser.Property{
+			Name:  "sub_dir",
+			Value: &parser.String{Value: trimmedPath},
+		})
+		updated = true
+	}
+	if updated {
+		for _, flag := range f.flags {
+			m.Properties = append(m.Properties, &parser.Property{Name: flag, Value: &parser.Bool{Value: true, Token: "true"}})
+		}
+		if f.modType != "" {
+			m.Type = f.modType
+		}
+	}
+	return updated
+}
+
+var localModuleUpdate = map[string][]etcPrebuiltModuleUpdate{
+	"HOST_OUT":                        {{prefix: "/etc", modType: "prebuilt_etc_host"}, {prefix: "/usr/share", modType: "prebuilt_usr_share_host"}},
 	"PRODUCT_OUT":                     {{prefix: "/system/etc"}, {prefix: "/vendor/etc", flags: []string{"proprietary"}}},
-	"TARGET_OUT":                      {{prefix: "/etc"}},
+	"TARGET_OUT":                      {{prefix: "/etc"}, {prefix: "/usr/share", modType: "prebuilt_usr_share"}},
 	"TARGET_OUT_ETC":                  {{prefix: ""}},
 	"TARGET_OUT_PRODUCT":              {{prefix: "/etc", flags: []string{"product_specific"}}},
 	"TARGET_OUT_PRODUCT_ETC":          {{prefix: "", flags: []string{"product_specific"}}},
@@ -526,37 +554,23 @@
 		if prop_local_module_path, ok := mod.GetProperty(local_module_path); ok {
 			removeProperty(mod, local_module_path)
 			prefixVariableName := getStringProperty(prop_local_module_path, "var")
-			path := getStringProperty(prop_local_module_path, "fixed")
-			if prefixRewrites, ok := localModulePathRewrite[prefixVariableName]; ok {
-				rewritten := false
-				for _, prefixRewrite := range prefixRewrites {
-					if path == prefixRewrite.prefix {
-						rewritten = true
-					} else if trimmedPath := strings.TrimPrefix(path, prefixRewrite.prefix+"/"); trimmedPath != path {
-						makePrebuiltEtcDestination(mod, trimmedPath)
-						rewritten = true
-					}
-					if rewritten {
-						for _, flag := range prefixRewrite.flags {
-							mod.Properties = append(mod.Properties, &parser.Property{Name: flag, Value: &parser.Bool{Value: true, Token: "true"}})
-						}
-						break
-					}
+			if moduleUpdates, ok := localModuleUpdate[prefixVariableName]; ok {
+				path := getStringProperty(prop_local_module_path, "fixed")
+				updated := false
+				for i := 0; i < len(moduleUpdates) && !updated; i++ {
+					updated = moduleUpdates[i].update(mod, path)
 				}
-				if !rewritten {
+				if !updated {
 					expectedPrefices := ""
 					sep := ""
-					for _, prefixRewrite := range prefixRewrites {
+					for _, moduleUpdate := range moduleUpdates {
 						expectedPrefices += sep
 						sep = ", "
-						expectedPrefices += prefixRewrite.prefix
+						expectedPrefices += moduleUpdate.prefix
 					}
 					return indicateAttributeError(mod, "filename",
 						"LOCAL_MODULE_PATH value under $(%s) should start with %s", prefixVariableName, expectedPrefices)
 				}
-				if prefixVariableName == "HOST_OUT" {
-					mod.Type = "prebuilt_etc_host"
-				}
 			} else {
 				return indicateAttributeError(mod, "filename", "Cannot handle $(%s) for the prebuilt_etc", prefixVariableName)
 			}