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 3070610b72)
This commit is contained in:
Jaekyun Seok 2017-02-02 00:44:58 +09:00
parent 85473982fb
commit 39f97ae22a
5 changed files with 192 additions and 0 deletions

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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="""<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="%s.auto_generated_rro__"
android:versionCode="1"
android:versionName="1.0">
<overlay android:targetPackage="%s" android:priority="0" android:isStatic="true"/>
</manifest>
"""
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)