Populate hidden API dark greylist

This patch will iterate over all classes in the light greylist and
add the remaining (currently blacklisted) class members into the
dark greylist. This is meant to mitigate the impact of the feature
on legacy apps, in case their hidden API uses have not been detected
by our analyses. The dark greylist entries will be available to apps
targeting pre-P SDK versions, but blocked for apps targeting P or later.

Bug: 64382372
Test: make out/target/common/obj/PACKAGING/hiddenapi-dark-greylist.txt
Change-Id: Id1ef4ab523b3b4d1333b5fbf2b3e6622ef2be607
diff --git a/Android.mk b/Android.mk
index ff2a62c..218c594 100644
--- a/Android.mk
+++ b/Android.mk
@@ -942,10 +942,23 @@
 	$(call assert-has-no-duplicates,$@)
 	$(call assert-is-subset,$@,$(LOCAL_SRC_PRIVATE_API))
 
-# Generate an empty dark greylist.
+# Generate dark greylist as remaining members of classes on the light greylist,
+# as well as the members of their inner classes.
+# The algorithm is as follows:
+#   (1) extract the class descriptor from each entry in LOCAL_LIGHT_GREYLIST
+#   (2) strip the final semicolon and anything after (and including) a dollar sign,
+#       e.g. 'Lpackage/class$inner;' turns into 'Lpackage/class'
+#   (3) insert all entries from LOCAL_SRC_PRIVATE_API which begin with the stripped
+#       descriptor followed by a semi-colon or a dollar sign, e.g. matching a regex
+#       '^Lpackage/class[;$]'
+#   (4) subtract entries shared with LOCAL_LIGHT_GREYLIST
 $(LOCAL_DARK_GREYLIST): $(LOCAL_SRC_ALL) $(LOCAL_LIGHT_GREYLIST)
-	rm -f $@
-	touch $@
+	comm -13 $(LOCAL_LIGHT_GREYLIST) \
+	         <(sed 's/;\->.*//' $(LOCAL_LIGHT_GREYLIST) | sed 's/$$.*//' | sort | uniq | \
+	               while read CLASS_DESC; do \
+	                   grep -E "^$${CLASS_DESC}[;$$]" $(LOCAL_SRC_PRIVATE_API); \
+	               done | sort | uniq) \
+	         > $@
 	$(call assert-is-subset,$@,$(LOCAL_SRC_PRIVATE_API))
 	$(call assert-has-no-duplicates,$@)
 	$(call assert-has-no-overlap,$@,$(LOCAL_LIGHT_GREYLIST))