From 39f97ae22a44adc1ce0542056ffa02cec1b21a48 Mon Sep 17 00:00:00 2001 From: Jaekyun Seok Date: Thu, 2 Feb 2017 00:44:58 +0900 Subject: [PATCH] Enforce RROs for all the build-time ROs This CL is to generate every static RRO package for its target package automatically at build-time. BOARD_ENFORCE_RRO build variable is added to specify whether enforcing RRO is required or not. BOARD_ENFORCE_RRO_EXEMPT_SOURCES build variable is added to specify the module list of which item should be exempt from enforcing RRO. Test: tested on bullhead and sailfish Bug: 34097942 Change-Id: I455b2ce34e66c57a540c299b5e378b7c4e78d5b8 (cherry picked from commit 3070610b729e695668a9d93e546907903956a74d) --- core/definitions.mk | 37 +++++++++++ core/generate_enforce_rro.mk | 30 +++++++++ core/main.mk | 11 ++++ core/package_internal.mk | 49 ++++++++++++++ .../generate-enforce-rro-android-manifest.py | 65 +++++++++++++++++++ 5 files changed, 192 insertions(+) create mode 100644 core/generate_enforce_rro.mk create mode 100755 tools/generate-enforce-rro-android-manifest.py diff --git a/core/definitions.mk b/core/definitions.mk index 2870869ab0..07a89488c3 100644 --- a/core/definitions.mk +++ b/core/definitions.mk @@ -3306,3 +3306,40 @@ include $(BUILD_SYSTEM)/distdir.mk # sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ # -e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \ # rm -f $*.d + + +########################################################### +# Append the information to generate a RRO package for the +# source module. +# +# $(1): Source module name. +# $(2): Whether $(3) is a manifest package name or not. +# $(3): Manifest package name if $(2) is true. +# Otherwise, android manifest file path of the +# source module. +# $(4): Whether LOCAL_EXPORT_PACKAGE_RESOURCES is set or +# not for the source module. +# $(5): Resource overlay list. +########################################################### +define append_enforce_rro_sources + $(eval ENFORCE_RRO_SOURCES += \ + $(strip $(1))||$(strip $(2))||$(strip $(3))||$(strip $(4))||$(call normalize-path-list, $(strip $(5)))) +endef + +########################################################### +# Generate all RRO packages for source modules stored in +# ENFORCE_RRO_SOURCES +########################################################### +define generate_all_enforce_rro_packages +$(foreach source,$(ENFORCE_RRO_SOURCES), \ + $(eval _o := $(subst ||,$(space),$(source))) \ + $(eval enforce_rro_source_module := $(word 1,$(_o))) \ + $(eval enforce_rro_source_is_manifest_package_name := $(word 2,$(_o))) \ + $(eval enforce_rro_source_manifest_package_info := $(word 3,$(_o))) \ + $(eval enforce_rro_use_res_lib := $(word 4,$(_o))) \ + $(eval enforce_rro_source_overlays := $(subst :, ,$(word 5,$(_o)))) \ + $(eval enforce_rro_module := $(enforce_rro_source_module)__auto_generated_rro) \ + $(eval include $(BUILD_SYSTEM)/generate_enforce_rro.mk) \ + $(eval ALL_MODULES.$(enforce_rro_source_module).REQUIRED += $(enforce_rro_module)) \ +) +endef \ No newline at end of file diff --git a/core/generate_enforce_rro.mk b/core/generate_enforce_rro.mk new file mode 100644 index 0000000000..579089c086 --- /dev/null +++ b/core/generate_enforce_rro.mk @@ -0,0 +1,30 @@ +include $(CLEAR_VARS) + +LOCAL_PACKAGE_NAME := $(enforce_rro_module) + +intermediates := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,COMMON) +rro_android_manifest_file := $(intermediates)/AndroidManifest.xml + +ifeq (true,$(enforce_rro_source_is_manifest_package_name)) +$(rro_android_manifest_file): PRIVATE_PACKAGE_NAME := $(enforce_rro_source_manifest_package_info) +$(rro_android_manifest_file): build/tools/generate-enforce-rro-android-manifest.py + $(hide) build/tools/generate-enforce-rro-android-manifest.py -u -p $(PRIVATE_PACKAGE_NAME) -o $@ +else +$(rro_android_manifest_file): PRIVATE_SOURCE_MANIFEST_FILE := $(enforce_rro_source_manifest_package_info) +$(rro_android_manifest_file): $(enforce_rro_source_manifest_package_info) build/tools/generate-enforce-rro-android-manifest.py + $(hide) build/tools/generate-enforce-rro-android-manifest.py -p $(PRIVATE_SOURCE_MANIFEST_FILE) -o $@ +endif + +LOCAL_PATH:= $(intermediates) + +ifeq ($(enforce_rro_use_res_lib),true) +LOCAL_RES_LIBRARIES := $(enforce_rro_source_module) +endif + +LOCAL_FULL_MANIFEST_FILE := $(rro_android_manifest_file) +LOCAL_CERTIFICATE := platform + +LOCAL_AAPT_FLAGS += --auto-add-overlay +LOCAL_RESOURCE_DIR := $(enforce_rro_source_overlays) + +include $(BUILD_RRO_PACKAGE) diff --git a/core/main.mk b/core/main.mk index 41d903baab..8200a4c4d6 100644 --- a/core/main.mk +++ b/core/main.mk @@ -497,6 +497,10 @@ ADDITIONAL_DEFAULT_PROPERTIES := $(strip $(ADDITIONAL_DEFAULT_PROPERTIES)) ADDITIONAL_BUILD_PROPERTIES := $(strip $(ADDITIONAL_BUILD_PROPERTIES)) .KATI_READONLY := ADDITIONAL_BUILD_PROPERTIES +ifeq ($(BOARD_ENFORCE_RRO),true) +ENFORCE_RRO_SOURCES := +endif + ifneq ($(ONE_SHOT_MAKEFILE),) # We've probably been invoked by the "mm" shell function # with a subdirectory's makefile. @@ -563,6 +567,13 @@ endif # ONE_SHOT_MAKEFILE # All module makefiles have been included at this point. # ------------------------------------------------------------------- +# ------------------------------------------------------------------- +# Enforce to generate all RRO packages for modules having resource +# overlays. +# ------------------------------------------------------------------- +ifeq ($(BOARD_ENFORCE_RRO),true) +$(call generate_all_enforce_rro_packages) +endif # ------------------------------------------------------------------- # Fix up CUSTOM_MODULES to refer to installed files rather than diff --git a/core/package_internal.mk b/core/package_internal.mk index ca12437817..f68a388e8a 100644 --- a/core/package_internal.mk +++ b/core/package_internal.mk @@ -100,7 +100,32 @@ package_resource_overlays := $(strip \ $(wildcard $(foreach dir, $(DEVICE_PACKAGE_OVERLAYS), \ $(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR))))) +enforce_rro_enabled := +ifeq ($(BOARD_ENFORCE_RRO),true) + ifeq (,$(filter $(LOCAL_PACKAGE_NAME), $(BOARD_ENFORCE_RRO_EXEMPT_SOURCES))) + ifneq ($(package_resource_overlays),) + enforce_rro_enabled := true + endif + endif + + ifdef enforce_rro_enabled + ifeq (,$(LOCAL_MODULE_PATH)) + ifeq (true,$(LOCAL_PROPRIETARY_MODULE)) + enforce_rro_enabled := + else ifeq (true,$(LOCAL_OEM_MODULE)) + enforce_rro_enabled := + else ifeq (true,$(LOCAL_ODM_MODULE)) + enforce_rro_enabled := + endif + else ifeq ($(filter $(TARGET_OUT)/%,$(LOCAL_MODULE_PATH)),) + enforce_rro_enabled := + endif + endif +endif + +ifndef enforce_rro_enabled LOCAL_RESOURCE_DIR := $(package_resource_overlays) $(LOCAL_RESOURCE_DIR) +endif all_assets := $(strip \ $(foreach dir, $(LOCAL_ASSET_DIR), \ @@ -645,3 +670,27 @@ endif # skip_definition # Reset internal variables. all_res_assets := + +ifdef enforce_rro_enabled + ifdef LOCAL_EXPORT_PACKAGE_RESOURCES + enforce_rro_use_res_lib := true + else + enforce_rro_use_res_lib := false + endif + + ifdef LOCAL_MANIFEST_PACKAGE_NAME + enforce_rro_is_manifest_package_name := true + enforce_rro_manifest_package_info := $(LOCAL_MANIFEST_PACKAGE_NAME) + else + enforce_rro_is_manifest_package_name := false + enforce_rro_manifest_package_info := $(full_android_manifest) + endif + +$(call append_enforce_rro_sources, \ + $(my_register_name), \ + $(enforce_rro_is_manifest_package_name), \ + $(enforce_rro_manifest_package_info), \ + $(enforce_rro_use_res_lib), \ + $(package_resource_overlays) \ + ) +endif # enforce_rro_enabled \ No newline at end of file diff --git a/tools/generate-enforce-rro-android-manifest.py b/tools/generate-enforce-rro-android-manifest.py new file mode 100755 index 0000000000..68331cfad1 --- /dev/null +++ b/tools/generate-enforce-rro-android-manifest.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 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. +""" +Utility to generate the Android manifest file of runtime resource overlay +package for source module. +""" +from xml.dom.minidom import parseString +import argparse +import os +import sys + +ANDROID_MANIFEST_TEMPLATE=""" + + +""" + + +def get_args(): + parser = argparse.ArgumentParser() + parser.add_argument( + '-u', '--use-package-name', action='store_true', + help='Indicate that --package-info is a package name.') + parser.add_argument( + '-p', '--package-info', required=True, + help='Manifest package name or manifest file path of source module.') + parser.add_argument( + '-o', '--output', required=True, + help='Output manifest file path.') + return parser.parse_args() + + +def main(argv): + args = get_args() + + package_name = args.package_info + if not args.use_package_name: + with open(args.package_info) as f: + data = f.read() + f.close() + dom = parseString(data) + package_name = dom.documentElement.getAttribute('package') + + with open(args.output, 'w+') as f: + f.write(ANDROID_MANIFEST_TEMPLATE % (package_name, package_name)) + f.close() + + +if __name__ == "__main__": + main(sys.argv)