BUILD_BROKEN_DUP_SYSPROP as escape hatch for the new sysprop restriction

As the final step for the refactoring of sysprop configuration, this
change adds BUILD_BROKEN_DUP_SYSPROP which is the escape hatch for
the new restriction. When it is turned on, the new syntax `a ?= b`
collapses to the old syntax `a = b`, duplicated assignments are allowed,
and the dups are resolved following the legacy rule of preferring the
first.

This change also summarizes all the user-facing changes to the Change.md
file.

Lastly, post_process_prop.py is refactored to accept new argument
'--allow-dup' which when turned on allowes duplicated sysprops.

Bug: 117892318
Bug: 158735147
Test: atest --host post_process_prop_unittest

Exempt-From-Owner-Approval: cherry-pick from master

Merged-In: I7bdfffd47d50aad66a78e28a30c3dad7ebac080c
(cherry picked from commit b302cdf6a417b9c8eaedee713187735a74707d6a)
Change-Id: I7bdfffd47d50aad66a78e28a30c3dad7ebac080c
diff --git a/core/sysprop.mk b/core/sysprop.mk
index 3806a96..aa4fe91 100644
--- a/core/sysprop.mk
+++ b/core/sysprop.mk
@@ -78,6 +78,17 @@
     $(eval _resolved_$(name) := $$(call collapse-pairs,$$(_temp),=))\
 )
 
+$(eval # Implement the legacy behavior when BUILD_BROKEN_DUP_SYSPROP is on.)
+$(eval # Optional assignments are all converted to normal assignments and)
+$(eval # when their duplicates the first one wins)
+$(if $(filter true,$(BUILD_BROKEN_DUP_SYSPROP)),\
+    $(foreach name,$(strip $(4)),\
+        $(eval _temp := $$(subst ?=,=,$$(_resolved_$(name))))\
+        $(eval _resolved_$(name) := $$(call uniq-pairs-by-first-component,$$(_resolved_$(name)),=))\
+    )\
+    $(eval _option := --allow-dup)\
+)
+
 $(2): $(POST_PROCESS_PROPS) $(INTERNAL_BUILD_ID_MAKEFILE) $(API_FINGERPRINT) $(3)
 	$(hide) echo Building $$@
 	$(hide) mkdir -p $$(dir $$@)
@@ -100,7 +111,7 @@
 	        echo "$$(line)" >> $$@;\
 	    )\
 	)
-	$(hide) $(POST_PROCESS_PROPS) $$@ $(5)
+	$(hide) $(POST_PROCESS_PROPS) $$(_option) $$@ $(5)
 	$(hide) echo "# end of file" >> $$@
 endef