Merge "Support uid/pid in PermissionEnforcer"
diff --git a/api/Android.bp b/api/Android.bp
index 4cb52bc..9d20eca 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -41,23 +41,6 @@
 }
 
 python_binary_host {
-    name: "api_versions_trimmer",
-    srcs: ["api_versions_trimmer.py"],
-}
-
-python_test_host {
-    name: "api_versions_trimmer_unittests",
-    main: "api_versions_trimmer_unittests.py",
-    srcs: [
-        "api_versions_trimmer_unittests.py",
-        "api_versions_trimmer.py",
-    ],
-    test_options: {
-        unit_test: true,
-    },
-}
-
-python_binary_host {
     name: "merge_annotation_zips",
     srcs: ["merge_annotation_zips.py"],
 }
diff --git a/api/api.go b/api/api.go
index 9876abb..09c2383 100644
--- a/api/api.go
+++ b/api/api.go
@@ -194,55 +194,6 @@
 	}
 }
 
-func createFilteredApiVersions(ctx android.LoadHookContext, modules []string) {
-	// For the filtered api versions, we prune all APIs except art module's APIs. because
-	// 1) ART apis are available by default to all modules, while other module-to-module deps are
-	//    explicit and probably receive more scrutiny anyway
-	// 2) The number of ART/libcore APIs is large, so not linting them would create a large gap
-	// 3) It's a compromise. Ideally we wouldn't be filtering out any module APIs, and have
-	//    per-module lint databases that excludes just that module's APIs. Alas, that's more
-	//    difficult to achieve.
-	modules = remove(modules, art)
-
-	for _, i := range []struct{
-		name string
-		out  string
-		in   string
-	}{
-		{
-			// We shouldn't need public-filtered or system-filtered.
-			// public-filtered is currently used to lint things that
-			// use the module sdk or the system server sdk, but those
-			// should be switched over to module-filtered and
-			// system-server-filtered, and then public-filtered can
-			// be removed.
-			name: "api-versions-xml-public-filtered",
-			out:  "api-versions-public-filtered.xml",
-			in:   ":api_versions_public{.api_versions.xml}",
-		}, {
-			name: "api-versions-xml-module-lib-filtered",
-			out:  "api-versions-module-lib-filtered.xml",
-			in:   ":api_versions_module_lib{.api_versions.xml}",
-		}, {
-			name: "api-versions-xml-system-server-filtered",
-			out:  "api-versions-system-server-filtered.xml",
-			in:   ":api_versions_system_server{.api_versions.xml}",
-		},
-	} {
-		props := genruleProps{}
-		props.Name = proptools.StringPtr(i.name)
-		props.Out = []string{i.out}
-		// Note: order matters: first parameter is the full api-versions.xml
-		// after that the stubs files in any order
-		// stubs files are all modules that export API surfaces EXCEPT ART
-		props.Srcs = append([]string{i.in}, createSrcs(modules, ".stubs{.jar}")...)
-		props.Tools = []string{"api_versions_trimmer"}
-		props.Cmd = proptools.StringPtr("$(location api_versions_trimmer) $(out) $(in)")
-		props.Dists = []android.Dist{{Targets: []string{"sdk"}}}
-		ctx.CreateModule(genrule.GenRuleFactory, &props, &bp2buildNotAvailable)
-	}
-}
-
 func createMergedPublicStubs(ctx android.LoadHookContext, modules []string) {
 	props := libraryProps{}
 	props.Name = proptools.StringPtr("all-modules-public-stubs")
@@ -395,8 +346,6 @@
 
 	createMergedAnnotationsFilegroups(ctx, bootclasspath, system_server_classpath)
 
-	createFilteredApiVersions(ctx, bootclasspath)
-
 	createPublicStubsSourceFilegroup(ctx, bootclasspath)
 }
 
