diff --git a/core/res/res/values/public.xml b/core/res/res/values/public-final.xml
similarity index 97%
rename from core/res/res/values/public.xml
rename to core/res/res/values/public-final.xml
index 80664eb296af2..19a484293b0aa 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public-final.xml
@@ -3222,149 +3222,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
new file mode 100644
index 0000000000000..2dc17b8468c32
--- /dev/null
+++ b/core/res/res/values/public-staging.xml
@@ -0,0 +1,228 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/aapt2/tools/finalize_res.py b/tools/aapt2/tools/finalize_res.py
new file mode 100755
index 0000000000000..0e4d865bc8904
--- /dev/null
+++ b/tools/aapt2/tools/finalize_res.py
@@ -0,0 +1,141 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2022 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.
+#
+# 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.
+
+"""
+Finalize resource values in tags
+and convert those to
+
+Usage: $ANDROID_BUILD_TOP/frameworks/base/tools/aapt2/tools/finalize_res.py \
+ $ANDROID_BUILD_TOP/frameworks/base/core/res/res/values/public-staging.xml \
+ $ANDROID_BUILD_TOP/frameworks/base/core/res/res/values/public-final.xml
+"""
+
+import re
+import sys
+
+resTypes = ["attr", "id", "style", "string", "dimen", "color", "array", "drawable", "layout",
+ "anim", "animator", "interpolator", "mipmap", "integer", "transition", "raw", "bool",
+ "fraction"]
+
+_type_ids = {}
+_type = ""
+
+_lowest_staging_first_id = 0x01FFFFFF
+
+"""
+ Created finalized declarations for staging resources, ignoring them if they've been
+ prefixed with removed_. The IDs are assigned without holes starting from the last ID for that
+ type currently finalized in public-final.xml.
+"""
+def finalize_item(raw):
+ name = raw.group(1)
+ if re.match(r'_*removed.+', name):
+ return ""
+ id = _type_ids[_type]
+ _type_ids[_type] += 1
+ return ' \n' % (_type, name, '0x{0:0{1}x}'.format(id, 8))
+
+
+"""
+ Finalizes staging-public-groups if they have any entries in them. Also keeps track of the
+ lowest first-id of the non-empty groups so that the next release's staging-public-groups can
+ be assigned the next down shifted first-id.
+"""
+def finalize_group(raw):
+ global _type, _lowest_staging_first_id
+ _type = raw.group(1)
+ id = int(raw.group(2), 16)
+ _type_ids[_type] = _type_ids.get(_type, id)
+ (res, count) = re.subn(' {0,4}\n', finalize_item, raw.group(3))
+ if count > 0:
+ res = raw.group(0).replace("staging-public-group",
+ "staging-public-group-final") + '\n' + res
+ _lowest_staging_first_id = min(id, _lowest_staging_first_id)
+ return res
+
+"""
+ Collects the max ID for each resType so that the new IDs can be assigned afterwards
+"""
+def collect_ids(raw):
+ for m in re.finditer(r'', raw):
+ type = m.group(1)
+ id = int(m.group(2), 16)
+ _type_ids[type] = max(id + 1, _type_ids.get(type, 0))
+
+
+with open(sys.argv[1], "r+") as stagingFile:
+ with open(sys.argv[2], "r+") as finalFile:
+ existing = finalFile.read()
+ # Cut out the closing resources tag so that it can be concatenated easily later
+ existing = "\n".join(existing.rsplit("", 1))
+
+ # Collect the IDs from the existing already finalized resources
+ collect_ids(existing)
+
+ staging = stagingFile.read()
+ stagingSplit = staging.rsplit("")
+ staging = stagingSplit[1]
+ staging = re.sub(
+ r'(.+?)',
+ finalize_group, staging, flags=re.DOTALL)
+ staging = re.sub(r' *\n', '\n', staging)
+ staging = re.sub(r'\n{3,}', '\n\n', staging)
+
+ # First write the existing finalized declarations and then append the new stuff
+ finalFile.seek(0)
+ finalFile.write(existing.strip("\n"))
+ finalFile.write("\n\n")
+ finalFile.write(staging.strip("\n"))
+ finalFile.write("\n")
+ finalFile.truncate()
+
+ stagingFile.seek(0)
+ # Include the documentation from public-staging.xml that was previously split out
+ stagingFile.write(stagingSplit[0])
+ # Write the next platform header
+ stagingFile.write("\n\n")
+ stagingFile.write(" \n")
+ stagingFile.write(" \n\n")
+
+ # Seed the next release's staging-public-groups as empty declarations,
+ # so its easy for another developer to expose a new public resource
+ nextId = _lowest_staging_first_id - 0x00010000
+ for resType in resTypes:
+ stagingFile.write(' \n'
+ ' \n\n' %
+ (resType, '0x{0:0{1}x}'.format(nextId, 8)))
+ nextId -= 0x00010000
+
+ # Close the resources tag and truncate, since the file will be shorter than the previous
+ stagingFile.write("\n")
+ stagingFile.truncate()
diff --git a/tools/finalize_res/finalize_res.py b/tools/finalize_res/finalize_res.py
deleted file mode 100755
index aaf01875024ec..0000000000000
--- a/tools/finalize_res/finalize_res.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env python3
-#-*- coding: utf-8 -*-
-
-# Copyright (C) 2021 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.
-
-"""
-Finalize resource values in tags
-
-Usage: finalize_res.py core/res/res/values/public.xml public_finalized.xml
-"""
-
-import re, sys, codecs
-
-def finalize_item(raw):
- global _type, _id
- _id += 1
- return '' % (_type, raw.group(1), '0x{0:0{1}x}'.format(_id-1,8))
-
-def finalize_group(raw):
- global _type, _id
- _type = raw.group(1)
- _id = int(raw.group(2), 16)
- return re.sub(r'', finalize_item, raw.group(3))
-
-with open(sys.argv[1]) as f:
- raw = f.read()
- raw = re.sub(r'(.+?)', finalize_group, raw, flags=re.DOTALL)
- with open(sys.argv[2], "w") as f:
- f.write(raw)