Add local preopt options for generating app image and profile

If true, LOCAL_DEX_PREOPT_APP_IMAGE cause dex2oat to generate an app
image.

If true, LOCAL_DEX_PREOPT_GENERATE_PROFILE generates a profile based
on a class listing. LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING must be
defined in this case.

Bug: 34929159

Test: device booting, image loaded

(cherry picked from commit 9968fdcd856b33be7d9f3f8067b584823f2d62b4)

Change-Id: Ib79ada86a4ac617491723f80d99a3add3d52a7f4
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index ae037b3..41ae0f0 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -45,8 +45,11 @@
 LOCAL_CXX_STL := default
 LOCAL_DATA_BINDING:=
 LOCAL_DBUS_PROXY_PREFIX:=
+LOCAL_DEX_PREOPT_APP_IMAGE:=
 LOCAL_DEX_PREOPT_FLAGS:=
+LOCAL_DEX_PREOPT_GENERATE_PROFILE:=
 LOCAL_DEX_PREOPT_IMAGE_LOCATION:=
+LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING:=
 LOCAL_DEX_PREOPT:= # '',true,false,nostripping
 LOCAL_DONT_CHECK_MODULE:=
 # Don't delete the META_INF dir when merging static Java libraries.
diff --git a/core/config.mk b/core/config.mk
index 8fa7d98..849748f 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -635,6 +635,7 @@
 FEC := $(HOST_OUT_EXECUTABLES)/fec
 
 DEXDUMP := $(HOST_OUT_EXECUTABLES)/dexdump2$(BUILD_EXECUTABLE_SUFFIX)
+PROFMAN := $(HOST_OUT_EXECUTABLES)/profman
 
 # relocation packer
 RELOCATION_PACKER := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/relocation_packer/relocation_packer
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index 41e5e87..41c4b2e 100644
--- a/core/dex_preopt_libart.mk
+++ b/core/dex_preopt_libart.mk
@@ -125,5 +125,6 @@
 	--no-inline-from=core-oj.jar \
 	$(PRIVATE_DEX_PREOPT_FLAGS) \
 	$(PRIVATE_ART_FILE_PREOPT_FLAGS) \
+	$(PRIVATE_PROFILE_PREOPT_FLAGS) \
 	$(GLOBAL_DEXPREOPT_FLAGS)
 endef
diff --git a/core/setup_one_odex.mk b/core/setup_one_odex.mk
index 0afc5b7..608ad11 100644
--- a/core/setup_one_odex.mk
+++ b/core/setup_one_odex.mk
@@ -38,7 +38,14 @@
 my_installed_vdex := $(patsubst %.odex,%.vdex,$(my_installed_odex))
 my_installed_art := $(patsubst %.odex,%.art,$(my_installed_odex))
 
-ifeq (true,$(WITH_DEXPREOPT_APP_IMAGE))
+ifndef LOCAL_DEX_PREOPT_APP_IMAGE
+# Local override not defined, use the global one.
+ifeq (true,$(WITH_DEX_PREOPT_APP_IMAGE))
+  LOCAL_DEX_PREOPT_APP_IMAGE := true
+endif
+endif
+
+ifeq (true,$(LOCAL_DEX_PREOPT_APP_IMAGE))
 my_built_art := $(patsubst %.odex,%.art,$(my_built_odex))
 $(my_built_odex): PRIVATE_ART_FILE_PREOPT_FLAGS := --app-image-file=$(my_built_art) \
     --image-format=lz4
@@ -48,6 +55,33 @@
 built_installed_art += $(my_built_art):$(my_installed_art)
 endif
 
+ifndef LOCAL_DEX_PREOPT_GENERATE_PROFILE
+ifeq (true,$(WITH_DEX_PREOPT_GENERATE_PROFILE))
+  LOCAL_DEX_PREOPT_GENERATE_PROFILE := true
+endif
+endif
+
+ifeq (true,$(LOCAL_DEX_PREOPT_GENERATE_PROFILE))
+ifndef LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING
+$(call pretty-error,Must have specified class listing (LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING))
+endif
+my_built_profile := $(dir $(my_built_odex))../../$($(my_2nd_arch_prefix)DEX2OAT_TARGET_ARCH).prof
+my_profile_classes := $(patsubst %.prof,%.classes,$(my_built_profile))
+my_dex_location := $(patsubst $(PRODUCT_OUT)%,%,$(LOCAL_INSTALLED_MODULE))
+$(my_built_odex): $(my_built_profile)
+$(my_built_odex): PRIVATE_PROFILE_PREOPT_FLAGS := --profile-file=$(my_built_profile)
+$(my_built_profile): PRIVATE_INSTALLED_MODULE := $(LOCAL_INSTALLED_MODULE)
+$(my_built_profile): PRIVATE_DEX_LOCATION := $(my_dex_location)
+$(my_built_profile): PRIVATE_PROFILE_CLASSES := $(my_profile_classes)
+$(my_built_profile): PRIVATE_SOURCE_CLASSES := $(LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING)
+$(my_built_profile): $(LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING)
+$(my_built_profile): $(PROFMAN)
+$(my_built_profile): $(PRIVATE_INSTALLED_MODULE)
+$(my_built_profile):
+	cp $(PRIVATE_SOURCE_CLASSES) $(PRIVATE_PROFILE_CLASSES)
+	$(PROFMAN) --create-profile-from=$(PRIVATE_PROFILE_CLASSES) --apk=$(PRIVATE_INSTALLED_MODULE) --dex-location=$(PRIVATE_DEX_LOCATION) --reference-profile-file=$@
+endif
+
 $(eval $(call copy-one-file,$(my_built_odex),$(my_installed_odex)))
 $(eval $(call copy-one-file,$(my_built_vdex),$(my_installed_vdex)))