From 07ceaa71c101a01052e2e36e86ec2adc6d57ca3b Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Fri, 2 Apr 2021 16:29:06 +0900 Subject: [PATCH] Use BOARD_API_LEVEL to define ro.board.api_level GRF devices must define the API level of which the SoC is first shipped by setting BOARD_SHIPPING_API_LEVEL. As this is a permanent value, vendors may not change this value even if they implement new features under the GRF policy. BOARD_API_LEVEL can be optionally defined in this case to manually set the api level of the vendor implementation. The current api level will be set to `ro.board.api_level` property. Bug: 176950752 Test: atest --host post_process_props_unittest Change-Id: Ib126c1a622ded9848650f3f60c0f15005867272d --- core/main.mk | 7 ++++ core/sysprop.mk | 2 +- tools/post_process_props.py | 57 +++++++++++++++++++++++++++++++- tools/test_post_process_props.py | 34 ++++++++++++++++++- 4 files changed, 97 insertions(+), 3 deletions(-) diff --git a/core/main.mk b/core/main.mk index 3362681b6..cc9c809cd 100644 --- a/core/main.mk +++ b/core/main.mk @@ -295,6 +295,13 @@ endif ifdef BOARD_SHIPPING_API_LEVEL ADDITIONAL_VENDOR_PROPERTIES += \ ro.board.first_api_level=$(BOARD_SHIPPING_API_LEVEL) + +# To manually set the vendor API level of the vendor modules, BOARD_API_LEVEL can be used. +# The values of the GRF properties will be verified by post_process_props.py +ifdef BOARD_API_LEVEL +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.board.api_level=$(BOARD_API_LEVEL) +endif endif ADDITIONAL_VENDOR_PROPERTIES += \ diff --git a/core/sysprop.mk b/core/sysprop.mk index 359d3d242..daebdd341 100644 --- a/core/sysprop.mk +++ b/core/sysprop.mk @@ -122,7 +122,7 @@ endif echo "$$(line)" >> $$@;\ )\ ) - $(hide) $(POST_PROCESS_PROPS) $$(_option) $$@ $(5) + $(hide) $(POST_PROCESS_PROPS) $$(_option) --sdk-version $(PLATFORM_SDK_VERSION) $$@ $(5) $(hide) $(foreach file,$(strip $(6)),\ if [ -f "$(file)" ]; then\ cat $(file) >> $$@;\ diff --git a/tools/post_process_props.py b/tools/post_process_props.py index d8c9cb157..46bae2914 100755 --- a/tools/post_process_props.py +++ b/tools/post_process_props.py @@ -42,7 +42,59 @@ def mangle_build_prop(prop_list): # default to "adb". That might not the right policy there, but it's better # to be explicit. if not prop_list.get_value("persist.sys.usb.config"): - prop_list.put("persist.sys.usb.config", "none"); + prop_list.put("persist.sys.usb.config", "none") + +def validate_and_add_grf_props(prop_list, sdk_version): + """Validate GRF properties if exist. + + If ro.board.first_api_level is defined, check if its value is valid for the + sdk version. + Also, validate the value of ro.board.api_level if defined. If the + ro.board.api_level property is not defined, define it with the required + vendor API level for the GRF policy. + + Returns: + True if the GRF properties are valid. + """ + grf_api_level = prop_list.get_value("ro.board.first_api_level") + board_api_level = prop_list.get_value("ro.board.api_level") + + if not grf_api_level: + if board_api_level: + sys.stderr.write("error: non-GRF device must not define " + "ro.board.api_level\n") + return False + # non-GRF device skips the GRF validation test + return True + + grf_api_level = int(grf_api_level) + if grf_api_level > sdk_version: + sys.stderr.write("error: ro.board.first_api_level(%d) must be less than " + "or equal to ro.build.version.sdk(%d)\n" + % (grf_api_level, sdk_version)) + return False + + grf_window = 4 + grf_required_api_level = (grf_api_level + + grf_window * ((sdk_version - grf_api_level) // grf_window)) + + if board_api_level: + board_api_level = int(board_api_level) + if board_api_level < grf_api_level or board_api_level > sdk_version: + sys.stderr.write("error: ro.board.api_level(%d) must be neither less " + "than ro.board.first_api_level(%d) nor greater than " + "ro.build.version.sdk(%d)\n" + % (board_api_level, grf_api_level, sdk_version)) + return False + if board_api_level < grf_required_api_level: + sys.stderr.write("error: ro.board.api_level(%d) must be greater than or " + "equal to %d based on GRF policy\n" + % (board_api_level, grf_required_api_level)) + return False + else: + prop_list.put("ro.board.api_level", str(grf_required_api_level)) + + return True def validate(prop_list): """Validate the properties. @@ -215,6 +267,7 @@ def main(argv): default=False) parser.add_argument("filename") parser.add_argument("disallowed_keys", metavar="KEY", type=str, nargs="*") + parser.add_argument("--sdk-version", type=int, required=True) args = parser.parse_args() if not args.filename.endswith("/build.prop"): @@ -225,6 +278,8 @@ def main(argv): mangle_build_prop(props) if not override_optional_props(props, args.allow_dup): sys.exit(1) + if not validate_and_add_grf_props(props, args.sdk_version): + sys.exit(1) if not validate(props): sys.exit(1) diff --git a/tools/test_post_process_props.py b/tools/test_post_process_props.py index 12d52e566..dd5f8ec97 100644 --- a/tools/test_post_process_props.py +++ b/tools/test_post_process_props.py @@ -53,7 +53,7 @@ class PropTestCase(unittest.TestCase): p.make_as_comment() self.assertTrue(p.is_comment()) - self.assertTrue("# a comment\n#a=b", str(p)) + self.assertEqual("# a comment\n#a=b", str(p)) class PropListTestcase(unittest.TestCase): def setUp(self): @@ -251,5 +251,37 @@ class PropListTestcase(unittest.TestCase): # because it's explicitly allowed self.assertTrue(override_optional_props(props, allow_dup=True)) + def test_validateGrfProps(self): + stderr_redirect = io.StringIO() + with contextlib.redirect_stderr(stderr_redirect): + props = PropList("hello") + props.put("ro.board.first_api_level","25") + + # ro.board.first_api_level must be less than or equal to the sdk version + self.assertFalse(validate_and_add_grf_props(props, 20)) + self.assertTrue(validate_and_add_grf_props(props, 26)) + # ro.board.api_level is automatically set + self.assertEqual(props.get_value("ro.board.api_level"), "25") + + props.get_all_props()[-1].make_as_comment() + self.assertTrue(validate_and_add_grf_props(props, 35)) + # ro.board.api_level is automatically set to the required GRF version + self.assertEqual(props.get_value("ro.board.api_level"), "33") + + props.get_all_props()[-1].make_as_comment() + # manually set ro.board.api_level to an invalid value + props.put("ro.board.api_level","20") + self.assertFalse(validate_and_add_grf_props(props, 26)) + + props.get_all_props()[-1].make_as_comment() + # manually set ro.board.api_level to a valid value + props.put("ro.board.api_level","26") + self.assertTrue(validate_and_add_grf_props(props, 26)) + # ro.board.api_level must be less than or equal to the sdk version + self.assertFalse(validate_and_add_grf_props(props, 25)) + # ro.board.api_level must be greater than or equal to the required GRF + # version + self.assertFalse(validate_and_add_grf_props(props, 30)) + if __name__ == '__main__': unittest.main(verbosity=2)