diff --git a/api/api_versions_trimmer.py b/api/api_versions_trimmer.py
deleted file mode 100755
index 9afd95a..0000000
--- a/api/api_versions_trimmer.py
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/env python3
-#
-# 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.
-
-"""Script to remove mainline APIs from the api-versions.xml."""
-
-import argparse
-import re
-import xml.etree.ElementTree as ET
-import zipfile
-
-
-def read_classes(stubs):
-  """Read classes from the stubs file.
-
-  Args:
-    stubs: argument can be a path to a file (a string), a file-like object or a
-    path-like object
-
-  Returns:
-    a set of the classes found in the file (set of strings)
-  """
-  classes = set()
-  with zipfile.ZipFile(stubs) as z:
-    for info in z.infolist():
-      if (not info.is_dir()
-          and info.filename.endswith(".class")
-          and not info.filename.startswith("META-INF")):
-        # drop ".class" extension
-        classes.add(info.filename[:-6])
-  return classes
-
-
-def filter_method_tag(method, classes_to_remove):
-  """Updates the signature of this method by calling filter_method_signature.
-
-  Updates the method passed into this function.
-
-  Args:
-    method: xml element that represents a method
-    classes_to_remove: set of classes you to remove
-  """
-  filtered = filter_method_signature(method.get("name"), classes_to_remove)
-  method.set("name", filtered)
-
-
-def filter_method_signature(signature, classes_to_remove):
-  """Removes mentions of certain classes from this method signature.
-
-  Replaces any existing classes that need to be removed, with java/lang/Object
-
-  Args:
-    signature: string that is a java representation of a method signature
-    classes_to_remove: set of classes you to remove
-  """
-  regex = re.compile("L.*?;")
-  start = signature.find("(")
-  matches = set(regex.findall(signature[start:]))
-  for m in matches:
-    # m[1:-1] to drop the leading `L` and `;` ending
-    if m[1:-1] in classes_to_remove:
-      signature = signature.replace(m, "Ljava/lang/Object;")
-  return signature
-
-
-def filter_lint_database(database, classes_to_remove, output):
-  """Reads a lint database and writes a filtered version without some classes.
-
-  Reads database from api-versions.xml and removes any references to classes
-  in the second argument. Writes the result (another xml with the same format
-  of the database) to output.
-
-  Args:
-    database: path to xml with lint database to read
-    classes_to_remove: iterable (ideally a set or similar for quick
-    lookups) that enumerates the classes that should be removed
-    output: path to write the filtered database
-  """
-  xml = ET.parse(database)
-  root = xml.getroot()
-  for c in xml.findall("class"):
-    cname = c.get("name")
-    if cname in classes_to_remove:
-      root.remove(c)
-    else:
-      # find the <extends /> tag inside this class to see if the parent
-      # has been removed from the known classes (attribute called name)
-      super_classes = c.findall("extends")
-      for super_class in super_classes:
-        super_class_name = super_class.get("name")
-        if super_class_name in classes_to_remove:
-          super_class.set("name", "java/lang/Object")
-      interfaces = c.findall("implements")
-      for interface in interfaces:
-        interface_name = interface.get("name")
-        if interface_name in classes_to_remove:
-          c.remove(interface)
-      for method in c.findall("method"):
-        filter_method_tag(method, classes_to_remove)
-  xml.write(output)
-
-
-def main():
-  """Run the program."""
-  parser = argparse.ArgumentParser(
-      description=
-      ("Read a lint database (api-versions.xml) and many stubs jar files. "
-       "Produce another database file that doesn't include the classes present "
-       "in the stubs file(s)."))
-  parser.add_argument("output", help="Destination of the result (xml file).")
-  parser.add_argument(
-      "api_versions",
-      help="The lint database (api-versions.xml file) to read data from"
-  )
-  parser.add_argument("stubs", nargs="+", help="The stubs jar file(s)")
-  parsed = parser.parse_args()
-  classes = set()
-  for stub in parsed.stubs:
-    classes.update(read_classes(stub))
-  filter_lint_database(parsed.api_versions, classes, parsed.output)
-
-
-if __name__ == "__main__":
-  main()
diff --git a/api/api_versions_trimmer_unittests.py b/api/api_versions_trimmer_unittests.py
deleted file mode 100644
index d2e5b7d..0000000
--- a/api/api_versions_trimmer_unittests.py
+++ /dev/null
@@ -1,307 +0,0 @@
-#!/usr/bin/env python3
-#
-# 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.
-
-import io
-import re
-import unittest
-import xml.etree.ElementTree as ET
-import zipfile
-
-import api_versions_trimmer
-
-
-def create_in_memory_zip_file(files):
-  f = io.BytesIO()
-  with zipfile.ZipFile(f, "w") as z:
-    for fname in files:
-      with z.open(fname, mode="w") as class_file:
-        class_file.write(b"")
-  return f
-
-
-def indent(elem, level=0):
-  i = "\n" + level * "  "
-  j = "\n" + (level - 1) * "  "
-  if len(elem):
-    if not elem.text or not elem.text.strip():
-      elem.text = i + "  "
-      if not elem.tail or not elem.tail.strip():
-        elem.tail = i
-        for subelem in elem:
-          indent(subelem, level + 1)
-        if not elem.tail or not elem.tail.strip():
-          elem.tail = j
-    else:
-      if level and (not elem.tail or not elem.tail.strip()):
-        elem.tail = j
-    return elem
-
-
-def pretty_print(s):
-  tree = ET.parse(io.StringIO(s))
-  el = indent(tree.getroot())
-  res = ET.tostring(el).decode("utf-8")
-  # remove empty lines inside the result because this still breaks some
-  # comparisons
-  return re.sub(r"\n\s*\n", "\n", res, re.MULTILINE)
-
-
-class ApiVersionsTrimmerUnittests(unittest.TestCase):
-
-  def setUp(self):
-    # so it prints diffs in long strings (xml files)
-    self.maxDiff = None
-
-  def test_read_classes(self):
-    f = create_in_memory_zip_file(
-        ["a/b/C.class",
-         "a/b/D.class",
-        ]
-    )
-    res = api_versions_trimmer.read_classes(f)
-    self.assertEqual({"a/b/C", "a/b/D"}, res)
-
-  def test_read_classes_ignore_dex(self):
-    f = create_in_memory_zip_file(
-        ["a/b/C.class",
-         "a/b/D.class",
-         "a/b/E.dex",
-         "f.dex",
-        ]
-    )
-    res = api_versions_trimmer.read_classes(f)
-    self.assertEqual({"a/b/C", "a/b/D"}, res)
-
-  def test_read_classes_ignore_manifest(self):
-    f = create_in_memory_zip_file(
-        ["a/b/C.class",
-         "a/b/D.class",
-         "META-INFO/G.class"
-        ]
-    )
-    res = api_versions_trimmer.read_classes(f)
-    self.assertEqual({"a/b/C", "a/b/D"}, res)
-
-  def test_filter_method_signature(self):
-    xml = """
-    <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/>
-    """
-    method = ET.fromstring(xml)
-    classes_to_remove = {"android/accessibilityservice/GestureDescription"}
-    expected = "dispatchGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z"
-    api_versions_trimmer.filter_method_tag(method, classes_to_remove)
-    self.assertEqual(expected, method.get("name"))
-
-  def test_filter_method_signature_with_L_in_method(self):
-    xml = """
-    <method name="dispatchLeftGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/>
-    """
-    method = ET.fromstring(xml)
-    classes_to_remove = {"android/accessibilityservice/GestureDescription"}
-    expected = "dispatchLeftGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z"
-    api_versions_trimmer.filter_method_tag(method, classes_to_remove)
-    self.assertEqual(expected, method.get("name"))
-
-  def test_filter_method_signature_with_L_in_class(self):
-    xml = """
-    <method name="dispatchGesture(Landroid/accessibilityservice/LeftGestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/>
-    """
-    method = ET.fromstring(xml)
-    classes_to_remove = {"android/accessibilityservice/LeftGestureDescription"}
-    expected = "dispatchGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z"
-    api_versions_trimmer.filter_method_tag(method, classes_to_remove)
-    self.assertEqual(expected, method.get("name"))
-
-  def test_filter_method_signature_with_inner_class(self):
-    xml = """
-    <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription$Inner;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/>
-    """
-    method = ET.fromstring(xml)
-    classes_to_remove = {"android/accessibilityservice/GestureDescription$Inner"}
-    expected = "dispatchGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z"
-    api_versions_trimmer.filter_method_tag(method, classes_to_remove)
-    self.assertEqual(expected, method.get("name"))
-
-  def _run_filter_db_test(self, database_str, expected):
-    """Performs the pattern of testing the filter_lint_database method.
-
-    Filters instances of the class "a/b/C" (hard-coded) from the database string
-    and compares the result with the expected result (performs formatting of
-    the xml of both inputs)
-
-    Args:
-      database_str: string, the contents of the lint database (api-versions.xml)
-      expected: string, the expected result after filtering the original
-    database
-    """
-    database = io.StringIO(database_str)
-    classes_to_remove = {"a/b/C"}
-    output = io.BytesIO()
-    api_versions_trimmer.filter_lint_database(
-        database,
-        classes_to_remove,
-        output
-    )
-    expected = pretty_print(expected)
-    res = pretty_print(output.getvalue().decode("utf-8"))
-    self.assertEqual(expected, res)
-
-  def test_filter_lint_database_updates_method_signature_params(self):
-    self._run_filter_db_test(
-        database_str="""
-    <api version="2">
-      <!-- will be removed -->
-      <class name="a/b/C" since="1">
-        <extends name="java/lang/Object"/>
-      </class>
-
-      <class name="a/b/E" since="1">
-        <!-- extends will be modified -->
-        <extends name="a/b/C"/>
-        <!-- first parameter will be modified -->
-        <method name="dispatchGesture(La/b/C;Landroid/os/Handler;)Z" since="24"/>
-        <!-- second should remain untouched -->
-        <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
-      </class>
-    </api>
-    """,
-        expected="""
-    <api version="2">
-      <class name="a/b/E" since="1">
-        <extends name="java/lang/Object"/>
-        <method name="dispatchGesture(Ljava/lang/Object;Landroid/os/Handler;)Z" since="24"/>
-        <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
-      </class>
-    </api>
-    """)
-
-  def test_filter_lint_database_updates_method_signature_return(self):
-    self._run_filter_db_test(
-        database_str="""
-    <api version="2">
-      <!-- will be removed -->
-      <class name="a/b/C" since="1">
-        <extends name="java/lang/Object"/>
-      </class>
-
-      <class name="a/b/E" since="1">
-        <!-- extends will be modified -->
-        <extends name="a/b/C"/>
-        <!-- return type should be changed -->
-        <method name="gestureIdToString(I)La/b/C;" since="24"/>
-      </class>
-    </api>
-    """,
-        expected="""
-    <api version="2">
-      <class name="a/b/E" since="1">
-
-        <extends name="java/lang/Object"/>
-
-        <method name="gestureIdToString(I)Ljava/lang/Object;" since="24"/>
-      </class>
-    </api>
-    """)
-
-  def test_filter_lint_database_removes_implements(self):
-    self._run_filter_db_test(
-        database_str="""
-    <api version="2">
-      <!-- will be removed -->
-      <class name="a/b/C" since="1">
-        <extends name="java/lang/Object"/>
-      </class>
-
-      <class name="a/b/D" since="1">
-        <extends name="java/lang/Object"/>
-        <implements name="a/b/C"/>
-        <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
-      </class>
-    </api>
-    """,
-        expected="""
-    <api version="2">
-
-      <class name="a/b/D" since="1">
-        <extends name="java/lang/Object"/>
-        <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
-      </class>
-    </api>
-    """)
-
-  def test_filter_lint_database_updates_extends(self):
-    self._run_filter_db_test(
-        database_str="""
-    <api version="2">
-      <!-- will be removed -->
-      <class name="a/b/C" since="1">
-        <extends name="java/lang/Object"/>
-      </class>
-
-      <class name="a/b/E" since="1">
-        <!-- extends will be modified -->
-        <extends name="a/b/C"/>
-        <method name="dispatchGesture(Ljava/lang/Object;Landroid/os/Handler;)Z" since="24"/>
-        <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
-      </class>
-    </api>
-    """,
-        expected="""
-    <api version="2">
-      <class name="a/b/E" since="1">
-        <extends name="java/lang/Object"/>
-        <method name="dispatchGesture(Ljava/lang/Object;Landroid/os/Handler;)Z" since="24"/>
-        <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
-      </class>
-    </api>
-    """)
-
-  def test_filter_lint_database_removes_class(self):
-    self._run_filter_db_test(
-        database_str="""
-    <api version="2">
-      <!-- will be removed -->
-      <class name="a/b/C" since="1">
-        <extends name="java/lang/Object"/>
-      </class>
-
-      <class name="a/b/D" since="1">
-        <extends name="java/lang/Object"/>
-        <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
-      </class>
-    </api>
-    """,
-        expected="""
-    <api version="2">
-
-      <class name="a/b/D" since="1">
-        <extends name="java/lang/Object"/>
-        <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
-      </class>
-    </api>
-    """)
-
-
-if __name__ == "__main__":
-  unittest.main(verbosity=2)
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 1efdf77..6b6bc97 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -460,6 +460,7 @@
 
 EGLConfig BootAnimation::getEglConfig(const EGLDisplay& display) {
     const EGLint attribs[] = {
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
         EGL_RED_SIZE,   8,
         EGL_GREEN_SIZE, 8,
         EGL_BLUE_SIZE,  8,
diff --git a/core/java/android/nfc/tech/IsoDep.java b/core/java/android/nfc/tech/IsoDep.java
index 089b159..0ba0c5a 100644
--- a/core/java/android/nfc/tech/IsoDep.java
+++ b/core/java/android/nfc/tech/IsoDep.java
@@ -88,6 +88,7 @@
      * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
      *
      * @param timeout timeout value in milliseconds
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public void setTimeout(int timeout) {
         try {
@@ -106,6 +107,7 @@
      * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
      *
      * @return timeout value in milliseconds
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public int getTimeout() {
         try {
@@ -167,6 +169,7 @@
      * @return response bytes received, will not be null
      * @throws TagLostException if the tag leaves the field
      * @throws IOException if there is an I/O failure, or this operation is canceled
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public byte[] transceive(byte[] data) throws IOException {
         return transceive(data, true);
@@ -193,6 +196,7 @@
      * support.
      *
      * @return whether the NFC adapter on this device supports extended length APDUs.
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public boolean isExtendedLengthApduSupported() {
         try {
diff --git a/core/java/android/nfc/tech/MifareClassic.java b/core/java/android/nfc/tech/MifareClassic.java
index 080e058..26f54e6 100644
--- a/core/java/android/nfc/tech/MifareClassic.java
+++ b/core/java/android/nfc/tech/MifareClassic.java
@@ -597,6 +597,7 @@
      * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
      *
      * @param timeout timeout value in milliseconds
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public void setTimeout(int timeout) {
         try {
@@ -615,6 +616,7 @@
      * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
      *
      * @return timeout value in milliseconds
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public int getTimeout() {
         try {
diff --git a/core/java/android/nfc/tech/MifareUltralight.java b/core/java/android/nfc/tech/MifareUltralight.java
index dec2c65..c0416a3 100644
--- a/core/java/android/nfc/tech/MifareUltralight.java
+++ b/core/java/android/nfc/tech/MifareUltralight.java
@@ -236,6 +236,7 @@
      * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
      *
      * @param timeout timeout value in milliseconds
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public void setTimeout(int timeout) {
         try {
@@ -255,6 +256,7 @@
      * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
      *
      * @return timeout value in milliseconds
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public int getTimeout() {
         try {
diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java
index 2256365..bb750cf 100644
--- a/core/java/android/nfc/tech/Ndef.java
+++ b/core/java/android/nfc/tech/Ndef.java
@@ -261,6 +261,7 @@
      * @throws TagLostException if the tag leaves the field
      * @throws IOException if there is an I/O failure, or the operation is canceled
      * @throws FormatException if the NDEF Message on the tag is malformed
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public NdefMessage getNdefMessage() throws IOException, FormatException {
         checkConnected();
@@ -301,6 +302,7 @@
      * @throws TagLostException if the tag leaves the field
      * @throws IOException if there is an I/O failure, or the operation is canceled
      * @throws FormatException if the NDEF Message to write is malformed
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException {
         checkConnected();
@@ -339,6 +341,7 @@
      * <p>Does not cause any RF activity and does not block.
      *
      * @return true if it is possible to make this tag read-only
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public boolean canMakeReadOnly() {
         INfcTag tagService = mTag.getTagService();
@@ -370,6 +373,7 @@
      * @return true on success, false if it is not possible to make this tag read-only
      * @throws TagLostException if the tag leaves the field
      * @throws IOException if there is an I/O failure, or the operation is canceled
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public boolean makeReadOnly() throws IOException {
         checkConnected();
diff --git a/core/java/android/nfc/tech/NdefFormatable.java b/core/java/android/nfc/tech/NdefFormatable.java
index 4175cd0..f19d302 100644
--- a/core/java/android/nfc/tech/NdefFormatable.java
+++ b/core/java/android/nfc/tech/NdefFormatable.java
@@ -111,6 +111,7 @@
      * @throws TagLostException if the tag leaves the field
      * @throws IOException if there is an I/O failure, or the operation is canceled
      * @throws FormatException if the NDEF Message to write is malformed
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public void formatReadOnly(NdefMessage firstMessage) throws IOException, FormatException {
         format(firstMessage, true);
diff --git a/core/java/android/nfc/tech/NfcA.java b/core/java/android/nfc/tech/NfcA.java
index 88730f9..7e66483 100644
--- a/core/java/android/nfc/tech/NfcA.java
+++ b/core/java/android/nfc/tech/NfcA.java
@@ -141,6 +141,7 @@
      * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
      *
      * @param timeout timeout value in milliseconds
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public void setTimeout(int timeout) {
         try {
@@ -159,6 +160,7 @@
      * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
      *
      * @return timeout value in milliseconds
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public int getTimeout() {
         try {
diff --git a/core/java/android/nfc/tech/NfcF.java b/core/java/android/nfc/tech/NfcF.java
index 4487121..2ccd388 100644
--- a/core/java/android/nfc/tech/NfcF.java
+++ b/core/java/android/nfc/tech/NfcF.java
@@ -145,6 +145,7 @@
      * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
      *
      * @param timeout timeout value in milliseconds
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public void setTimeout(int timeout) {
         try {
@@ -163,6 +164,7 @@
      * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
      *
      * @return timeout value in milliseconds
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public int getTimeout() {
         try {
diff --git a/core/java/android/nfc/tech/TagTechnology.java b/core/java/android/nfc/tech/TagTechnology.java
index 0e2c7c1..839fe42 100644
--- a/core/java/android/nfc/tech/TagTechnology.java
+++ b/core/java/android/nfc/tech/TagTechnology.java
@@ -176,6 +176,7 @@
      * @see #close()
      * @throws TagLostException if the tag leaves the field
      * @throws IOException if there is an I/O failure, or connect is canceled
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public void connect() throws IOException;
 
@@ -193,6 +194,7 @@
      * @see #close()
      * @throws TagLostException if the tag leaves the field
      * @throws IOException if there is an I/O failure, or connect is canceled
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      * @hide
      */
     public void reconnect() throws IOException;
@@ -205,6 +207,7 @@
      * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
      *
      * @see #connect()
+     * @throws SecurityException if the tag object is reused after the tag has left the field
      */
     public void close() throws IOException;
 
diff --git a/core/java/android/widget/OWNERS b/core/java/android/widget/OWNERS
index 02dafd4..7f0a651 100644
--- a/core/java/android/widget/OWNERS
+++ b/core/java/android/widget/OWNERS
@@ -13,3 +13,5 @@
 per-file SpellChecker.java = file:../view/inputmethod/OWNERS
 
 per-file RemoteViews* = file:../appwidget/OWNERS
+
+per-file Toast.java = juliacr@google.com, jeffdq@google.com
diff --git a/core/java/com/android/internal/app/OWNERS b/core/java/com/android/internal/app/OWNERS
index 0d02683..a1d571f 100644
--- a/core/java/com/android/internal/app/OWNERS
+++ b/core/java/com/android/internal/app/OWNERS
@@ -1,4 +1,6 @@
 per-file *AppOp* = file:/core/java/android/permission/OWNERS
+per-file UnlaunchableAppActivity.java = file:/core/java/android/app/admin/WorkProfile_OWNERS
+per-file IntentForwarderActivity.java = file:/core/java/android/app/admin/WorkProfile_OWNERS
 per-file *Resolver* = file:/packages/SystemUI/OWNERS
 per-file *Chooser* = file:/packages/SystemUI/OWNERS
 per-file SimpleIconFactory.java = file:/packages/SystemUI/OWNERS
diff --git a/core/java/com/android/internal/expresslog/Counter.java b/core/java/com/android/internal/expresslog/Counter.java
index afdbdc8..4a46d91 100644
--- a/core/java/com/android/internal/expresslog/Counter.java
+++ b/core/java/com/android/internal/expresslog/Counter.java
@@ -36,6 +36,16 @@
     }
 
     /**
+     * Increments Telemetry Express Counter metric by 1
+     * @param metricId to log, no-op if metricId is not defined in the TeX catalog
+     * @param uid used as a dimension for the count metric
+     * @hide
+     */
+    public static void logIncrementWithUid(@NonNull String metricId, int uid) {
+        logIncrementWithUid(metricId, uid, 1);
+    }
+
+    /**
      * Increments Telemetry Express Counter metric by arbitrary value
      * @param metricId to log, no-op if metricId is not defined in the TeX catalog
      * @param amount to increment counter
@@ -45,4 +55,17 @@
         final long metricIdHash = Utils.hashString(metricId);
         FrameworkStatsLog.write(FrameworkStatsLog.EXPRESS_EVENT_REPORTED, metricIdHash, amount);
     }
+
+    /**
+     * Increments Telemetry Express Counter metric by arbitrary value
+     * @param metricId to log, no-op if metricId is not defined in the TeX catalog
+     * @param uid used as a dimension for the count metric
+     * @param amount to increment counter
+     * @hide
+     */
+    public static void logIncrementWithUid(@NonNull String metricId, int uid, long amount) {
+        final long metricIdHash = Utils.hashString(metricId);
+        FrameworkStatsLog.write(
+                FrameworkStatsLog.EXPRESS_UID_EVENT_REPORTED, metricIdHash, amount, uid);
+    }
 }
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 1505ccc..85cb15b 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -721,7 +721,8 @@
         } catch (ErrnoException ex) {
             throw new RuntimeException("Failed to capget()", ex);
         }
-        capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
+        capabilities &= Integer.toUnsignedLong(data[0].effective) |
+                (Integer.toUnsignedLong(data[1].effective) << 32);
 
         /* Hardcoded command line to start the system server */
         String[] args = {
diff --git a/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS b/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
new file mode 100644
index 0000000..7755000
--- /dev/null
+++ b/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
@@ -0,0 +1,3 @@
+# TODO(b/274465475): Migrate LatencyTracker testing to its own module
+marcinoc@google.com
+ilkos@google.com
diff --git a/core/java/com/android/internal/util/OWNERS b/core/java/com/android/internal/util/OWNERS
index 1808bd5..9be8ea7 100644
--- a/core/java/com/android/internal/util/OWNERS
+++ b/core/java/com/android/internal/util/OWNERS
@@ -6,3 +6,4 @@
 per-file State* = jchalard@google.com, lorenzo@google.com, satk@google.com
 per-file *Dump* = file:/core/java/com/android/internal/util/dump/OWNERS
 per-file *Screenshot* = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
+per-file *LatencyTracker* = file:/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 57a196f..a5d979c 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -2296,7 +2296,9 @@
     // region shared with the child process we reduce the number of pages that
     // transition to the private-dirty state when malloc adjusts the meta-data
     // on each of the pages it is managing after the fork.
-    mallopt(M_PURGE, 0);
+    if (mallopt(M_PURGE_ALL, 0) != 1) {
+      mallopt(M_PURGE, 0);
+    }
   }
 
   pid_t pid = fork();
diff --git a/core/tests/coretests/src/com/android/internal/util/OWNERS b/core/tests/coretests/src/com/android/internal/util/OWNERS
index d832745..dda11fb 100644
--- a/core/tests/coretests/src/com/android/internal/util/OWNERS
+++ b/core/tests/coretests/src/com/android/internal/util/OWNERS
@@ -1,2 +1,3 @@
 per-file *Notification* = file:/services/core/java/com/android/server/notification/OWNERS
-per-file *ContrastColor* = file:/services/core/java/com/android/server/notification/OWNERS
\ No newline at end of file
+per-file *ContrastColor* = file:/services/core/java/com/android/server/notification/OWNERS
+per-file *LatencyTracker* = file:/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
diff --git a/core/tests/coretests/testdoubles/OWNERS b/core/tests/coretests/testdoubles/OWNERS
new file mode 100644
index 0000000..baf92ec
--- /dev/null
+++ b/core/tests/coretests/testdoubles/OWNERS
@@ -0,0 +1 @@
+per-file *LatencyTracker* = file:/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
diff --git a/keystore/java/android/security/keystore2/KeyStoreCryptoOperationUtils.java b/keystore/java/android/security/keystore2/KeyStoreCryptoOperationUtils.java
index 6fa1a69..372e4cb 100644
--- a/keystore/java/android/security/keystore2/KeyStoreCryptoOperationUtils.java
+++ b/keystore/java/android/security/keystore2/KeyStoreCryptoOperationUtils.java
@@ -40,7 +40,6 @@
 import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Random;
 
 /**
  * Assorted utility methods for implementing crypto operations on top of KeyStore.
@@ -50,7 +49,6 @@
 abstract class KeyStoreCryptoOperationUtils {
 
     private static volatile SecureRandom sRng;
-    private static final Random sRandom = new Random();
 
     private KeyStoreCryptoOperationUtils() {}
 
@@ -213,7 +211,7 @@
         } else {
             // Keystore won't give us an operation challenge if the operation doesn't
             // need user authorization. So we make our own.
-            return sRandom.nextLong();
+            return getRng().nextLong();
         }
     }
 }
diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java
index e6d95eb6..cf3ba87 100644
--- a/media/java/android/media/ThumbnailUtils.java
+++ b/media/java/android/media/ThumbnailUtils.java
@@ -49,6 +49,7 @@
 import libcore.io.IoUtils;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Comparator;
@@ -255,17 +256,19 @@
 
         // get orientation
         if (MediaFile.isExifMimeType(mimeType)) {
-            exif = new ExifInterface(file);
-            switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0)) {
-                case ExifInterface.ORIENTATION_ROTATE_90:
-                    orientation = 90;
-                    break;
-                case ExifInterface.ORIENTATION_ROTATE_180:
-                    orientation = 180;
-                    break;
-                case ExifInterface.ORIENTATION_ROTATE_270:
-                    orientation = 270;
-                    break;
+            try (FileInputStream is = new FileInputStream(file)) {
+                exif = new ExifInterface(is.getFD());
+                switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0)) {
+                    case ExifInterface.ORIENTATION_ROTATE_90:
+                        orientation = 90;
+                        break;
+                    case ExifInterface.ORIENTATION_ROTATE_180:
+                        orientation = 180;
+                        break;
+                    case ExifInterface.ORIENTATION_ROTATE_270:
+                        orientation = 270;
+                        break;
+                }
             }
         }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
index c61ebc0..0630a2e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
@@ -261,19 +261,21 @@
         Pattern pattern = Pattern.compile(PATTERN_BT_BROADCAST_METADATA);
         Matcher match = pattern.matcher(qrCodeString);
         if (match.find()) {
-            mSourceAddressType = Integer.parseInt(match.group(MATCH_INDEX_ADDRESS_TYPE));
-            mSourceDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(
+            try {
+                mSourceAddressType = Integer.parseInt(match.group(MATCH_INDEX_ADDRESS_TYPE));
+                mSourceDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(
                     match.group(MATCH_INDEX_DEVICE));
-            mSourceAdvertisingSid = Integer.parseInt(match.group(MATCH_INDEX_ADVERTISING_SID));
-            mBroadcastId = Integer.parseInt(match.group(MATCH_INDEX_BROADCAST_ID));
-            mPaSyncInterval = Integer.parseInt(match.group(MATCH_INDEX_SYNC_INTERVAL));
-            mIsEncrypted = Boolean.valueOf(match.group(MATCH_INDEX_IS_ENCRYPTED));
-            mBroadcastCode = match.group(MATCH_INDEX_BROADCAST_CODE).getBytes();
-            mPresentationDelayMicros =
-                  Integer.parseInt(match.group(MATCH_INDEX_PRESENTATION_DELAY));
+                mSourceAdvertisingSid = Integer.parseInt(
+                    match.group(MATCH_INDEX_ADVERTISING_SID));
+                mBroadcastId = Integer.parseInt(match.group(MATCH_INDEX_BROADCAST_ID));
+                mPaSyncInterval = Integer.parseInt(match.group(MATCH_INDEX_SYNC_INTERVAL));
+                mIsEncrypted = Boolean.valueOf(match.group(MATCH_INDEX_IS_ENCRYPTED));
+                mBroadcastCode = match.group(MATCH_INDEX_BROADCAST_CODE).getBytes();
+                mPresentationDelayMicros =
+                    Integer.parseInt(match.group(MATCH_INDEX_PRESENTATION_DELAY));
 
-            if (DEBUG) {
-                Log.d(TAG, "Converted qrCodeString result: "
+                if (DEBUG) {
+                    Log.d(TAG, "Converted qrCodeString result: "
                         + " ,Type = " + mSourceAddressType
                         + " ,Device = " + mSourceDevice
                         + " ,AdSid = " + mSourceAdvertisingSid
@@ -282,11 +284,11 @@
                         + " ,encrypted = " + mIsEncrypted
                         + " ,BroadcastCode = " + Arrays.toString(mBroadcastCode)
                         + " ,delay = " + mPresentationDelayMicros);
-            }
+                }
 
-            mSubgroup = convertToSubgroup(match.group(MATCH_INDEX_SUBGROUPS));
+                mSubgroup = convertToSubgroup(match.group(MATCH_INDEX_SUBGROUPS));
 
-            return new BluetoothLeBroadcastMetadata.Builder()
+                return new BluetoothLeBroadcastMetadata.Builder()
                     .setSourceDevice(mSourceDevice, mSourceAddressType)
                     .setSourceAdvertisingSid(mSourceAdvertisingSid)
                     .setBroadcastId(mBroadcastId)
@@ -296,10 +298,13 @@
                     .setPresentationDelayMicros(mPresentationDelayMicros)
                     .addSubgroup(mSubgroup)
                     .build();
+            } catch (IllegalArgumentException e) {
+                Log.d(TAG, "IllegalArgumentException when convert : " + e);
+                return null;
+            }
         } else {
             if (DEBUG) {
-                Log.d(TAG,
-                        "The match fail, can not convert it to BluetoothLeBroadcastMetadata.");
+                Log.d(TAG, "The match fail, can not convert it to BluetoothLeBroadcastMetadata.");
             }
             return null;
         }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 593acd6..5ca03b8 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1313,8 +1313,8 @@
         intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
         if (mMonitorRotation) {
             RotationHelper.init(mContext, mAudioHandler,
-                    rotationParam -> onRotationUpdate(rotationParam),
-                    foldParam -> onFoldUpdate(foldParam));
+                    rotation -> onRotationUpdate(rotation),
+                    foldState -> onFoldStateUpdate(foldState));
         }
 
         intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
@@ -1463,16 +1463,20 @@
 
     //-----------------------------------------------------------------
     // rotation/fold updates coming from RotationHelper
-    void onRotationUpdate(String rotationParameter) {
+    void onRotationUpdate(Integer rotation) {
+        mSpatializerHelper.setDisplayOrientation((float) (rotation * Math.PI / 180.));
         // use REPLACE as only the last rotation matters
+        final String rotationParameter = "rotation=" + rotation;
         sendMsg(mAudioHandler, MSG_ROTATION_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
                 /*obj*/ rotationParameter, /*delay*/ 0);
     }
 
-    void onFoldUpdate(String foldParameter) {
+    void onFoldStateUpdate(Boolean foldState) {
+        mSpatializerHelper.setFoldState(foldState);
         // use REPLACE as only the last fold state matters
+        final String foldStateParameter = "device_folded=" + (foldState ? "on" : "off");
         sendMsg(mAudioHandler, MSG_FOLD_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
-                /*obj*/ foldParameter, /*delay*/ 0);
+                /*obj*/ foldStateParameter, /*delay*/ 0);
     }
 
     //-----------------------------------------------------------------
@@ -1687,6 +1691,11 @@
 
         mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect);
 
+        // Restore rotation information.
+        if (mMonitorRotation) {
+            RotationHelper.forceUpdate();
+        }
+
         onIndicateSystemReady();
         // indicate the end of reconfiguration phase to audio HAL
         AudioSystem.setParameters("restarting=false");
diff --git a/services/core/java/com/android/server/audio/RotationHelper.java b/services/core/java/com/android/server/audio/RotationHelper.java
index 5cdf58b..394e4af 100644
--- a/services/core/java/com/android/server/audio/RotationHelper.java
+++ b/services/core/java/com/android/server/audio/RotationHelper.java
@@ -55,14 +55,14 @@
     private static AudioDisplayListener sDisplayListener;
     private static FoldStateListener sFoldStateListener;
     /** callback to send rotation updates to AudioSystem */
-    private static Consumer<String> sRotationUpdateCb;
+    private static Consumer<Integer> sRotationCallback;
     /** callback to send folded state updates to AudioSystem */
-    private static Consumer<String> sFoldUpdateCb;
+    private static Consumer<Boolean> sFoldStateCallback;
 
     private static final Object sRotationLock = new Object();
     private static final Object sFoldStateLock = new Object();
-    private static int sDeviceRotation = Surface.ROTATION_0; // R/W synchronized on sRotationLock
-    private static boolean sDeviceFold = true; // R/W synchronized on sFoldStateLock
+    private static Integer sRotation = null; // R/W synchronized on sRotationLock
+    private static Boolean sFoldState = null; // R/W synchronized on sFoldStateLock
 
     private static Context sContext;
     private static Handler sHandler;
@@ -73,15 +73,15 @@
      * - sContext != null
      */
     static void init(Context context, Handler handler,
-            Consumer<String> rotationUpdateCb, Consumer<String> foldUpdateCb) {
+            Consumer<Integer> rotationCallback, Consumer<Boolean> foldStateCallback) {
         if (context == null) {
             throw new IllegalArgumentException("Invalid null context");
         }
         sContext = context;
         sHandler = handler;
         sDisplayListener = new AudioDisplayListener();
-        sRotationUpdateCb = rotationUpdateCb;
-        sFoldUpdateCb = foldUpdateCb;
+        sRotationCallback = rotationCallback;
+        sFoldStateCallback = foldStateCallback;
         enable();
     }
 
@@ -112,9 +112,9 @@
         int newRotation = DisplayManagerGlobal.getInstance()
                 .getDisplayInfo(Display.DEFAULT_DISPLAY).rotation;
         synchronized(sRotationLock) {
-            if (newRotation != sDeviceRotation) {
-                sDeviceRotation = newRotation;
-                publishRotation(sDeviceRotation);
+            if (sRotation == null || sRotation != newRotation) {
+                sRotation = newRotation;
+                publishRotation(sRotation);
             }
         }
     }
@@ -123,43 +123,52 @@
         if (DEBUG_ROTATION) {
             Log.i(TAG, "publishing device rotation =" + rotation + " (x90deg)");
         }
-        String rotationParam;
+        int rotationDegrees;
         switch (rotation) {
             case Surface.ROTATION_0:
-                rotationParam = "rotation=0";
+                rotationDegrees = 0;
                 break;
             case Surface.ROTATION_90:
-                rotationParam = "rotation=90";
+                rotationDegrees = 90;
                 break;
             case Surface.ROTATION_180:
-                rotationParam = "rotation=180";
+                rotationDegrees = 180;
                 break;
             case Surface.ROTATION_270:
-                rotationParam = "rotation=270";
+                rotationDegrees = 270;
                 break;
             default:
                 Log.e(TAG, "Unknown device rotation");
-                rotationParam = null;
+                rotationDegrees = -1;
         }
-        if (rotationParam != null) {
-            sRotationUpdateCb.accept(rotationParam);
+        if (rotationDegrees != -1) {
+            sRotationCallback.accept(rotationDegrees);
         }
     }
 
     /**
      * publish the change of device folded state if any.
      */
-    static void updateFoldState(boolean newFolded) {
+    static void updateFoldState(boolean foldState) {
         synchronized (sFoldStateLock) {
-            if (sDeviceFold != newFolded) {
-                sDeviceFold = newFolded;
-                String foldParam;
-                if (newFolded) {
-                    foldParam = "device_folded=on";
-                } else {
-                    foldParam = "device_folded=off";
-                }
-                sFoldUpdateCb.accept(foldParam);
+            if (sFoldState == null || sFoldState != foldState) {
+                sFoldState = foldState;
+                sFoldStateCallback.accept(foldState);
+            }
+        }
+    }
+
+    /**
+     *  forceUpdate is called when audioserver restarts.
+     */
+    static void forceUpdate() {
+        synchronized (sRotationLock) {
+            sRotation = null;
+        }
+        updateOrientation(); // We will get at least one orientation update now.
+        synchronized (sFoldStateLock) {
+            if (sFoldState  != null) {
+                sFoldStateCallback.accept(sFoldState);
             }
         }
     }
@@ -185,4 +194,4 @@
             updateOrientation();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 8e8fd05..2b56666 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -1063,7 +1063,7 @@
         if (transform.length != 6) {
             throw new IllegalArgumentException("invalid array size" + transform.length);
         }
-        if (!checkSpatForHeadTracking("setGlobalTransform")) {
+        if (!checkSpatializerForHeadTracking("setGlobalTransform")) {
             return;
         }
         try {
@@ -1074,7 +1074,7 @@
     }
 
     synchronized void recenterHeadTracker() {
-        if (!checkSpatForHeadTracking("recenterHeadTracker")) {
+        if (!checkSpatializerForHeadTracking("recenterHeadTracker")) {
             return;
         }
         try {
@@ -1084,8 +1084,30 @@
         }
     }
 
+    synchronized void setDisplayOrientation(float displayOrientation) {
+        if (!checkSpatializer("setDisplayOrientation")) {
+            return;
+        }
+        try {
+            mSpat.setDisplayOrientation(displayOrientation);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling setDisplayOrientation", e);
+        }
+    }
+
+    synchronized void setFoldState(boolean folded) {
+        if (!checkSpatializer("setFoldState")) {
+            return;
+        }
+        try {
+            mSpat.setFoldState(folded);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling setFoldState", e);
+        }
+    }
+
     synchronized void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) {
-        if (!checkSpatForHeadTracking("setDesiredHeadTrackingMode")) {
+        if (!checkSpatializerForHeadTracking("setDesiredHeadTrackingMode")) {
             return;
         }
         if (mode != Spatializer.HEAD_TRACKING_MODE_DISABLED) {
@@ -1178,7 +1200,7 @@
         return mHeadTrackerAvailable;
     }
 
-    private boolean checkSpatForHeadTracking(String funcName) {
+    private boolean checkSpatializer(String funcName) {
         switch (mState) {
             case STATE_UNINITIALIZED:
             case STATE_NOT_SUPPORTED:
@@ -1189,14 +1211,18 @@
             case STATE_ENABLED_AVAILABLE:
                 if (mSpat == null) {
                     // try to recover by resetting the native spatializer state
-                    Log.e(TAG, "checkSpatForHeadTracking(): "
-                            + "native spatializer should not be null in state: " + mState);
+                    Log.e(TAG, "checkSpatializer(): called from " + funcName
+                            + "(), native spatializer should not be null in state: " + mState);
                     postReset();
                     return false;
                 }
                 break;
         }
-        return mIsHeadTrackingSupported;
+        return true;
+    }
+
+    private boolean checkSpatializerForHeadTracking(String funcName) {
+        return checkSpatializer(funcName) && mIsHeadTrackingSupported;
     }
 
     private void dispatchActualHeadTrackingMode(int newMode) {
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 6d3f8fd..1e9352d1 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -31,6 +31,7 @@
 import static android.os.PowerWhitelistManager.REASON_VPN;
 import static android.os.UserHandle.PER_USER_RANGE;
 import static android.telephony.CarrierConfigManager.KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT;
+import static android.telephony.CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT;
 
 import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
 import static com.android.server.vcn.util.PersistableBundleUtils.STRING_DESERIALIZER;
@@ -269,6 +270,42 @@
     @VisibleForTesting
     static final int DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT = 5 * 60;
 
+    /**
+     *  Prefer using {@link IkeSessionParams.ESP_IP_VERSION_AUTO} and
+     *  {@link IkeSessionParams.ESP_ENCAP_TYPE_AUTO} for ESP packets.
+     *
+     *  This is one of the possible customization values for
+     *  CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT.
+     */
+    @VisibleForTesting
+    public static final int PREFERRED_IKE_PROTOCOL_AUTO = 0;
+    /**
+     *  Prefer using {@link IkeSessionParams.ESP_IP_VERSION_IPV4} and
+     *  {@link IkeSessionParams.ESP_ENCAP_TYPE_UDP} for ESP packets.
+     *
+     *  This is one of the possible customization values for
+     *  CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT.
+     */
+    @VisibleForTesting
+    public static final int PREFERRED_IKE_PROTOCOL_IPV4_UDP = 40;
+    /**
+     *  Prefer using {@link IkeSessionParams.ESP_IP_VERSION_IPV6} and
+     *  {@link IkeSessionParams.ESP_ENCAP_TYPE_UDP} for ESP packets.
+     *
+     *  Do not use this value for production code. Its numeric value will change in future versions.
+     */
+    @VisibleForTesting
+    public static final int PREFERRED_IKE_PROTOCOL_IPV6_UDP = 60;
+    /**
+     *  Prefer using {@link IkeSessionParams.ESP_IP_VERSION_IPV6} and
+     *  {@link IkeSessionParams.ESP_ENCAP_TYPE_NONE} for ESP packets.
+     *
+     *  This is one of the possible customization values for
+     *  CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT.
+     */
+    @VisibleForTesting
+    public static final int PREFERRED_IKE_PROTOCOL_IPV6_ESP = 61;
+
     // TODO: create separate trackers for each unique VPN to support
     // automated reconnection
 
@@ -326,12 +363,13 @@
     private final LocalLog mVpnManagerEvents = new LocalLog(MAX_EVENTS_LOGS);
 
     /**
-     * Cached Map of <subscription ID, keepalive delay ms> since retrieving the PersistableBundle
+     * Cached Map of <subscription ID, CarrierConfigInfo> since retrieving the PersistableBundle
      * and the target value from CarrierConfigManager is somewhat expensive as it has hundreds of
      * fields. This cache is cleared when the carrier config changes to ensure data freshness.
      */
     @GuardedBy("this")
-    private final SparseArray<Integer> mCachedKeepalivePerSubId = new SparseArray<>();
+    private final SparseArray<CarrierConfigInfo> mCachedCarrierConfigInfoPerSubId =
+            new SparseArray<>();
 
     /**
      * Whether to keep the connection active after rebooting, or upgrading or reinstalling. This
@@ -378,6 +416,28 @@
         void checkInterruptAndDelay(boolean sleepLonger) throws InterruptedException;
     }
 
+    private static class CarrierConfigInfo {
+        public final String mccMnc;
+        public final int keepaliveDelayMs;
+        public final int encapType;
+        public final int ipVersion;
+
+        CarrierConfigInfo(String mccMnc, int keepaliveDelayMs,
+                int encapType,
+                int ipVersion) {
+            this.mccMnc = mccMnc;
+            this.keepaliveDelayMs = keepaliveDelayMs;
+            this.encapType = encapType;
+            this.ipVersion = ipVersion;
+        }
+
+        @Override
+        public String toString() {
+            return "CarrierConfigInfo(" + mccMnc + ") [keepaliveDelayMs=" + keepaliveDelayMs
+                    + ", encapType=" + encapType + ", ipVersion=" + ipVersion + "]";
+        }
+    }
+
     @VisibleForTesting
     public static class Dependencies {
         public boolean isCallerSystem() {
@@ -2923,7 +2983,7 @@
                     public void onCarrierConfigChanged(int slotIndex, int subId, int carrierId,
                             int specificCarrierId) {
                         synchronized (Vpn.this) {
-                            mCachedKeepalivePerSubId.remove(subId);
+                            mCachedCarrierConfigInfoPerSubId.remove(subId);
 
                             // Ignore stale runner.
                             if (mVpnRunner != Vpn.IkeV2VpnRunner.this) return;
@@ -3388,47 +3448,105 @@
         }
 
         private int guessEspIpVersionForNetwork() {
-            // TODO : guess the IP version based on carrier if auto IP version selection is enabled
-            return ESP_IP_VERSION_AUTO;
+            final CarrierConfigInfo carrierconfig = getCarrierConfig();
+            final int ipVersion = (carrierconfig != null)
+                    ? carrierconfig.ipVersion : ESP_IP_VERSION_AUTO;
+            if (carrierconfig != null) {
+                Log.d(TAG, "Get customized IP version(" + ipVersion + ") on SIM("
+                        + carrierconfig.mccMnc + ")");
+            }
+            return ipVersion;
         }
 
         private int guessEspEncapTypeForNetwork() {
-            // TODO : guess the ESP encap type based on carrier if auto IP version selection is
-            // enabled
-            return ESP_ENCAP_TYPE_AUTO;
+            final CarrierConfigInfo carrierconfig = getCarrierConfig();
+            final int encapType = (carrierconfig != null)
+                    ? carrierconfig.encapType : ESP_ENCAP_TYPE_AUTO;
+            if (carrierconfig != null) {
+                Log.d(TAG, "Get customized encap type(" + encapType + ") on SIM("
+                        + carrierconfig.mccMnc + ")");
+            }
+            return encapType;
         }
 
         private int guessNattKeepaliveTimerForNetwork() {
+            final CarrierConfigInfo carrierconfig = getCarrierConfig();
+            final int natKeepalive = (carrierconfig != null)
+                    ? carrierconfig.keepaliveDelayMs : AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
+            if (carrierconfig != null) {
+                Log.d(TAG, "Get customized keepalive(" + natKeepalive + ") on SIM("
+                        + carrierconfig.mccMnc + ")");
+            }
+            return natKeepalive;
+        }
+
+        private CarrierConfigInfo getCarrierConfig() {
             final int subId = getCellSubIdForNetworkCapabilities(mUnderlyingNetworkCapabilities);
             if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
                 Log.d(TAG, "Underlying network is not a cellular network");
-                return AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
+                return null;
             }
 
             synchronized (Vpn.this) {
-                if (mCachedKeepalivePerSubId.contains(subId)) {
-                    Log.d(TAG, "Get cached keepalive config");
-                    return mCachedKeepalivePerSubId.get(subId);
+                if (mCachedCarrierConfigInfoPerSubId.contains(subId)) {
+                    Log.d(TAG, "Get cached config");
+                    return mCachedCarrierConfigInfoPerSubId.get(subId);
                 }
-
-                final TelephonyManager perSubTm = mTelephonyManager.createForSubscriptionId(subId);
-                if (perSubTm.getSimApplicationState() != TelephonyManager.SIM_STATE_LOADED) {
-                    Log.d(TAG, "SIM card is not ready on sub " + subId);
-                    return AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
-                }
-
-                final PersistableBundle carrierConfig =
-                        mCarrierConfigManager.getConfigForSubId(subId);
-                if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
-                    return AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
-                }
-
-                final int natKeepalive =
-                        carrierConfig.getInt(KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT);
-                mCachedKeepalivePerSubId.put(subId, natKeepalive);
-                Log.d(TAG, "Get customized keepalive=" + natKeepalive);
-                return natKeepalive;
             }
+
+            final TelephonyManager perSubTm = mTelephonyManager.createForSubscriptionId(subId);
+            if (perSubTm.getSimApplicationState() != TelephonyManager.SIM_STATE_LOADED) {
+                Log.d(TAG, "SIM card is not ready on sub " + subId);
+                return null;
+            }
+
+            final PersistableBundle carrierConfig =
+                    mCarrierConfigManager.getConfigForSubId(subId);
+            if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
+                return null;
+            }
+
+            final int natKeepalive =
+                    carrierConfig.getInt(KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT);
+            final int preferredIpPortocol =
+                    carrierConfig.getInt(KEY_PREFERRED_IKE_PROTOCOL_INT);
+            final String mccMnc = perSubTm.getSimOperator(subId);
+            final CarrierConfigInfo info =
+                    buildCarrierConfigInfo(mccMnc, natKeepalive, preferredIpPortocol);
+            synchronized (Vpn.this) {
+                mCachedCarrierConfigInfoPerSubId.put(subId, info);
+            }
+
+            return info;
+        }
+
+        private CarrierConfigInfo buildCarrierConfigInfo(String mccMnc,
+                int natKeepalive, int preferredIpPortocol) {
+            final int ipVersion;
+            final int encapType;
+            switch (preferredIpPortocol) {
+                case PREFERRED_IKE_PROTOCOL_AUTO:
+                    ipVersion = IkeSessionParams.ESP_IP_VERSION_AUTO;
+                    encapType = IkeSessionParams.ESP_ENCAP_TYPE_AUTO;
+                    break;
+                case PREFERRED_IKE_PROTOCOL_IPV4_UDP:
+                    ipVersion = IkeSessionParams.ESP_IP_VERSION_IPV4;
+                    encapType = IkeSessionParams.ESP_ENCAP_TYPE_UDP;
+                    break;
+                case PREFERRED_IKE_PROTOCOL_IPV6_UDP:
+                    ipVersion = IkeSessionParams.ESP_IP_VERSION_IPV6;
+                    encapType = IkeSessionParams.ESP_ENCAP_TYPE_UDP;
+                    break;
+                case PREFERRED_IKE_PROTOCOL_IPV6_ESP:
+                    ipVersion = IkeSessionParams.ESP_IP_VERSION_IPV6;
+                    encapType = IkeSessionParams.ESP_ENCAP_TYPE_NONE;
+                    break;
+                default:
+                    ipVersion = IkeSessionParams.ESP_IP_VERSION_AUTO;
+                    encapType = IkeSessionParams.ESP_ENCAP_TYPE_AUTO;
+                    break;
+            }
+            return new CarrierConfigInfo(mccMnc, natKeepalive, encapType, ipVersion);
         }
 
         boolean maybeMigrateIkeSession(@NonNull Network underlyingNetwork) {
@@ -3440,10 +3558,22 @@
                     + mCurrentToken
                     + " to network "
                     + underlyingNetwork);
-            final int ipVersion = mProfile.isAutomaticIpVersionSelectionEnabled()
-                    ? guessEspIpVersionForNetwork() : ESP_IP_VERSION_AUTO;
-            final int encapType = mProfile.isAutomaticIpVersionSelectionEnabled()
-                    ? guessEspEncapTypeForNetwork() : ESP_ENCAP_TYPE_AUTO;
+
+            final int ipVersion;
+            final int encapType;
+            if (mProfile.isAutomaticIpVersionSelectionEnabled()) {
+                ipVersion = guessEspIpVersionForNetwork();
+                encapType = guessEspEncapTypeForNetwork();
+            } else if (mProfile.getIkeTunnelConnectionParams() != null) {
+                ipVersion = mProfile.getIkeTunnelConnectionParams()
+                        .getIkeSessionParams().getIpVersion();
+                encapType = mProfile.getIkeTunnelConnectionParams()
+                        .getIkeSessionParams().getEncapType();
+            } else {
+                ipVersion = ESP_IP_VERSION_AUTO;
+                encapType = ESP_ENCAP_TYPE_AUTO;
+            }
+
             final int keepaliveDelaySeconds;
             if (mProfile.isAutomaticNattKeepaliveTimerEnabled()) {
                 keepaliveDelaySeconds = guessNattKeepaliveTimerForNetwork();
@@ -4884,7 +5014,7 @@
                     pw.println("Reset session scheduled");
                 }
             }
-            pw.println("mCachedKeepalivePerSubId=" + mCachedKeepalivePerSubId);
+            pw.println("mCachedCarrierConfigInfoPerSubId=" + mCachedCarrierConfigInfoPerSubId);
 
             pw.println("mUnderlyNetworkChanges (most recent first):");
             pw.increaseIndent();
diff --git a/services/core/java/com/android/server/policy/GlobalActions.java b/services/core/java/com/android/server/policy/GlobalActions.java
index e146135..76a714c 100644
--- a/services/core/java/com/android/server/policy/GlobalActions.java
+++ b/services/core/java/com/android/server/policy/GlobalActions.java
@@ -93,7 +93,8 @@
         mGlobalActionsAvailable = available;
         if (mShowing && !mGlobalActionsAvailable) {
             // Global actions provider died but we need to be showing global actions still, show the
-            // legacy global acrions provider.
+            // legacy global actions provider and remove timeout callbacks to avoid legacy re-show.
+            mHandler.removeCallbacks(mShowTimeout);
             ensureLegacyCreated();
             mLegacyGlobalActions.showDialog(mKeyguardShowing, mDeviceProvisioned);
         }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 75d84ea..bb2a2cf 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1183,7 +1183,8 @@
     private void finishHoldScreenUpdate() {
         final boolean hold = mTmpHoldScreenWindow != null;
         if (hold && mTmpHoldScreenWindow != mHoldScreenWindow) {
-            mHoldScreenWakeLock.setWorkSource(new WorkSource(mTmpHoldScreenWindow.mSession.mUid));
+            mHoldScreenWakeLock.setWorkSource(new WorkSource(mTmpHoldScreenWindow.mSession.mUid,
+                    mTmpHoldScreenWindow.mSession.mPackageName));
         }
         mHoldScreenWindow = mTmpHoldScreenWindow;
         mTmpHoldScreenWindow = null;
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index b9739f03..b64122d 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -115,7 +115,7 @@
     private boolean mShowingAlertWindowNotificationAllowed;
     private boolean mClientDead = false;
     private float mLastReportedAnimatorScale;
-    private String mPackageName;
+    protected String mPackageName;
     private String mRelayoutTag;
     private final InsetsVisibilities mDummyRequestedVisibilities = new InsetsVisibilities();
     private final InsetsSourceControl[] mDummyControls =  new InsetsSourceControl[0];
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 36362f7..f570f87 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -4334,6 +4334,22 @@
             "min_udp_port_4500_nat_timeout_sec_int";
 
     /**
+     * The preferred IKE protocol for ESP packets.
+     *
+     * This will be used by Android platform VPNs to select preferred encapsulation type and IP
+     * protocol type. The possible customization values are:
+     *
+     * AUTO IP VERSION and ENCAPSULATION TYPE SELECTION : "0"
+     * IPv4 UDP                                         : "40"
+     * IPv6 ESP                                         : "61"
+     *
+     * See the {@code PREFERRED_IKE_PROTOCOL_} constants in
+     * {@link com.android.server.connectivity.Vpn}.
+     * @hide
+     */
+    public static final String KEY_PREFERRED_IKE_PROTOCOL_INT = "preferred_ike_protocol_int";
+
+    /**
      * Specifies whether the system should prefix the EAP method to the anonymous identity.
      * The following prefix will be added if this key is set to TRUE:
      *   EAP-AKA: "0"
@@ -9256,6 +9272,7 @@
         sDefaults.putInt(KEY_PARAMETERS_USED_FOR_LTE_SIGNAL_BAR_INT,
                 CellSignalStrengthLte.USE_RSRP);
         sDefaults.putInt(KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT, 300);
+        sDefaults.putInt(KEY_PREFERRED_IKE_PROTOCOL_INT, 0);
         // Default wifi configurations.
         sDefaults.putAll(Wifi.getDefaults());
         sDefaults.putBoolean(ENABLE_EAP_METHOD_PREFIX_BOOL, false);