Merge "Update jank reasons in timestats" into sc-dev
diff --git a/Android.bp b/Android.bp
index 9829c7f..298c01a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,3 +1,41 @@
+package {
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+//
+// large-scale-change filtered out the below license kinds as false-positives:
+//   SPDX-license-identifier-LGPL
+//   SPDX-license-identifier-LGPL-2.1
+//   SPDX-license-identifier-LGPL-3.0
+// See: http://go/android-license-faq
+license {
+    name: "frameworks_native_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+        "SPDX-license-identifier-BSD",
+        "SPDX-license-identifier-MIT",
+        "SPDX-license-identifier-Unicode-DFS",
+        "legacy_notice",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 ndk_headers {
     name: "libandroid_headers",
     from: "include/android",
@@ -43,3 +81,8 @@
         ":framework_native_aidl_gui",
     ],
 }
+
+cc_library_headers{
+    name: "libandroid_headers_private",
+    export_include_dirs: ["include/private"],
+}
\ No newline at end of file
diff --git a/cmds/atrace/Android.bp b/cmds/atrace/Android.bp
index e7d0ad0..aa0ef25 100644
--- a/cmds/atrace/Android.bp
+++ b/cmds/atrace/Android.bp
@@ -1,5 +1,22 @@
 // Copyright 2012 The Android Open Source Project
 
+package {
+    default_applicable_licenses: ["frameworks_native_cmds_atrace_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "frameworks_native_cmds_atrace_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 cc_binary {
     name: "atrace",
     srcs: ["atrace.cpp"],
diff --git a/cmds/bugreport/Android.bp b/cmds/bugreport/Android.bp
index 24044a6..8262aed 100644
--- a/cmds/bugreport/Android.bp
+++ b/cmds/bugreport/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_binary {
     name: "bugreport",
     srcs: ["bugreport.cpp"],
diff --git a/cmds/bugreportz/Android.bp b/cmds/bugreportz/Android.bp
index 924a3a3..332f858 100644
--- a/cmds/bugreportz/Android.bp
+++ b/cmds/bugreportz/Android.bp
@@ -1,5 +1,14 @@
 // bugreportz
 // ==========
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_binary {
     name: "bugreportz",
 
diff --git a/cmds/cmd/Android.bp b/cmds/cmd/Android.bp
index 8ea71cd..c900a24 100644
--- a/cmds/cmd/Android.bp
+++ b/cmds/cmd/Android.bp
@@ -1,3 +1,20 @@
+package {
+    default_applicable_licenses: ["frameworks_native_cmds_cmd_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "frameworks_native_cmds_cmd_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 cc_library_static {
     name: "libcmd",
 
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index 34e9a85..f48f1fb 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -13,6 +13,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
     name: "dumpstate_cflag_defaults",
     cflags: [
diff --git a/cmds/dumpsys/Android.bp b/cmds/dumpsys/Android.bp
index f99588f..91aa018 100644
--- a/cmds/dumpsys/Android.bp
+++ b/cmds/dumpsys/Android.bp
@@ -1,3 +1,20 @@
+package {
+    default_applicable_licenses: ["frameworks_native_cmds_dumpsys_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "frameworks_native_cmds_dumpsys_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 cc_defaults {
     name: "dumpsys_defaults",
 
diff --git a/cmds/dumpsys/tests/Android.bp b/cmds/dumpsys/tests/Android.bp
index e182b9d..6854c75 100644
--- a/cmds/dumpsys/tests/Android.bp
+++ b/cmds/dumpsys/tests/Android.bp
@@ -1,4 +1,13 @@
 // Build the unit tests for dumpsys
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_cmds_dumpsys_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_cmds_dumpsys_license"],
+}
+
 cc_test {
     name: "dumpsys_test",
     test_suites: ["device-tests"],
diff --git a/cmds/flatland/Android.mk b/cmds/flatland/Android.mk
index 7aa111c..754a99c 100644
--- a/cmds/flatland/Android.mk
+++ b/cmds/flatland/Android.mk
@@ -11,6 +11,9 @@
 LOCAL_CFLAGS := -Wall -Werror
 
 LOCAL_MODULE:= flatland
+LOCAL_LICENSE_KINDS:= SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS:= notice
+LOCAL_NOTICE_FILE:= $(LOCAL_PATH)/../../NOTICE
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/cmds/idlcli/Android.bp b/cmds/idlcli/Android.bp
index 72ffc94..c537fed 100644
--- a/cmds/idlcli/Android.bp
+++ b/cmds/idlcli/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
     name: "idlcli-defaults",
     shared_libs: [
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index cbe857a..5c2211f 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
     name: "installd_defaults",
 
diff --git a/cmds/installd/tests/Android.bp b/cmds/installd/tests/Android.bp
index 7c9e3b2..f67ab81 100644
--- a/cmds/installd/tests/Android.bp
+++ b/cmds/installd/tests/Android.bp
@@ -1,4 +1,13 @@
 // Build the unit tests for installd
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "installd_utils_test",
     test_suites: ["device-tests"],
@@ -157,4 +166,3 @@
         "libotapreoptparameters"
     ],
 }
-
diff --git a/cmds/ip-up-vpn/Android.mk b/cmds/ip-up-vpn/Android.mk
index e1e2204..396ae9d 100644
--- a/cmds/ip-up-vpn/Android.mk
+++ b/cmds/ip-up-vpn/Android.mk
@@ -21,6 +21,9 @@
 LOCAL_CFLAGS := -Wall -Werror
 LOCAL_SHARED_LIBRARIES := libcutils liblog
 LOCAL_MODULE := ip-up-vpn
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE
 LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/ppp
 LOCAL_MODULE_TAGS := optional
 
diff --git a/cmds/lshal/Android.bp b/cmds/lshal/Android.bp
index 0cbb80f..649e53a 100644
--- a/cmds/lshal/Android.bp
+++ b/cmds/lshal/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_static {
     name: "liblshal",
     shared_libs: [
diff --git a/cmds/lshal/libprocpartition/Android.bp b/cmds/lshal/libprocpartition/Android.bp
index 9592111..cbfbdc9 100644
--- a/cmds/lshal/libprocpartition/Android.bp
+++ b/cmds/lshal/libprocpartition/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_static {
     name: "libprocpartition",
     shared_libs: [
diff --git a/cmds/rawbu/Android.bp b/cmds/rawbu/Android.bp
index 363ffc1..e34119d 100644
--- a/cmds/rawbu/Android.bp
+++ b/cmds/rawbu/Android.bp
@@ -1,5 +1,22 @@
 // Copyright 2009 The Android Open Source Project
 
+package {
+    default_applicable_licenses: ["frameworks_native_cmds_rawbu_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "frameworks_native_cmds_rawbu_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 cc_binary {
     name: "rawbu",
 
diff --git a/cmds/rss_hwm_reset/Android.bp b/cmds/rss_hwm_reset/Android.bp
index 15f10ef..cd335d4 100644
--- a/cmds/rss_hwm_reset/Android.bp
+++ b/cmds/rss_hwm_reset/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_binary {
     name: "rss_hwm_reset",
 
diff --git a/cmds/service/Android.bp b/cmds/service/Android.bp
index a5b1ac5..3e8e3f6 100644
--- a/cmds/service/Android.bp
+++ b/cmds/service/Android.bp
@@ -1,3 +1,20 @@
+package {
+    default_applicable_licenses: ["frameworks_native_cmds_service_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "frameworks_native_cmds_service_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 cc_binary {
     name: "service",
 
diff --git a/cmds/servicemanager/Android.bp b/cmds/servicemanager/Android.bp
index b139251..9de344a 100644
--- a/cmds/servicemanager/Android.bp
+++ b/cmds/servicemanager/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
     name: "servicemanager_defaults",
 
diff --git a/cmds/surfacereplayer/Android.bp b/cmds/surfacereplayer/Android.bp
index d4c037a..34fc8b1 100644
--- a/cmds/surfacereplayer/Android.bp
+++ b/cmds/surfacereplayer/Android.bp
@@ -1,4 +1,13 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 subdirs = [
     "proto",
     "replayer",
-]
\ No newline at end of file
+]
diff --git a/cmds/surfacereplayer/proto/Android.bp b/cmds/surfacereplayer/proto/Android.bp
index 71a5e23..dae976e 100644
--- a/cmds/surfacereplayer/proto/Android.bp
+++ b/cmds/surfacereplayer/proto/Android.bp
@@ -1,3 +1,14 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_static {
     name: "libtrace_proto",
     srcs: [
diff --git a/cmds/surfacereplayer/replayer/Android.bp b/cmds/surfacereplayer/replayer/Android.bp
index 7632311..3985230 100644
--- a/cmds/surfacereplayer/replayer/Android.bp
+++ b/cmds/surfacereplayer/replayer/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libsurfacereplayer",
     srcs: [
diff --git a/data/etc/android.hardware.keystore.app_attest_key.xml b/data/etc/android.hardware.keystore.app_attest_key.xml
new file mode 100644
index 0000000..8adc439
--- /dev/null
+++ b/data/etc/android.hardware.keystore.app_attest_key.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="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.
+-->
+
+<!-- Feature for devices that support app attestation keys (i.e. KeyMint 1.0). -->
+<permissions>
+    <feature name="android.hardware.keystore.app_attest_key" />
+</permissions>
diff --git a/headers/Android.bp b/headers/Android.bp
index 8f41c2b..7481a23 100644
--- a/headers/Android.bp
+++ b/headers/Android.bp
@@ -1,3 +1,13 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_headers {
     name: "media_plugin_headers",
     vendor_available: true,
diff --git a/include/android/permission_manager.h b/include/android/permission_manager.h
index 2d5d060..753b6d1 100644
--- a/include/android/permission_manager.h
+++ b/include/android/permission_manager.h
@@ -14,6 +14,17 @@
  * limitations under the License.
  */
 
+/**
+ * Structures and functions related to permission checks in native code.
+ *
+ * @addtogroup Permission
+ * @{
+ */
+
+/**
+ * @file permission_manager.h
+ */
+
 #ifndef ANDROID_PERMISSION_MANAGER_H
 #define ANDROID_PERMISSION_MANAGER_H
 
@@ -48,8 +59,8 @@
 enum {
     /**
      * This is returned if the permission check completed without errors.
-     * The output result is valid and contains one of {PERMISSION_MANAGER_PERMISSION_GRANTED,
-     * PERMISSION_MANAGER_PERMISSION_DENIED}.
+     * The output result is valid and contains one of {::PERMISSION_MANAGER_PERMISSION_GRANTED,
+     * ::PERMISSION_MANAGER_PERMISSION_DENIED}.
      */
     PERMISSION_MANAGER_STATUS_OK = 0,
     /**
@@ -85,3 +96,5 @@
 __END_DECLS
 
 #endif  // ANDROID_PERMISSION_MANAGER_H
+
+/** @} */
diff --git a/include/android/surface_control.h b/include/android/surface_control.h
index 98fd875..b836581 100644
--- a/include/android/surface_control.h
+++ b/include/android/surface_control.h
@@ -67,9 +67,21 @@
                                         __INTRODUCED_IN(29);
 
 /**
- * Releases the \a surface_control object. After releasing the ASurfaceControl the caller no longer
- * has ownership of the AsurfaceControl. The surface and it's children may remain on display as long
- * as their parent remains on display.
+ * Acquires a reference on the given ASurfaceControl object.  This prevents the object
+ * from being deleted until the reference is removed.
+ *
+ * To release the reference, use the ASurfaceControl_release function.
+ *
+ * Available since API level 31.
+ */
+void ASurfaceControl_acquire(ASurfaceControl* surface_control) __INTRODUCED_IN(31);
+
+/**
+ * Removes a reference that was previously acquired with one of the following functions:
+ *   ASurfaceControl_createFromWindow
+ *   ASurfaceControl_create
+ *   ANativeWindow_acquire
+ * The surface and its children may remain on display as long as their parent remains on display.
  *
  * Available since API level 29.
  */
diff --git a/include/private/surface_control_private.h b/include/private/surface_control_private.h
new file mode 100644
index 0000000..37a476e
--- /dev/null
+++ b/include/private/surface_control_private.h
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_PRIVATE_NATIVE_SURFACE_CONTROL_H
+#define ANDROID_PRIVATE_NATIVE_SURFACE_CONTROL_H
+
+#include <stdint.h>
+
+__BEGIN_DECLS
+
+struct ASurfaceControl;
+struct ASurfaceControlStats;
+
+typedef struct ASurfaceControlStats ASurfaceControlStats;
+
+/**
+ * Callback to be notified when surface stats for a specific surface control are available.
+ */
+typedef void (*ASurfaceControl_SurfaceStatsListener)(void* context,
+        ASurfaceControl* control, ASurfaceControlStats* stats);
+
+/**
+ * Registers a callback to be invoked when surface stats from a specific surface are available.
+ *
+ * \param context Optional context provided by the client that is passed into
+ * the callback.
+ *
+ * \param control The surface to retrieve callbacks for.
+ *
+ * \param func The callback to be invoked when surface stats are available.
+ */
+void ASurfaceControl_registerSurfaceStatsListener(ASurfaceControl* control, void* context,
+        ASurfaceControl_SurfaceStatsListener func);
+
+/**
+ * Unregisters a callback to be invoked when surface stats from a specific surface are available.
+ *
+ * \param context The context passed into ASurfaceControl_registerSurfaceStatsListener
+ *
+ * \param func The callback passed into ASurfaceControl_registerSurfaceStatsListener
+ */
+void ASurfaceControl_unregisterSurfaceStatsListener(void* context,
+                                       ASurfaceControl_SurfaceStatsListener func);
+
+/**
+ * Returns the timestamp of when the buffer was acquired for a specific frame with frame number
+ * obtained from ASurfaceControlStats_getFrameNumber.
+ */
+int64_t ASurfaceControlStats_getAcquireTime(ASurfaceControlStats* stats);
+
+/**
+ * Returns the frame number of the surface stats object passed into the callback.
+ */
+uint64_t ASurfaceControlStats_getFrameNumber(ASurfaceControlStats* stats);
+
+__END_DECLS
+
+#endif //ANDROID_PRIVATE_NATIVE_SURFACE_CONTROL_H
diff --git a/libs/adbd_auth/Android.bp b/libs/adbd_auth/Android.bp
index 8883c04..16cded8 100644
--- a/libs/adbd_auth/Android.bp
+++ b/libs/adbd_auth/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library {
     name: "libadbd_auth",
     cflags: [
diff --git a/libs/android_runtime_lazy/Android.bp b/libs/android_runtime_lazy/Android.bp
index cdd7764..b74923c 100644
--- a/libs/android_runtime_lazy/Android.bp
+++ b/libs/android_runtime_lazy/Android.bp
@@ -30,6 +30,15 @@
 // instead of libandroid_runtime. When they are used by a vendor process,
 // depending on libandroid_runtime is meaningless. In this case,
 // they can depend on libandroid_runtime_lazy.
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library {
     name: "libandroid_runtime_lazy",
     vendor_available: true,
diff --git a/libs/arect/Android.bp b/libs/arect/Android.bp
index 80aa891..bb40f51 100644
--- a/libs/arect/Android.bp
+++ b/libs/arect/Android.bp
@@ -12,6 +12,23 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["frameworks_native_libs_arect_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "frameworks_native_libs_arect_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 ndk_headers {
     name: "libarect_headers_for_ndk",
     from: "include/android",
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index b585ad2..e9d866b 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_headers {
     name: "libbinder_headers",
     export_include_dirs: ["include"],
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index bf4387a..ddda024 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -228,8 +228,9 @@
                 : Stability::getLocalLevel();
 
             if (CC_UNLIKELY(!Stability::check(category, required))) {
-                ALOGE("Cannot do a user transaction on a %s binder in a %s context.",
+                ALOGE("Cannot do a user transaction on a %s binder (%s) in a %s context.",
                     category.debugString().c_str(),
+                    String8(getInterfaceDescriptor()).c_str(),
                     Stability::levelString(required).c_str());
                 return BAD_TYPE;
             }
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 1a4ede1..3773760 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -520,7 +520,7 @@
     }
 }
 
-#if defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID_VNDK__)
 constexpr int32_t kHeader = B_PACK_CHARS('V', 'N', 'D', 'R');
 #else
 constexpr int32_t kHeader = B_PACK_CHARS('S', 'Y', 'S', 'T');
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index c38249e..edadcd5 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -406,12 +406,6 @@
     , mThreadPoolSeq(1)
     , mCallRestriction(CallRestriction::NONE)
 {
-
-// TODO(b/166468760): enforce in build system
-#if defined(__ANDROID_APEX__)
-    LOG_ALWAYS_FATAL("Cannot use libbinder in APEX (only system.img libbinder) since it is not stable.");
-#endif
-
     if (mDriverFD >= 0) {
         // mmap the binder, providing a chunk of virtual address space to receive transactions.
         mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
diff --git a/libs/binder/Stability.cpp b/libs/binder/Stability.cpp
index 339c538..b56e09f 100644
--- a/libs/binder/Stability.cpp
+++ b/libs/binder/Stability.cpp
@@ -76,18 +76,12 @@
 }
 
 Stability::Level Stability::getLocalLevel() {
+#ifdef __ANDROID_APEX__
+#error APEX can't use libbinder (must use libbinder_ndk)
+#endif
+
 #ifdef __ANDROID_VNDK__
-    #ifdef __ANDROID_APEX__
-        // TODO(b/142684679) avoid use_vendor on system APEXes
-        #if !defined(__ANDROID_APEX_COM_ANDROID_MEDIA_SWCODEC__) \
-            && !defined(__ANDROID_APEX_TEST_COM_ANDROID_MEDIA_SWCODEC__)
-        #error VNDK + APEX only defined for com.android.media.swcodec
-        #endif
-        // TODO(b/142684679) avoid use_vendor on system APEXes
-        return Level::SYSTEM;
-    #else
-        return Level::VENDOR;
-    #endif
+    return Level::VENDOR;
 #else
     // TODO(b/139325195): split up stability levels for system/APEX.
     return Level::SYSTEM;
diff --git a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
index 889e15a..a7a6563 100644
--- a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
+++ b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
@@ -108,4 +108,10 @@
      * has been set to {@link PackageManager#CERT_INPUT_SHA256}.
      */
     boolean hasSha256SigningCertificate(in @utf8InCpp String packageName, in byte[] certificate);
+
+    /**
+     * Returns the debug flag for the given package.
+     * Unknown packages will cause the call to fail.
+     */
+     boolean isPackageDebuggable(in String packageName);
 }
diff --git a/libs/binder/include/private/binder/binder_module.h b/libs/binder/include/private/binder/binder_module.h
index 5a719b8..1579199 100644
--- a/libs/binder/include/private/binder/binder_module.h
+++ b/libs/binder/include/private/binder/binder_module.h
@@ -88,10 +88,6 @@
 };
 #endif //BINDER_GET_FROZEN_INFO
 
-enum transaction_flags_ext {
-    TF_CLEAR_BUF = 0x20, /* clear buffer on txn complete */
-};
-
 #ifdef __cplusplus
 }   // namespace android
 #endif
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index 897c72a..eb103d3 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -15,6 +15,23 @@
  */
 
 // TODO(b/31559095): bionic on host should define this
+package {
+    default_applicable_licenses: ["frameworks_native_libs_binder_ndk_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "frameworks_native_libs_binder_ndk_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 cc_defaults {
     name: "libbinder_ndk_host_user",
     target: {
diff --git a/libs/binder/ndk/include_cpp/android/binder_to_string.h b/libs/binder/ndk/include_cpp/android/binder_to_string.h
index bd51b11..5842925 100644
--- a/libs/binder/ndk/include_cpp/android/binder_to_string.h
+++ b/libs/binder/ndk/include_cpp/android/binder_to_string.h
@@ -28,10 +28,22 @@
 
 #include <codecvt>
 #include <locale>
+#include <memory>
+#include <optional>
 #include <sstream>
 #include <string>
 #include <type_traits>
 
+#if __has_include(<utils/StrongPointer.h>)
+#include <utils/StrongPointer.h>
+#define HAS_STRONG_POINTER
+#endif
+
+#if __has_include(<utils/String16.h>)
+#include <utils/String16.h>
+#define HAS_STRING16
+#endif
+
 #if __has_include(<android/binder_ibinder.h>)
 #include <android/binder_auto_utils.h>
 #include <android/binder_interface_utils.h>
@@ -42,9 +54,6 @@
 #include <binder/IInterface.h>
 #include <binder/ParcelFileDescriptor.h>
 #include <binder/ParcelableHolder.h>
-#include <utils/String16.h>
-#include <utils/StrongPointer.h>
-#define HAS_CPP_INTERFACE
 #endif  //_has_include
 
 namespace android {
@@ -80,11 +89,28 @@
     enum { value = decltype(_test<_T>(0))::value };
 };
 
-// Truthy if _T is like a pointer
+template <typename T, template <typename...> typename U>
+struct IsInstantiationOf : std::false_type {};
+
+template <template <typename...> typename U, typename... Args>
+struct IsInstantiationOf<U<Args...>, U> : std::true_type {};
+
+// Truthy if _T is like a pointer: one of sp/optional/shared_ptr
 template <typename _T>
 class IsPointerLike {
     template <typename _U>
-    static auto _test(int) -> decltype(!std::declval<_U>(), *std::declval<_U>(), std::true_type());
+    static std::enable_if_t<
+#ifdef HAS_STRONG_POINTER
+            IsInstantiationOf<_U, sp>::value ||  // for IBinder and interface types in the C++
+                                                 // backend
+#endif
+                    IsInstantiationOf<_U, std::optional>::value ||  // for @nullable types in the
+                                                                    // C++/NDK backends
+                    IsInstantiationOf<_U, std::shared_ptr>::value,  // for interface types in the
+                                                                    // NDK backends
+
+            std::true_type>
+    _test(int);
     template <typename _U>
     static std::false_type _test(...);
 
@@ -142,12 +168,17 @@
         return std::to_string(t);
     } else if constexpr (std::is_same_v<std::string, _T>) {
         return t;
-#ifdef HAS_CPP_INTERFACE
+#ifdef HAS_STRING16
     } else if constexpr (std::is_same_v<String16, _T>) {
         std::stringstream out;
         out << t;
         return out.str();
 #endif
+    } else if constexpr (details::IsPointerLike<_T>::value) {
+        if (!t) return "(null)";
+        std::stringstream out;
+        out << ToString(*t);
+        return out.str();
     } else if constexpr (details::HasToStringMethod<_T>::value) {
         return t.toString();
     } else if constexpr (details::HasToStringFunction<_T>::value) {
@@ -168,11 +199,6 @@
         }
         out << "]";
         return out.str();
-    } else if constexpr (details::IsPointerLike<_T>::value) {
-        if (!t) return "(null)";
-        std::stringstream out;
-        out << ToString(*t);
-        return out.str();
     } else {
         return "{no toString() implemented}";
     }
diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
index 2784aa8..4580751 100644
--- a/libs/binder/ndk/include_platform/android/binder_manager.h
+++ b/libs/binder/ndk/include_platform/android/binder_manager.h
@@ -31,7 +31,8 @@
  *
  * \return EX_NONE on success.
  */
-binder_exception_t AServiceManager_addService(AIBinder* binder, const char* instance);
+__attribute__((warn_unused_result)) binder_exception_t AServiceManager_addService(
+        AIBinder* binder, const char* instance);
 
 /**
  * Gets a binder object with this specific instance name. Will return nullptr immediately if the
@@ -94,4 +95,52 @@
  */
 bool AServiceManager_isDeclared(const char* instance) __INTRODUCED_IN(31);
 
+/**
+ * Prevent lazy services without client from shutting down their process
+ *
+ * \param persist 'true' if the process should not exit.
+ */
+void AServiceManager_forceLazyServicesPersist(bool persist) __INTRODUCED_IN(31);
+
+/**
+ * Set a callback that is invoked when the active service count (i.e. services with clients)
+ * registered with this process drops to zero (or becomes nonzero).
+ * The callback takes a boolean argument, which is 'true' if there is
+ * at least one service with clients.
+ *
+ * \param callback function to call when the number of services
+ *    with clients changes.
+ * \param context opaque pointer passed back as second parameter to the
+ * callback.
+ *
+ * The callback takes two arguments. The first is a boolean that represents if there are
+ * services with clients (true) or not (false).
+ * The second is the 'context' pointer passed during the registration.
+ *
+ * Callback return value:
+ * - false: Default behavior for lazy services (shut down the process if there
+ *          are no clients).
+ * - true:  Don't shut down the process even if there are no clients.
+ *
+ * This callback gives a chance to:
+ * 1 - Perform some additional operations before exiting;
+ * 2 - Prevent the process from exiting by returning "true" from the callback.
+ */
+void AServiceManager_setActiveServicesCallback(bool (*callback)(bool, void*), void* context)
+        __INTRODUCED_IN(31);
+
+/**
+ * Try to unregister all services previously registered with 'registerService'.
+ *
+ * \return true on success.
+ */
+bool AServiceManager_tryUnregister() __INTRODUCED_IN(31);
+
+/**
+ * Re-register services that were unregistered by 'tryUnregister'.
+ * This method should be called in the case 'tryUnregister' fails
+ * (and should be called on the same thread).
+ */
+void AServiceManager_reRegister() __INTRODUCED_IN(31);
+
 __END_DECLS
diff --git a/libs/binder/ndk/include_platform/android/binder_stability.h b/libs/binder/ndk/include_platform/android/binder_stability.h
index f5e8bf6..44ed48f 100644
--- a/libs/binder/ndk/include_platform/android/binder_stability.h
+++ b/libs/binder/ndk/include_platform/android/binder_stability.h
@@ -30,6 +30,8 @@
     FLAG_PRIVATE_VENDOR = 0x10000000,
 };
 
+// TODO(b/180646847): __ANDROID_APEX__ here is what allows product partition to
+// talk to system.
 #if defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
 
 enum {
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 9a93bf3..cef0bf3 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -120,6 +120,10 @@
     AServiceManager_isDeclared; # apex llndk
     AServiceManager_registerLazyService; # llndk
     AServiceManager_waitForService; # apex llndk
+    AServiceManager_forceLazyServicesPersist; # llndk
+    AServiceManager_setActiveServicesCallback; # llndk
+    AServiceManager_tryUnregister; # llndk
+    AServiceManager_reRegister; # llndk
 
     AIBinder_Class_getDescriptor;
     AIBinder_Weak_clone;
diff --git a/libs/binder/ndk/service_manager.cpp b/libs/binder/ndk/service_manager.cpp
index c782d47..cb0987e 100644
--- a/libs/binder/ndk/service_manager.cpp
+++ b/libs/binder/ndk/service_manager.cpp
@@ -92,3 +92,22 @@
     sp<IServiceManager> sm = defaultServiceManager();
     return sm->isDeclared(String16(instance));
 }
+void AServiceManager_forceLazyServicesPersist(bool persist) {
+    auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
+    serviceRegistrar.forcePersist(persist);
+}
+void AServiceManager_setActiveServicesCallback(bool (*callback)(bool, void*), void* context) {
+    auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
+    std::function<bool(bool)> fn = [=](bool hasClients) -> bool {
+        return callback(hasClients, context);
+    };
+    serviceRegistrar.setActiveServicesCallback(fn);
+}
+bool AServiceManager_tryUnregister() {
+    auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
+    return serviceRegistrar.tryUnregister();
+}
+void AServiceManager_reRegister() {
+    auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
+    serviceRegistrar.reRegister();
+}
\ No newline at end of file
diff --git a/libs/binder/ndk/tests/Android.bp b/libs/binder/ndk/tests/Android.bp
index 46e6270..bb51bf0 100644
--- a/libs/binder/ndk/tests/Android.bp
+++ b/libs/binder/ndk/tests/Android.bp
@@ -14,6 +14,15 @@
  * limitations under the License.
  */
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_libs_binder_ndk_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_libs_binder_ndk_license"],
+}
+
 cc_defaults {
     name: "test_libbinder_ndk_defaults",
     shared_libs: [
diff --git a/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
index dc77467d..ecbd649 100644
--- a/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
+++ b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
@@ -28,4 +28,7 @@
     void forceFlushCommands();
 
     boolean getsRequestedSid();
+
+    void forcePersist(boolean persist);
+    void setCustomActiveServicesCallback();
 }
diff --git a/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp b/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp
index ad78e31..f3cd218 100644
--- a/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp
+++ b/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp
@@ -163,7 +163,8 @@
 
     // LOCAL SERVERS
     std::shared_ptr<NdkServer> ndkServer = SharedRefBase::make<NdkServer>();
-    AServiceManager_addService(ndkServer->asBinder().get(), kLocalNdkServerName.c_str());
+    CHECK(STATUS_OK ==
+          AServiceManager_addService(ndkServer->asBinder().get(), kLocalNdkServerName.c_str()));
 
     return RUN_ALL_TESTS();
 }
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 0d1989e..de1a48d 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -46,6 +46,11 @@
 constexpr char kExistingNonNdkService[] = "SurfaceFlinger";
 constexpr char kBinderNdkUnitTestService[] = "BinderNdkUnitTest";
 constexpr char kLazyBinderNdkUnitTestService[] = "LazyBinderNdkUnitTest";
+constexpr char kForcePersistNdkUnitTestService[] = "ForcePersistNdkUnitTestService";
+constexpr char kActiveServicesNdkUnitTestService[] = "ActiveServicesNdkUnitTestService";
+
+constexpr unsigned int kShutdownWaitTime = 10;
+constexpr uint64_t kContextTestValue = 0xb4e42fb4d9a1d715;
 
 class MyBinderNdkUnitTest : public aidl::BnBinderNdkUnitTest {
     ndk::ScopedAStatus repeatInt(int32_t in, int32_t* out) {
@@ -76,6 +81,46 @@
         fsync(out);
         return STATUS_OK;
     }
+    ndk::ScopedAStatus forcePersist(bool persist) {
+        AServiceManager_forceLazyServicesPersist(persist);
+        return ndk::ScopedAStatus::ok();
+    }
+    ndk::ScopedAStatus setCustomActiveServicesCallback() {
+        AServiceManager_setActiveServicesCallback(activeServicesCallback, this);
+        return ndk::ScopedAStatus::ok();
+    }
+    static bool activeServicesCallback(bool hasClients, void* context) {
+        if (hasClients) {
+            return false;
+        }
+
+        // Unregister all services
+        if (!AServiceManager_tryUnregister()) {
+            // Prevent shutdown (test will fail)
+            return false;
+        }
+
+        // Re-register all services
+        AServiceManager_reRegister();
+
+        // Unregister again before shutdown
+        if (!AServiceManager_tryUnregister()) {
+            // Prevent shutdown (test will fail)
+            return false;
+        }
+
+        // Check if the context was passed correctly
+        MyBinderNdkUnitTest* service = static_cast<MyBinderNdkUnitTest*>(context);
+        if (service->contextTestValue != kContextTestValue) {
+            // Prevent shutdown (test will fail)
+            return false;
+        }
+
+        exit(EXIT_SUCCESS);
+        // Unreachable
+    }
+
+    uint64_t contextTestValue = kContextTestValue;
 };
 
 int generatedService() {
@@ -168,6 +213,16 @@
     return 1;  // should not return
 }
 
+bool isServiceRunning(const char* serviceName) {
+    AIBinder* binder = AServiceManager_checkService(serviceName);
+    if (binder == nullptr) {
+        return false;
+    }
+    AIBinder_decStrong(binder);
+
+    return true;
+}
+
 TEST(NdkBinder, GetServiceThatDoesntExist) {
     sp<IFoo> foo = IFoo::getService("asdfghkl;");
     EXPECT_EQ(nullptr, foo.get());
@@ -238,10 +293,51 @@
     service = nullptr;
     IPCThreadState::self()->flushCommands();
     // Make sure the service is dead after some time of no use
-    sleep(10);
+    sleep(kShutdownWaitTime);
     ASSERT_EQ(nullptr, AServiceManager_checkService(kLazyBinderNdkUnitTestService));
 }
 
+TEST(NdkBinder, ForcedPersistenceTest) {
+    for (int i = 0; i < 2; i++) {
+        ndk::SpAIBinder binder(AServiceManager_waitForService(kForcePersistNdkUnitTestService));
+        std::shared_ptr<aidl::IBinderNdkUnitTest> service =
+                aidl::IBinderNdkUnitTest::fromBinder(binder);
+        ASSERT_NE(service, nullptr);
+        ASSERT_TRUE(service->forcePersist(i == 0).isOk());
+
+        binder = nullptr;
+        service = nullptr;
+        IPCThreadState::self()->flushCommands();
+
+        sleep(kShutdownWaitTime);
+
+        bool isRunning = isServiceRunning(kForcePersistNdkUnitTestService);
+
+        if (i == 0) {
+            ASSERT_TRUE(isRunning) << "Service shut down when it shouldn't have.";
+        } else {
+            ASSERT_FALSE(isRunning) << "Service failed to shut down.";
+        }
+    }
+}
+
+TEST(NdkBinder, ActiveServicesCallbackTest) {
+    ndk::SpAIBinder binder(AServiceManager_waitForService(kActiveServicesNdkUnitTestService));
+    std::shared_ptr<aidl::IBinderNdkUnitTest> service =
+            aidl::IBinderNdkUnitTest::fromBinder(binder);
+    ASSERT_NE(service, nullptr);
+    ASSERT_TRUE(service->setCustomActiveServicesCallback().isOk());
+
+    binder = nullptr;
+    service = nullptr;
+    IPCThreadState::self()->flushCommands();
+
+    sleep(kShutdownWaitTime);
+
+    ASSERT_FALSE(isServiceRunning(kActiveServicesNdkUnitTestService))
+            << "Service failed to shut down.";
+}
+
 void LambdaOnDeath(void* cookie) {
     auto onDeath = static_cast<std::function<void(void)>*>(cookie);
     (*onDeath)();
@@ -564,10 +660,18 @@
     }
     if (fork() == 0) {
         prctl(PR_SET_PDEATHSIG, SIGHUP);
+        return lazyService(kForcePersistNdkUnitTestService);
+    }
+    if (fork() == 0) {
+        prctl(PR_SET_PDEATHSIG, SIGHUP);
+        return lazyService(kActiveServicesNdkUnitTestService);
+    }
+    if (fork() == 0) {
+        prctl(PR_SET_PDEATHSIG, SIGHUP);
         return generatedService();
     }
 
-    ABinderProcess_setThreadPoolMaxThreadCount(1);  // to recieve death notifications/callbacks
+    ABinderProcess_setThreadPoolMaxThreadCount(1);  // to receive death notifications/callbacks
     ABinderProcess_startThreadPool();
 
     return RUN_ALL_TESTS();
diff --git a/libs/binder/parcel_fuzzer/Android.bp b/libs/binder/parcel_fuzzer/Android.bp
index 3e6fe99..74b8eb8 100644
--- a/libs/binder/parcel_fuzzer/Android.bp
+++ b/libs/binder/parcel_fuzzer/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_fuzz {
     name: "binder_parcel_fuzzer",
     defaults: ["libbinder_ndk_host_user"],
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index fd5f2f5..e12a429 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 rust_library {
     name: "libbinder_rs",
     crate_name: "binder",
@@ -14,7 +23,11 @@
         darwin: {
             enabled: false,
         }
-    }
+    },
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.virt",
+    ],
 }
 
 rust_library {
@@ -32,7 +45,11 @@
         darwin: {
             enabled: false,
         }
-    }
+    },
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.virt",
+    ],
 }
 
 rust_bindgen {
@@ -78,6 +95,10 @@
             enabled: false,
         },
     },
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.virt",
+    ],
 }
 
 rust_test {
diff --git a/libs/binder/rust/tests/Android.bp b/libs/binder/rust/tests/Android.bp
index 8810b5d..0bf76c6 100644
--- a/libs/binder/rust/tests/Android.bp
+++ b/libs/binder/rust/tests/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 rust_test {
     name: "rustBinderTest",
     srcs: ["integration.rs"],
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 259417a..3bbb0b5 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -14,6 +14,15 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
     name: "binder_test_defaults",
     cflags: [
diff --git a/libs/binder/tests/fuzzers/Android.bp b/libs/binder/tests/fuzzers/Android.bp
index 5531296..b1263e8 100644
--- a/libs/binder/tests/fuzzers/Android.bp
+++ b/libs/binder/tests/fuzzers/Android.bp
@@ -14,6 +14,15 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
     name: "binder_fuzz_defaults",
     host_supported: true,
diff --git a/libs/binderdebug/Android.bp b/libs/binderdebug/Android.bp
index 343246a..3eeaf3e 100644
--- a/libs/binderdebug/Android.bp
+++ b/libs/binderdebug/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library {
     name: "libbinderdebug",
     vendor_available: true,
diff --git a/libs/binderdebug/tests/Android.bp b/libs/binderdebug/tests/Android.bp
index 4c06b1d..d141a05 100644
--- a/libs/binderdebug/tests/Android.bp
+++ b/libs/binderdebug/tests/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "libbinderdebug_test",
     test_suites: ["general-tests"],
diff --git a/libs/binderthreadstate/1.0/Android.bp b/libs/binderthreadstate/1.0/Android.bp
index ebdc932..99477d8 100644
--- a/libs/binderthreadstate/1.0/Android.bp
+++ b/libs/binderthreadstate/1.0/Android.bp
@@ -1,5 +1,14 @@
 // This file is autogenerated by hidl-gen -Landroidbp.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 hidl_interface {
     name: "binderthreadstateutilstest@1.0",
     root: "binderthreadstateutilstest",
diff --git a/libs/binderthreadstate/Android.bp b/libs/binderthreadstate/Android.bp
index 08c62df..0a82463 100644
--- a/libs/binderthreadstate/Android.bp
+++ b/libs/binderthreadstate/Android.bp
@@ -14,6 +14,15 @@
 
 // DO NOT ADD NEW USAGES OF THIS
 // See comments in header file.
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_static {
     name: "libbinderthreadstateutils",
     double_loadable: true,
diff --git a/libs/bufferqueueconverter/Android.bp b/libs/bufferqueueconverter/Android.bp
index bab2674..c5d3a32 100644
--- a/libs/bufferqueueconverter/Android.bp
+++ b/libs/bufferqueueconverter/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_headers {
     name: "libbufferqueueconverter_headers",
     vendor_available: true,
diff --git a/libs/cputimeinstate/Android.bp b/libs/cputimeinstate/Android.bp
index e3cd085..570af71 100644
--- a/libs/cputimeinstate/Android.bp
+++ b/libs/cputimeinstate/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library {
     name: "libtimeinstate",
     srcs: ["cputimeinstate.cpp"],
@@ -35,4 +44,3 @@
     ],
     require_root: true,
 }
-
diff --git a/libs/diskusage/Android.bp b/libs/diskusage/Android.bp
index a826306..8684061 100644
--- a/libs/diskusage/Android.bp
+++ b/libs/diskusage/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_static {
     name: "libdiskusage",
     srcs: ["dirsize.c"],
diff --git a/libs/dumputils/Android.bp b/libs/dumputils/Android.bp
index e403d36..acda402 100644
--- a/libs/dumputils/Android.bp
+++ b/libs/dumputils/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library {
     name: "libdumputils",
 
diff --git a/libs/fakeservicemanager/Android.bp b/libs/fakeservicemanager/Android.bp
index 76518c1..47c0657 100644
--- a/libs/fakeservicemanager/Android.bp
+++ b/libs/fakeservicemanager/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
     name: "fakeservicemanager_defaults",
     host_supported: true,
diff --git a/libs/gralloc/types/Android.bp b/libs/gralloc/types/Android.bp
index dd0ae30..a0032ae 100644
--- a/libs/gralloc/types/Android.bp
+++ b/libs/gralloc/types/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library {
     name: "libgralloctypes",
     defaults: ["libbinder_ndk_host_user"],
diff --git a/libs/gralloc/types/fuzzer/Android.bp b/libs/gralloc/types/fuzzer/Android.bp
index 8933dc3..6689771 100644
--- a/libs/gralloc/types/fuzzer/Android.bp
+++ b/libs/gralloc/types/fuzzer/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_fuzz {
     name: "libgralloctypes_fuzzer",
     defaults: ["libbinder_ndk_host_user"],
diff --git a/libs/gralloc/types/tests/Android.bp b/libs/gralloc/types/tests/Android.bp
index b939c1d..66eb0aa 100644
--- a/libs/gralloc/types/tests/Android.bp
+++ b/libs/gralloc/types/tests/Android.bp
@@ -14,6 +14,15 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "GrallocTypes_test",
     shared_libs: [
diff --git a/libs/graphicsenv/Android.bp b/libs/graphicsenv/Android.bp
index 642c5f2..a96a07a 100644
--- a/libs/graphicsenv/Android.bp
+++ b/libs/graphicsenv/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libgraphicsenv",
 
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index fa5044c..debd664 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -11,6 +11,15 @@
 // 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.
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_headers {
     name: "libgui_headers",
     vendor_available: true,
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 1e6fc2b..82c9268 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -55,7 +55,7 @@
     ALOGE("[%s](f:%u,a:%u) " x, mName.c_str(), mNumFrameAvailable, mNumAcquired, ##__VA_ARGS__)
 
 void BLASTBufferItemConsumer::onDisconnect() {
-    Mutex::Autolock lock(mFrameEventHistoryMutex);
+    Mutex::Autolock lock(mMutex);
     mPreviouslyConnected = mCurrentlyConnected;
     mCurrentlyConnected = false;
     if (mPreviouslyConnected) {
@@ -66,7 +66,7 @@
 
 void BLASTBufferItemConsumer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps,
                                                        FrameEventHistoryDelta* outDelta) {
-    Mutex::Autolock lock(mFrameEventHistoryMutex);
+    Mutex::Autolock lock(mMutex);
     if (newTimestamps) {
         // BufferQueueProducer only adds a new timestamp on
         // queueBuffer
@@ -90,7 +90,7 @@
                                                     const sp<Fence>& prevReleaseFence,
                                                     CompositorTiming compositorTiming,
                                                     nsecs_t latchTime, nsecs_t dequeueReadyTime) {
-    Mutex::Autolock lock(mFrameEventHistoryMutex);
+    Mutex::Autolock lock(mMutex);
 
     // if the producer is not connected, don't bother updating,
     // the next producer that connects won't access this frame event
@@ -108,7 +108,7 @@
 
 void BLASTBufferItemConsumer::getConnectionEvents(uint64_t frameNumber, bool* needsDisconnect) {
     bool disconnect = false;
-    Mutex::Autolock lock(mFrameEventHistoryMutex);
+    Mutex::Autolock lock(mMutex);
     while (!mDisconnectEvents.empty() && mDisconnectEvents.front() <= frameNumber) {
         disconnect = true;
         mDisconnectEvents.pop();
@@ -116,6 +116,19 @@
     if (needsDisconnect != nullptr) *needsDisconnect = disconnect;
 }
 
+void BLASTBufferItemConsumer::setBlastBufferQueue(BLASTBufferQueue* blastbufferqueue) {
+    Mutex::Autolock lock(mMutex);
+    mBLASTBufferQueue = blastbufferqueue;
+}
+
+void BLASTBufferItemConsumer::onSidebandStreamChanged() {
+    Mutex::Autolock lock(mMutex);
+    if (mBLASTBufferQueue != nullptr) {
+        sp<NativeHandle> stream = getSidebandStream();
+        mBLASTBufferQueue->setSidebandStream(stream);
+    }
+}
+
 BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface,
                                    int width, int height, int32_t format,
                                    bool enableTripleBuffering)
@@ -145,6 +158,7 @@
     mBufferItemConsumer->setBufferFreedListener(this);
     mBufferItemConsumer->setDefaultBufferSize(mSize.width, mSize.height);
     mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format));
+    mBufferItemConsumer->setBlastBufferQueue(this);
 
     mTransformHint = mSurfaceControl->getTransformHint();
     mBufferItemConsumer->setTransformHint(mTransformHint);
@@ -160,6 +174,7 @@
 }
 
 BLASTBufferQueue::~BLASTBufferQueue() {
+    mBufferItemConsumer->setBlastBufferQueue(nullptr);
     if (mPendingTransactions.empty()) {
         return;
     }
@@ -557,6 +572,13 @@
     return OK;
 }
 
+void BLASTBufferQueue::setSidebandStream(const sp<NativeHandle>& stream) {
+    std::unique_lock _lock{mMutex};
+    SurfaceComposerClient::Transaction t;
+
+    t.setSidebandStream(mSurfaceControl, stream).apply();
+}
+
 sp<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) {
     std::unique_lock _lock{mMutex};
     sp<IBinder> scHandle = nullptr;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 27fb2a8..d41da9b 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -194,6 +194,25 @@
     }
 }
 
+void TransactionCompletedListener::addSurfaceStatsListener(void* context, void* cookie,
+        sp<SurfaceControl> surfaceControl, SurfaceStatsCallback listener) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    mSurfaceStatsListeners.insert({surfaceControl->getHandle(),
+            SurfaceStatsCallbackEntry(context, cookie, listener)});
+}
+
+void TransactionCompletedListener::removeSurfaceStatsListener(void* context, void* cookie) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    for (auto it = mSurfaceStatsListeners.begin(); it != mSurfaceStatsListeners.end();) {
+        auto [itContext, itCookie, itListener] = it->second;
+        if (itContext == context && itCookie == cookie) {
+            it = mSurfaceStatsListeners.erase(it);
+        } else {
+            it++;
+        }
+    }
+}
+
 void TransactionCompletedListener::addSurfaceControlToCallbacks(
         const sp<SurfaceControl>& surfaceControl,
         const std::unordered_set<CallbackId>& callbackIds) {
@@ -210,6 +229,7 @@
 void TransactionCompletedListener::onTransactionCompleted(ListenerStats listenerStats) {
     std::unordered_map<CallbackId, CallbackTranslation> callbacksMap;
     std::multimap<sp<IBinder>, sp<JankDataListener>> jankListenersMap;
+    std::multimap<sp<IBinder>, SurfaceStatsCallbackEntry> surfaceListeners;
     {
         std::lock_guard<std::mutex> lock(mMutex);
 
@@ -226,6 +246,7 @@
          */
         callbacksMap = mCallbacks;
         jankListenersMap = mJankListeners;
+        surfaceListeners = mSurfaceStatsListeners;
         for (const auto& transactionStats : listenerStats.transactionStats) {
             for (auto& callbackId : transactionStats.callbackIds) {
                 mCallbacks.erase(callbackId);
@@ -259,9 +280,16 @@
                              surfaceControlStats);
         }
         for (const auto& surfaceStats : transactionStats.surfaceStats) {
+            auto listenerRange = surfaceListeners.equal_range(surfaceStats.surfaceControl);
+            for (auto it = listenerRange.first; it != listenerRange.second; it++) {
+                auto entry = it->second;
+                entry.callback(entry.context, transactionStats.latchTime,
+                    transactionStats.presentFence, surfaceStats);
+            }
+
             if (surfaceStats.jankData.empty()) continue;
-            for (auto it = jankListenersMap.find(surfaceStats.surfaceControl);
-                    it != jankListenersMap.end(); it++) {
+            auto jankRange = jankListenersMap.equal_range(surfaceStats.surfaceControl);
+            for (auto it = jankRange.first; it != jankRange.second; it++) {
                 it->second->onJankDataAvailable(surfaceStats.jankData);
             }
         }
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index bccb71b..dd8e714 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -32,6 +32,7 @@
 
 namespace android {
 
+class BLASTBufferQueue;
 class BufferItemConsumer;
 
 class BLASTBufferItemConsumer : public BufferItemConsumer {
@@ -40,27 +41,32 @@
                             int bufferCount, bool controlledByApp)
           : BufferItemConsumer(consumer, consumerUsage, bufferCount, controlledByApp),
             mCurrentlyConnected(false),
-            mPreviouslyConnected(false) {}
+            mPreviouslyConnected(false),
+            mBLASTBufferQueue(nullptr) {}
 
     void onDisconnect() override;
     void addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps,
-                                  FrameEventHistoryDelta* outDelta) override
-            REQUIRES(mFrameEventHistoryMutex);
+                                  FrameEventHistoryDelta* outDelta) override REQUIRES(mMutex);
     void updateFrameTimestamps(uint64_t frameNumber, nsecs_t refreshStartTime,
                                const sp<Fence>& gpuCompositionDoneFence,
                                const sp<Fence>& presentFence, const sp<Fence>& prevReleaseFence,
                                CompositorTiming compositorTiming, nsecs_t latchTime,
-                               nsecs_t dequeueReadyTime) REQUIRES(mFrameEventHistoryMutex);
+                               nsecs_t dequeueReadyTime) REQUIRES(mMutex);
     void getConnectionEvents(uint64_t frameNumber, bool* needsDisconnect);
+    void setBlastBufferQueue(BLASTBufferQueue* blastbufferqueue) REQUIRES(mMutex);
+
+protected:
+    void onSidebandStreamChanged() override REQUIRES(mMutex);
 
 private:
     uint64_t mCurrentFrameNumber = 0;
 
-    Mutex mFrameEventHistoryMutex;
-    ConsumerFrameEventHistory mFrameEventHistory GUARDED_BY(mFrameEventHistoryMutex);
-    std::queue<uint64_t> mDisconnectEvents GUARDED_BY(mFrameEventHistoryMutex);
-    bool mCurrentlyConnected GUARDED_BY(mFrameEventHistoryMutex);
-    bool mPreviouslyConnected GUARDED_BY(mFrameEventHistoryMutex);
+    Mutex mMutex;
+    ConsumerFrameEventHistory mFrameEventHistory GUARDED_BY(mMutex);
+    std::queue<uint64_t> mDisconnectEvents GUARDED_BY(mMutex);
+    bool mCurrentlyConnected GUARDED_BY(mMutex);
+    bool mPreviouslyConnected GUARDED_BY(mMutex);
+    BLASTBufferQueue* mBLASTBufferQueue GUARDED_BY(mMutex);
 };
 
 class BLASTBufferQueue
@@ -94,6 +100,8 @@
     status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless);
     status_t setFrameTimelineInfo(const FrameTimelineInfo& info);
 
+    void setSidebandStream(const sp<NativeHandle>& stream);
+
     virtual ~BLASTBufferQueue();
 
 private:
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index e89f3a7..8de7574 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -80,6 +80,10 @@
 using TransactionCompletedCallback =
         std::function<void(nsecs_t /*latchTime*/, const sp<Fence>& /*presentFence*/,
                            const std::vector<SurfaceControlStats>& /*stats*/)>;
+using SurfaceStatsCallback =
+        std::function<void(void* /*context*/, nsecs_t /*latchTime*/,
+                           const sp<Fence>& /*presentFence*/,
+                           const SurfaceStats& /*stats*/)>;
 
 // ---------------------------------------------------------------------------
 
@@ -650,8 +654,21 @@
                 surfaceControls;
     };
 
+    struct SurfaceStatsCallbackEntry {
+        SurfaceStatsCallbackEntry(void* context, void* cookie, SurfaceStatsCallback callback)
+                : context(context),
+                cookie(cookie),
+                callback(callback) {}
+
+        void* context;
+        void* cookie;
+        SurfaceStatsCallback callback;
+    };
+
     std::unordered_map<CallbackId, CallbackTranslation> mCallbacks GUARDED_BY(mMutex);
     std::multimap<sp<IBinder>, sp<JankDataListener>> mJankListeners GUARDED_BY(mMutex);
+    std::multimap<sp<IBinder>, SurfaceStatsCallbackEntry>
+                mSurfaceStatsListeners GUARDED_BY(mMutex);
 
 public:
     static sp<TransactionCompletedListener> getInstance();
@@ -679,6 +696,10 @@
      */
     void removeJankListener(const sp<JankDataListener>& listener);
 
+    void addSurfaceStatsListener(void* context, void* cookie, sp<SurfaceControl> surfaceControl,
+                SurfaceStatsCallback listener);
+    void removeSurfaceStatsListener(void* context, void* cookie);
+
     // Overrides BnTransactionCompletedListener's onTransactionCompleted
     void onTransactionCompleted(ListenerStats stats) override;
 };
diff --git a/libs/gui/sysprop/Android.bp b/libs/gui/sysprop/Android.bp
index 64b1eac..bddb0ac 100644
--- a/libs/gui/sysprop/Android.bp
+++ b/libs/gui/sysprop/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 sysprop_library {
     name: "LibGuiProperties",
     srcs: ["*.sysprop"],
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index 53c13c8..c801c62 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -2,6 +2,15 @@
 
 // Build the binary to $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
 // to integrate with auto-test framework.
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "libgui_test",
     test_suites: ["device-tests"],
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index 5447b76..fb07a19 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -129,7 +129,11 @@
     }
 
     void setUpProducer(BLASTBufferQueueHelper adapter, sp<IGraphicBufferProducer>& producer) {
-        auto igbProducer = adapter.getIGraphicBufferProducer();
+        producer = adapter.getIGraphicBufferProducer();
+        setUpProducer(producer);
+    }
+
+    void setUpProducer(sp<IGraphicBufferProducer>& igbProducer) {
         ASSERT_NE(nullptr, igbProducer.get());
         ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
         IGraphicBufferProducer::QueueBufferOutput qbOutput;
@@ -137,7 +141,6 @@
                   igbProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false,
                                        &qbOutput));
         ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
-        producer = igbProducer;
     }
 
     void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
@@ -555,6 +558,8 @@
     ASSERT_EQ(queuesToNativeWindow, 1);
 }
 
+// Test a slow producer doesn't hold up a faster producer from the same client. Essentially tests
+// BBQ uses separate transaction queues.
 TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) {
     sp<SurfaceControl> bgSurface =
             mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
@@ -781,7 +786,7 @@
     void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
                              nsecs_t* requestedPresentTime, nsecs_t* postedTime,
                              IGraphicBufferProducer::QueueBufferOutput* qbOutput,
-                             bool getFrameTimestamps) {
+                             bool getFrameTimestamps, nsecs_t requestedPresentTimeDelay = 0) {
         int slot;
         sp<Fence> fence;
         sp<GraphicBuffer> buf;
@@ -791,7 +796,7 @@
         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
         ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
 
-        nsecs_t requestedTime = systemTime();
+        nsecs_t requestedTime = systemTime() + requestedPresentTimeDelay;
         if (requestedPresentTime) *requestedPresentTime = requestedTime;
         IGraphicBufferProducer::QueueBufferInput input(requestedTime, false, HAL_DATASPACE_UNKNOWN,
                                                        Rect(mDisplayWidth, mDisplayHeight),
@@ -801,6 +806,27 @@
         if (postedTime) *postedTime = systemTime();
         igbProducer->queueBuffer(slot, input, qbOutput);
     }
+
+    void createBufferQueueProducer(sp<IGraphicBufferProducer>* bqIgbp) {
+        mBufferQueueSurfaceControl =
+                mClient->createSurface(String8("BqSurface"), 0, 0, PIXEL_FORMAT_RGBA_8888,
+                                       ISurfaceComposerClient::eFXSurfaceBufferQueue);
+        ASSERT_NE(nullptr, mBufferQueueSurfaceControl.get());
+        Transaction()
+                .setLayerStack(mBufferQueueSurfaceControl, 0)
+                .show(mBufferQueueSurfaceControl)
+                .setDataspace(mBufferQueueSurfaceControl, ui::Dataspace::V0_SRGB)
+                .setSize(mBufferQueueSurfaceControl, mDisplayWidth, mDisplayHeight)
+                .setLayer(mBufferQueueSurfaceControl, std::numeric_limits<int32_t>::max())
+                .apply();
+
+        sp<Surface> bqSurface = mBufferQueueSurfaceControl->getSurface();
+        ASSERT_NE(nullptr, bqSurface.get());
+
+        *bqIgbp = bqSurface->getIGraphicBufferProducer();
+        setUpProducer(*bqIgbp);
+    }
+    sp<SurfaceControl> mBufferQueueSurfaceControl;
 };
 
 TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
@@ -853,4 +879,153 @@
     // wait for any callbacks that have not been received
     adapter.waitForCallbacks();
 }
+
+// Runs the same Frame Event History test
+TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic_BufferQueue) {
+    sp<IGraphicBufferProducer> bqIgbp;
+    createBufferQueueProducer(&bqIgbp);
+
+    ProducerFrameEventHistory history;
+    IGraphicBufferProducer::QueueBufferOutput qbOutput;
+    nsecs_t requestedPresentTimeA = 0;
+    nsecs_t postedTimeA = 0;
+    setUpAndQueueBuffer(bqIgbp, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
+    history.applyDelta(qbOutput.frameTimestamps);
+
+    FrameEvents* events = nullptr;
+    events = history.getFrame(1);
+    ASSERT_NE(nullptr, events);
+    ASSERT_EQ(1, events->frameNumber);
+    ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
+    ASSERT_GE(events->postedTime, postedTimeA);
+
+    // wait for buffer to be presented
+    std::this_thread::sleep_for(200ms);
+
+    nsecs_t requestedPresentTimeB = 0;
+    nsecs_t postedTimeB = 0;
+    setUpAndQueueBuffer(bqIgbp, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
+    history.applyDelta(qbOutput.frameTimestamps);
+    events = history.getFrame(1);
+    ASSERT_NE(nullptr, events);
+
+    // frame number, requestedPresentTime, and postTime should not have changed
+    ASSERT_EQ(1, events->frameNumber);
+    ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
+    ASSERT_GE(events->postedTime, postedTimeA);
+
+    ASSERT_GE(events->latchTime, postedTimeA);
+    ASSERT_FALSE(events->hasDequeueReadyInfo());
+
+    ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
+    ASSERT_NE(nullptr, events->displayPresentFence);
+    ASSERT_NE(nullptr, events->releaseFence);
+
+    // we should also have gotten the initial values for the next frame
+    events = history.getFrame(2);
+    ASSERT_NE(nullptr, events);
+    ASSERT_EQ(2, events->frameNumber);
+    ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
+    ASSERT_GE(events->postedTime, postedTimeB);
+}
+
+TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
+    BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
+    sp<IGraphicBufferProducer> igbProducer;
+    setUpProducer(adapter, igbProducer);
+
+    ProducerFrameEventHistory history;
+    IGraphicBufferProducer::QueueBufferOutput qbOutput;
+    nsecs_t requestedPresentTimeA = 0;
+    nsecs_t postedTimeA = 0;
+    nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
+    setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
+                        presentTimeDelay);
+    history.applyDelta(qbOutput.frameTimestamps);
+
+    FrameEvents* events = nullptr;
+    events = history.getFrame(1);
+    ASSERT_NE(nullptr, events);
+    ASSERT_EQ(1, events->frameNumber);
+    ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
+    ASSERT_GE(events->postedTime, postedTimeA);
+
+    // queue another buffer so the first can be dropped
+    nsecs_t requestedPresentTimeB = 0;
+    nsecs_t postedTimeB = 0;
+    setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
+    history.applyDelta(qbOutput.frameTimestamps);
+    events = history.getFrame(1);
+    ASSERT_NE(nullptr, events);
+
+    // frame number, requestedPresentTime, and postTime should not have changed
+    ASSERT_EQ(1, events->frameNumber);
+    ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
+    ASSERT_GE(events->postedTime, postedTimeA);
+
+    // a valid latchtime should not be set
+    ASSERT_FALSE(events->hasLatchInfo());
+    ASSERT_FALSE(events->hasDequeueReadyInfo());
+
+    ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
+    ASSERT_NE(nullptr, events->displayPresentFence);
+    ASSERT_NE(nullptr, events->releaseFence);
+
+    // we should also have gotten the initial values for the next frame
+    events = history.getFrame(2);
+    ASSERT_NE(nullptr, events);
+    ASSERT_EQ(2, events->frameNumber);
+    ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
+    ASSERT_GE(events->postedTime, postedTimeB);
+}
+
+TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame_BufferQueue) {
+    sp<IGraphicBufferProducer> bqIgbp;
+    createBufferQueueProducer(&bqIgbp);
+
+    ProducerFrameEventHistory history;
+    IGraphicBufferProducer::QueueBufferOutput qbOutput;
+    nsecs_t requestedPresentTimeA = 0;
+    nsecs_t postedTimeA = 0;
+    nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
+    setUpAndQueueBuffer(bqIgbp, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
+                        presentTimeDelay);
+    history.applyDelta(qbOutput.frameTimestamps);
+
+    FrameEvents* events = nullptr;
+    events = history.getFrame(1);
+    ASSERT_NE(nullptr, events);
+    ASSERT_EQ(1, events->frameNumber);
+    ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
+    ASSERT_GE(events->postedTime, postedTimeA);
+
+    // queue another buffer so the first can be dropped
+    nsecs_t requestedPresentTimeB = 0;
+    nsecs_t postedTimeB = 0;
+    setUpAndQueueBuffer(bqIgbp, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
+    history.applyDelta(qbOutput.frameTimestamps);
+    events = history.getFrame(1);
+    ASSERT_NE(nullptr, events);
+
+    // frame number, requestedPresentTime, and postTime should not have changed
+    ASSERT_EQ(1, events->frameNumber);
+    ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
+    ASSERT_GE(events->postedTime, postedTimeA);
+
+    // a valid latchtime should not be set
+    ASSERT_FALSE(events->hasLatchInfo());
+    ASSERT_FALSE(events->hasDequeueReadyInfo());
+
+    ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
+    ASSERT_NE(nullptr, events->displayPresentFence);
+    ASSERT_NE(nullptr, events->releaseFence);
+
+    // we should also have gotten the initial values for the next frame
+    events = history.getFrame(2);
+    ASSERT_NE(nullptr, events);
+    ASSERT_EQ(2, events->frameNumber);
+    ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
+    ASSERT_GE(events->postedTime, postedTimeB);
+}
+
 } // namespace android
diff --git a/libs/incidentcompanion/Android.bp b/libs/incidentcompanion/Android.bp
index 63411b9..ef7f523 100644
--- a/libs/incidentcompanion/Android.bp
+++ b/libs/incidentcompanion/Android.bp
@@ -14,6 +14,15 @@
  * limitations under the License.
  */
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 filegroup {
     name: "incidentcompanion_aidl",
     srcs: [
@@ -49,4 +58,3 @@
         "-Wunused-parameter",
     ],
 }
-
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index fce3000..4253610 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -14,6 +14,15 @@
 
 // libinput is partially built for the host (used by build time keymap validation tool)
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 filegroup {
     name: "inputconstants_aidl",
     srcs: [
diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp
index b23aade..fe8a567 100644
--- a/libs/input/tests/Android.bp
+++ b/libs/input/tests/Android.bp
@@ -1,4 +1,13 @@
 // Build the unit tests.
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "libinput_tests",
     srcs: [
diff --git a/libs/math/Android.bp b/libs/math/Android.bp
index 22d4712..3cf9f3f 100644
--- a/libs/math/Android.bp
+++ b/libs/math/Android.bp
@@ -12,6 +12,23 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["frameworks_native_libs_math_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "frameworks_native_libs_math_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 cc_library_static {
     name: "libmath",
     host_supported: true,
diff --git a/libs/math/tests/Android.bp b/libs/math/tests/Android.bp
index 0184f56..4a7c4dd 100644
--- a/libs/math/tests/Android.bp
+++ b/libs/math/tests/Android.bp
@@ -14,6 +14,15 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_libs_math_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_libs_math_license"],
+}
+
 cc_test {
     name: "vec_test",
     srcs: ["vec_test.cpp"],
diff --git a/libs/nativebase/Android.bp b/libs/nativebase/Android.bp
index 8399e8c..1a4729c 100644
--- a/libs/nativebase/Android.bp
+++ b/libs/nativebase/Android.bp
@@ -12,6 +12,23 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["frameworks_native_libs_nativebase_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "frameworks_native_libs_nativebase_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 cc_library_headers {
     name: "libnativebase_headers",
     vendor_available: true,
diff --git a/libs/nativedisplay/Android.bp b/libs/nativedisplay/Android.bp
index 6574ae6..ed728dc 100644
--- a/libs/nativedisplay/Android.bp
+++ b/libs/nativedisplay/Android.bp
@@ -12,6 +12,25 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: [
+        "frameworks_native_libs_nativedisplay_license",
+    ],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "frameworks_native_libs_nativedisplay_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 cc_library_headers {
     name: "libnativedisplay_headers",
     export_include_dirs: ["include",],
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index 3011dcc..8675439 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -12,6 +12,25 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: [
+        "frameworks_native_libs_nativewindow_license",
+    ],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "frameworks_native_libs_nativewindow_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 ndk_headers {
     name: "libnativewindow_ndk_headers",
     from: "include/android",
diff --git a/libs/nativewindow/tests/Android.bp b/libs/nativewindow/tests/Android.bp
index 2e4bd99..30737c1 100644
--- a/libs/nativewindow/tests/Android.bp
+++ b/libs/nativewindow/tests/Android.bp
@@ -14,6 +14,17 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_libs_nativewindow_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: [
+        "frameworks_native_libs_nativewindow_license",
+    ],
+}
+
 cc_test {
     name: "libnativewindow_test",
     test_suites: [
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index 00540b8..eb3b434 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
     name: "renderengine_defaults",
     cflags: [
diff --git a/libs/renderengine/OWNERS b/libs/renderengine/OWNERS
index 08cf2de..c478506 100644
--- a/libs/renderengine/OWNERS
+++ b/libs/renderengine/OWNERS
@@ -1,3 +1,5 @@
 alecmouri@google.com
+djsollen@google.com
 jreck@google.com
 lpy@google.com
+scroggo@google.com
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index 64d6c6b..7496b74 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -72,6 +72,7 @@
                         base::unique_fd&& bufferFence, base::unique_fd* drawFence) override;
     bool cleanupPostRender(CleanupMode mode) override;
     int getContextPriority() override;
+    bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; }
 
     EGLDisplay getEGLDisplay() const { return mEGLDisplay; }
     // Creates an output image for rendering to
diff --git a/libs/renderengine/gl/filters/BlurFilter.cpp b/libs/renderengine/gl/filters/BlurFilter.cpp
index 19f18c0..3455e08 100644
--- a/libs/renderengine/gl/filters/BlurFilter.cpp
+++ b/libs/renderengine/gl/filters/BlurFilter.cpp
@@ -207,7 +207,7 @@
 }
 
 string BlurFilter::getVertexShader() const {
-    return R"SHADER(#version 310 es
+    return R"SHADER(#version 300 es
         precision mediump float;
 
         in vec2 aPosition;
@@ -222,7 +222,7 @@
 }
 
 string BlurFilter::getFragmentShader() const {
-    return R"SHADER(#version 310 es
+    return R"SHADER(#version 300 es
         precision mediump float;
 
         uniform sampler2D uTexture;
@@ -244,7 +244,7 @@
 }
 
 string BlurFilter::getMixFragShader() const {
-    string shader = R"SHADER(#version 310 es
+    string shader = R"SHADER(#version 300 es
         precision mediump float;
 
         in highp vec2 vUV;
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index 506f81e..163a163 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -188,6 +188,10 @@
     // number of contexts that can be created at a specific priority level in the system.
     virtual int getContextPriority() = 0;
 
+    // Returns true if blur was requested in the RenderEngineCreationArgs and the implementation
+    // also supports background blur.  If false, no blur will be applied when drawing layers.
+    virtual bool supportsBackgroundBlur() = 0;
+
 protected:
     friend class threaded::RenderEngineThreaded;
 };
diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h
index 2c34da4..895ba3f 100644
--- a/libs/renderengine/include/renderengine/mock/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -54,6 +54,7 @@
                           base::unique_fd*));
     MOCK_METHOD0(cleanFramebufferCache, void());
     MOCK_METHOD0(getContextPriority, int());
+    MOCK_METHOD0(supportsBackgroundBlur, bool());
 };
 
 } // namespace mock
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index b4a2d79..327b04c 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -337,7 +337,7 @@
     if (useProtectedContext == mInProtectedContext) {
         return true;
     }
-    if (useProtectedContext && supportsProtectedContent()) {
+    if (useProtectedContext && !supportsProtectedContent()) {
         return false;
     }
     const EGLSurface surface =
@@ -518,7 +518,7 @@
 }
 
 void SkiaGLRenderEngine::initCanvas(SkCanvas* canvas, const DisplaySettings& display) {
-    if (mCapture->isCaptureRunning()) {
+    if (CC_UNLIKELY(mCapture->isCaptureRunning())) {
         // Record display settings when capture is running.
         std::stringstream displaySettings;
         PrintTo(display, &displaySettings);
@@ -626,6 +626,7 @@
     // offscreen buffer and when to render to the native buffer.
     sk_sp<SkSurface> activeSurface(dstSurface);
     SkCanvas* canvas = dstCanvas;
+    SkiaCapture::OffscreenState offscreenCaptureState;
     const LayerSettings* blurCompositionLayer = nullptr;
     if (mBlurFilter) {
         bool requiresCompositionLayer = false;
@@ -642,7 +643,7 @@
             }
             if (requiresCompositionLayer) {
                 activeSurface = dstSurface->makeSurface(dstSurface->imageInfo());
-                canvas = activeSurface->getCanvas();
+                canvas = mCapture->tryOffscreenCapture(activeSurface.get(), &offscreenCaptureState);
                 blurCompositionLayer = layer;
                 break;
             }
@@ -692,7 +693,15 @@
             //  blit the offscreen framebuffer into the destination AHB
             SkPaint paint;
             paint.setBlendMode(SkBlendMode::kSrc);
-            activeSurface->draw(dstCanvas, 0, 0, SkSamplingOptions(), &paint);
+            if (CC_UNLIKELY(mCapture->isCaptureRunning())) {
+                uint64_t id = mCapture->endOffscreenCapture(&offscreenCaptureState);
+                dstCanvas->drawAnnotation(SkRect::Make(dstCanvas->imageInfo().dimensions()),
+                                          String8::format("SurfaceID|%" PRId64, id).c_str(),
+                                          nullptr);
+                dstCanvas->drawImage(blurInput, 0, 0, SkSamplingOptions(), &paint);
+            } else {
+                activeSurface->draw(dstCanvas, 0, 0, SkSamplingOptions(), &paint);
+            }
 
             // assign dstCanvas to canvas and ensure that the canvas state is up to date
             canvas = dstCanvas;
@@ -709,7 +718,7 @@
         }
 
         canvas->save();
-        if (mCapture->isCaptureRunning()) {
+        if (CC_UNLIKELY(mCapture->isCaptureRunning())) {
             // Record the name of the layer if the capture is running.
             std::stringstream layerSettings;
             PrintTo(*layer, &layerSettings);
@@ -744,7 +753,7 @@
                                             blurInput);
             }
             for (auto region : layer->blurRegions) {
-                if (cachedBlurs[region.blurRadius] != nullptr) {
+                if (cachedBlurs[region.blurRadius] == nullptr) {
                     ATRACE_NAME("BlurRegion");
                     cachedBlurs[region.blurRadius] =
                             mBlurFilter->generate(grContext.get(), region.blurRadius, blurInput,
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index 8ef7359..5779ae6 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -61,6 +61,7 @@
     bool isProtected() const override { return mInProtectedContext; }
     bool supportsProtectedContent() const override;
     bool useProtectedContext(bool useProtectedContext) override;
+    bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; }
 
 protected:
     void dump(std::string& result) override;
diff --git a/libs/renderengine/skia/debug/SkiaCapture.cpp b/libs/renderengine/skia/debug/SkiaCapture.cpp
index e9cfead..40f5cf2 100644
--- a/libs/renderengine/skia/debug/SkiaCapture.cpp
+++ b/libs/renderengine/skia/debug/SkiaCapture.cpp
@@ -41,11 +41,11 @@
     mTimer.stop();
 }
 
-SkCanvas* SkiaCapture::tryCapture(SkSurface* surface) {
+SkCanvas* SkiaCapture::tryCapture(SkSurface* surface) NO_THREAD_SAFETY_ANALYSIS {
     ATRACE_CALL();
 
     // If we are not running yet, set up.
-    if (!mCaptureRunning) {
+    if (CC_LIKELY(!mCaptureRunning)) {
         mTimerInterval = std::chrono::milliseconds(
                 base::GetIntProperty(PROPERTY_DEBUG_RENDERENGINE_CAPTURE_SKIA_MS, 0));
         // Set up the multi-frame capture. If we fail to set it up, then just return canvas.
@@ -56,7 +56,8 @@
         // Start the new timer. When timer expires, write to file.
         mTimer.setTimeout(
                 [this] {
-                    endCapture();
+                    const std::scoped_lock lock(mMutex);
+                    LOG_ALWAYS_FATAL_IF(mCurrentPageCanvas != nullptr);
                     writeToFile();
                     // To avoid going in circles, set the flag to 0. This way the capture can be
                     // restarted just by setting the flag and without restarting the process.
@@ -65,29 +66,82 @@
                 mTimerInterval);
     }
 
+    mMutex.lock();
+
     // Create a canvas pointer, fill it.
-    SkCanvas* pictureCanvas = mMultiPic->beginPage(surface->width(), surface->height());
+    mCurrentPageCanvas = mMultiPic->beginPage(surface->width(), surface->height());
 
     // Setting up an nway canvas is common to any kind of capture.
     mNwayCanvas = std::make_unique<SkNWayCanvas>(surface->width(), surface->height());
     mNwayCanvas->addCanvas(surface->getCanvas());
-    mNwayCanvas->addCanvas(pictureCanvas);
+    mNwayCanvas->addCanvas(mCurrentPageCanvas);
 
     return mNwayCanvas.get();
 }
 
-void SkiaCapture::endCapture() {
+void SkiaCapture::endCapture() NO_THREAD_SAFETY_ANALYSIS {
     ATRACE_CALL();
     // Don't end anything if we are not running.
-    if (!mCaptureRunning) {
+    if (CC_LIKELY(!mCaptureRunning)) {
         return;
     }
     // Reset the canvas pointer.
+    mCurrentPageCanvas = nullptr;
     mNwayCanvas.reset();
     // End page.
     if (mMultiPic) {
         mMultiPic->endPage();
     }
+    mMutex.unlock();
+}
+
+SkCanvas* SkiaCapture::tryOffscreenCapture(SkSurface* surface, OffscreenState* state) {
+    ATRACE_CALL();
+    // Don't start anything if we are not running.
+    if (CC_LIKELY(!mCaptureRunning)) {
+        return surface->getCanvas();
+    }
+
+    // Create a canvas pointer, fill it.
+    state->offscreenRecorder = std::make_unique<SkPictureRecorder>();
+    SkCanvas* pictureCanvas =
+            state->offscreenRecorder->beginRecording(surface->width(), surface->height());
+
+    // Setting up an nway canvas is common to any kind of capture.
+    state->offscreenCanvas = std::make_unique<SkNWayCanvas>(surface->width(), surface->height());
+    state->offscreenCanvas->addCanvas(surface->getCanvas());
+    state->offscreenCanvas->addCanvas(pictureCanvas);
+
+    return state->offscreenCanvas.get();
+}
+
+uint64_t SkiaCapture::endOffscreenCapture(OffscreenState* state) {
+    ATRACE_CALL();
+    // Don't end anything if we are not running.
+    if (CC_LIKELY(!mCaptureRunning)) {
+        return 0;
+    }
+
+    // compute the uniqueID for this capture
+    static std::atomic<uint64_t> nextID{1};
+    const uint64_t uniqueID = nextID.fetch_add(1, std::memory_order_relaxed);
+
+    // Reset the canvas pointer as we are no longer drawing into it
+    state->offscreenCanvas.reset();
+
+    // Record the offscreen as a picture in the currently active page.
+    SkRect bounds =
+            SkRect::Make(state->offscreenRecorder->getRecordingCanvas()->imageInfo().dimensions());
+    mCurrentPageCanvas
+            ->drawAnnotation(bounds,
+                             String8::format("OffscreenLayerDraw|%" PRId64, uniqueID).c_str(),
+                             nullptr);
+    mCurrentPageCanvas->drawPicture(state->offscreenRecorder->finishRecordingAsPicture());
+
+    // Reset the offscreen picture recorder
+    state->offscreenRecorder.reset();
+
+    return uniqueID;
 }
 
 void SkiaCapture::writeToFile() {
diff --git a/libs/renderengine/skia/debug/SkiaCapture.h b/libs/renderengine/skia/debug/SkiaCapture.h
index eaaf598..5e18e60 100644
--- a/libs/renderengine/skia/debug/SkiaCapture.h
+++ b/libs/renderengine/skia/debug/SkiaCapture.h
@@ -18,8 +18,12 @@
 
 #include <SkDocument.h>
 #include <SkNWayCanvas.h>
+#include <SkPictureRecorder.h>
 #include <SkSurface.h>
+
 #include <chrono>
+#include <mutex>
+
 #include "CaptureTimer.h"
 #include "tools/SkSharingProc.h"
 
@@ -48,6 +52,16 @@
     // Returns whether the capture is running.
     bool isCaptureRunning() { return mCaptureRunning; }
 
+    // Offscreen state member variables are private to SkiaCapture, but the allocation
+    // and lifetime is managed by the caller. This enables nested offscreen
+    // captures to occur.
+    struct OffscreenState {
+        std::unique_ptr<SkPictureRecorder> offscreenRecorder;
+        std::unique_ptr<SkNWayCanvas> offscreenCanvas;
+    };
+    SkCanvas* tryOffscreenCapture(SkSurface* surface, OffscreenState* state);
+    uint64_t endOffscreenCapture(OffscreenState* state);
+
 private:
     // Performs the first-frame work of a multi frame SKP capture. Returns true if successful.
     bool setupMultiFrameCapture();
@@ -61,10 +75,16 @@
     std::unique_ptr<SkSharingSerialContext> mSerialContext;
     std::unique_ptr<SkNWayCanvas> mNwayCanvas;
 
+    SkCanvas* mCurrentPageCanvas = nullptr;
+
     // Capturing and interval control.
     bool mCaptureRunning = false;
     CaptureTimer mTimer;
     Interval mTimerInterval = 0ms;
+
+    // Mutex to ensure that a frame in progress when the timer fires is allowed to run to
+    // completion before we write the file to disk.
+    std::mutex mMutex;
 };
 
 } // namespace skia
diff --git a/libs/renderengine/skia/filters/BlurFilter.cpp b/libs/renderengine/skia/filters/BlurFilter.cpp
index 9d20e32..5960e48 100644
--- a/libs/renderengine/skia/filters/BlurFilter.cpp
+++ b/libs/renderengine/skia/filters/BlurFilter.cpp
@@ -20,6 +20,7 @@
 #include <SkCanvas.h>
 #include <SkData.h>
 #include <SkPaint.h>
+#include <SkRRect.h>
 #include <SkRuntimeEffect.h>
 #include <SkSize.h>
 #include <SkString.h>
diff --git a/libs/renderengine/tests/Android.bp b/libs/renderengine/tests/Android.bp
index 51c7028..d0e19dd 100644
--- a/libs/renderengine/tests/Android.bp
+++ b/libs/renderengine/tests/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "librenderengine_test",
     defaults: ["skia_deps", "surfaceflinger_defaults"],
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index 886c9da..500a90b 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -914,13 +914,6 @@
 
 template <typename SourceVariant>
 void RenderEngineTest::fillBufferAndBlurBackground() {
-        char value[PROPERTY_VALUE_MAX];
-    property_get("ro.surface_flinger.supports_background_blur", value, "0");
-    if (!atoi(value)) {
-        // This device doesn't support blurs, no-op.
-        return;
-    }
-
     auto blurRadius = 50;
     auto center = DEFAULT_DISPLAY_WIDTH / 2;
 
@@ -959,9 +952,11 @@
     // solid color
     expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
 
-    // blurred color (downsampling should result in the center color being close to 128)
-    expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
-                      10 /* tolerance */);
+    if (mRE->supportsBackgroundBlur()) {
+        // blurred color (downsampling should result in the center color being close to 128)
+        expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
+                          10 /* tolerance */);
+    }
 }
 
 template <typename SourceVariant>
diff --git a/libs/renderengine/tests/RenderEngineThreadedTest.cpp b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
index 02ff06f..08b672a 100644
--- a/libs/renderengine/tests/RenderEngineThreadedTest.cpp
+++ b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
@@ -144,6 +144,17 @@
     ASSERT_EQ(true, result);
 }
 
+TEST_F(RenderEngineThreadedTest, supportsBackgroundBlur_returnsFalse) {
+    EXPECT_CALL(*mRenderEngine, supportsBackgroundBlur()).WillOnce(Return(false));
+    status_t result = mThreadedRE->supportsBackgroundBlur();
+    ASSERT_EQ(false, result);
+}
+
+TEST_F(RenderEngineThreadedTest, supportsBackgroundBlur_returnsTrue) {
+    EXPECT_CALL(*mRenderEngine, supportsBackgroundBlur()).WillOnce(Return(true));
+    status_t result = mThreadedRE->supportsBackgroundBlur();
+    ASSERT_EQ(true, result);
+}
 TEST_F(RenderEngineThreadedTest, drawLayers) {
     renderengine::DisplaySettings settings;
     std::vector<const renderengine::LayerSettings*> layers;
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp
index 3b97f56..f448135 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.cpp
+++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp
@@ -315,6 +315,21 @@
     return resultFuture.get();
 }
 
+bool RenderEngineThreaded::supportsBackgroundBlur() {
+    std::promise<bool> resultPromise;
+    std::future<bool> resultFuture = resultPromise.get_future();
+    {
+        std::lock_guard lock(mThreadMutex);
+        mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) {
+            ATRACE_NAME("REThreaded::supportsBackgroundBlur");
+            bool returnValue = instance.supportsBackgroundBlur();
+            resultPromise.set_value(returnValue);
+        });
+    }
+    mCondition.notify_one();
+    return resultFuture.get();
+}
+
 } // namespace threaded
 } // namespace renderengine
 } // namespace android
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.h b/libs/renderengine/threaded/RenderEngineThreaded.h
index 8b1e2de..8279cbc 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.h
+++ b/libs/renderengine/threaded/RenderEngineThreaded.h
@@ -64,6 +64,7 @@
 
     void cleanFramebufferCache() override;
     int getContextPriority() override;
+    bool supportsBackgroundBlur() override;
 
 private:
     void threadMain(CreateInstanceFactory factory);
diff --git a/libs/sensor/Android.bp b/libs/sensor/Android.bp
index e8154a6..497c33c 100644
--- a/libs/sensor/Android.bp
+++ b/libs/sensor/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libsensor",
 
diff --git a/libs/sensor/Sensor.cpp b/libs/sensor/Sensor.cpp
index 9d817ae..240738d 100644
--- a/libs/sensor/Sensor.cpp
+++ b/libs/sensor/Sensor.cpp
@@ -468,6 +468,19 @@
     mUuid.i64[1] = 0;
 }
 
+void Sensor::capMinDelayMicros(int32_t cappedMinDelay) {
+    if (mMinDelay < cappedMinDelay) {
+        mMinDelay = cappedMinDelay;
+    }
+}
+
+void Sensor::capHighestDirectReportRateLevel(int32_t cappedRateLevel) {
+    if (cappedRateLevel < getHighestDirectReportRateLevel()) {
+        mFlags &= ~SENSOR_FLAG_MASK_DIRECT_REPORT;
+        mFlags |= cappedRateLevel << SENSOR_FLAG_SHIFT_DIRECT_REPORT;
+    }
+}
+
 int32_t Sensor::getId() const {
     return int32_t(mUuid.i64[0]);
 }
diff --git a/libs/sensor/include/sensor/Sensor.h b/libs/sensor/include/sensor/Sensor.h
index 324d443..374b68f 100644
--- a/libs/sensor/include/sensor/Sensor.h
+++ b/libs/sensor/include/sensor/Sensor.h
@@ -104,6 +104,9 @@
     int32_t getId() const;
     void setId(int32_t id);
 
+    void capMinDelayMicros(int32_t cappedMinDelay);
+    void capHighestDirectReportRateLevel(int32_t cappedRateLevel);
+
     // LightFlattenable protocol
     inline bool isFixedSize() const { return false; }
     size_t getFlattenedSize() const;
diff --git a/libs/sensor/tests/Android.bp b/libs/sensor/tests/Android.bp
index c9a7668..8fdb003 100644
--- a/libs/sensor/tests/Android.bp
+++ b/libs/sensor/tests/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "libsensor_test",
 
diff --git a/libs/sensorprivacy/Android.bp b/libs/sensorprivacy/Android.bp
index 4a606ff..00514c4 100644
--- a/libs/sensorprivacy/Android.bp
+++ b/libs/sensorprivacy/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libsensorprivacy",
 
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 714ee3e..3b024be 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -12,6 +12,23 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["frameworks_native_libs_ui_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "frameworks_native_libs_ui_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 cc_defaults {
     name: "libui-defaults",
     clang: true,
@@ -77,7 +94,6 @@
         "libarect",
         "libmath",
     ],
-
 }
 
 cc_library_shared {
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index d005ce8..516aad8 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -14,6 +14,15 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_libs_ui_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_libs_ui_license"],
+}
+
 cc_test {
     name: "Region_test",
     shared_libs: ["libui"],
diff --git a/libs/ui/tools/Android.bp b/libs/ui/tools/Android.bp
index fb46c2b..c28c303 100644
--- a/libs/ui/tools/Android.bp
+++ b/libs/ui/tools/Android.bp
@@ -14,6 +14,15 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_libs_ui_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_libs_ui_license"],
+}
+
 cc_defaults {
     name: "libui_tools_default",
     clang_cflags: [
diff --git a/libs/vibrator/Android.bp b/libs/vibrator/Android.bp
index 49bc6bf..83c250a 100644
--- a/libs/vibrator/Android.bp
+++ b/libs/vibrator/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library {
     name: "libvibrator",
     vendor_available: true,
diff --git a/libs/vibrator/fuzzer/Android.bp b/libs/vibrator/fuzzer/Android.bp
index 8020151..f2a313c 100644
--- a/libs/vibrator/fuzzer/Android.bp
+++ b/libs/vibrator/fuzzer/Android.bp
@@ -17,6 +17,15 @@
  *****************************************************************************
  */
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_fuzz {
     name: "vibrator_fuzzer",
 
diff --git a/libs/vr/Android.bp b/libs/vr/Android.bp
index e8176cf..b308895 100644
--- a/libs/vr/Android.bp
+++ b/libs/vr/Android.bp
@@ -1,3 +1,14 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-BSD
+    //   legacy_notice
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 subdirs = [
     "*",
 ]
diff --git a/libs/vr/libbroadcastring/Android.bp b/libs/vr/libbroadcastring/Android.bp
index 13af470..2eb2f9f 100644
--- a/libs/vr/libbroadcastring/Android.bp
+++ b/libs/vr/libbroadcastring/Android.bp
@@ -1,3 +1,14 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_static {
     name: "libbroadcastring",
     clang: true,
diff --git a/libs/vr/libbufferhub/Android.bp b/libs/vr/libbufferhub/Android.bp
index 37c19d4..45bdd35 100644
--- a/libs/vr/libbufferhub/Android.bp
+++ b/libs/vr/libbufferhub/Android.bp
@@ -12,6 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_headers {
     name: "libbufferhub_headers",
     export_include_dirs: ["include"],
diff --git a/libs/vr/libbufferhubqueue/Android.bp b/libs/vr/libbufferhubqueue/Android.bp
index 77c7911..f372bd7 100644
--- a/libs/vr/libbufferhubqueue/Android.bp
+++ b/libs/vr/libbufferhubqueue/Android.bp
@@ -12,6 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 sourceFiles = [
     "buffer_hub_queue_client.cpp",
     "buffer_hub_queue_parcelable.cpp",
diff --git a/libs/vr/libbufferhubqueue/benchmarks/Android.bp b/libs/vr/libbufferhubqueue/benchmarks/Android.bp
index ef1eed6..fc1f376 100644
--- a/libs/vr/libbufferhubqueue/benchmarks/Android.bp
+++ b/libs/vr/libbufferhubqueue/benchmarks/Android.bp
@@ -1,4 +1,15 @@
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_benchmark {
     srcs: ["buffer_transport_benchmark.cpp"],
     shared_libs: [
diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp
index a337921..e883916 100644
--- a/libs/vr/libbufferhubqueue/tests/Android.bp
+++ b/libs/vr/libbufferhubqueue/tests/Android.bp
@@ -1,4 +1,15 @@
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 header_libraries = [
     "libdvr_headers",
 ]
diff --git a/libs/vr/libdisplay/Android.bp b/libs/vr/libdisplay/Android.bp
index 8c354fb..365a676 100644
--- a/libs/vr/libdisplay/Android.bp
+++ b/libs/vr/libdisplay/Android.bp
@@ -12,6 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 sourceFiles = [
     "display_client.cpp",
     "display_manager_client.cpp",
diff --git a/libs/vr/libdvr/Android.bp b/libs/vr/libdvr/Android.bp
index d5a19d3..83c30d7 100644
--- a/libs/vr/libdvr/Android.bp
+++ b/libs/vr/libdvr/Android.bp
@@ -13,6 +13,17 @@
 // limitations under the License.
 
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_headers {
     name: "libdvr_headers",
     export_include_dirs: ["include"],
diff --git a/libs/vr/libdvr/tests/Android.bp b/libs/vr/libdvr/tests/Android.bp
index 3260447..4ed80a4 100644
--- a/libs/vr/libdvr/tests/Android.bp
+++ b/libs/vr/libdvr/tests/Android.bp
@@ -12,6 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     srcs: [
         "dvr_display_manager-test.cpp",
diff --git a/libs/vr/libdvrcommon/Android.bp b/libs/vr/libdvrcommon/Android.bp
index e751768..9e1e516 100644
--- a/libs/vr/libdvrcommon/Android.bp
+++ b/libs/vr/libdvrcommon/Android.bp
@@ -12,6 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 localIncludeFiles = [
     "include",
 ]
diff --git a/libs/vr/libpdx/Android.bp b/libs/vr/libpdx/Android.bp
index 24ba830..c1f6da3 100644
--- a/libs/vr/libpdx/Android.bp
+++ b/libs/vr/libpdx/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_headers {
     name: "libpdx_headers",
     export_include_dirs: ["private"],
diff --git a/libs/vr/libpdx/fuzz/Android.bp b/libs/vr/libpdx/fuzz/Android.bp
index b36e0de..cc32b18 100644
--- a/libs/vr/libpdx/fuzz/Android.bp
+++ b/libs/vr/libpdx/fuzz/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_fuzz {
     name: "libpdx_service_dispatcher_fuzzer",
     clang: true,
diff --git a/libs/vr/libpdx_default_transport/Android.bp b/libs/vr/libpdx_default_transport/Android.bp
index b3534de..ea73d7a 100644
--- a/libs/vr/libpdx_default_transport/Android.bp
+++ b/libs/vr/libpdx_default_transport/Android.bp
@@ -1,3 +1,14 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
     name: "pdx_default_transport_compiler_defaults",
     clang: true,
@@ -75,4 +86,3 @@
         "libpdx_default_transport",
     ],
 }
-
diff --git a/libs/vr/libpdx_uds/Android.bp b/libs/vr/libpdx_uds/Android.bp
index 1d6eea2..532d1a7 100644
--- a/libs/vr/libpdx_uds/Android.bp
+++ b/libs/vr/libpdx_uds/Android.bp
@@ -1,3 +1,14 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_static {
     name: "libpdx_uds",
     clang: true,
diff --git a/libs/vr/libperformance/Android.bp b/libs/vr/libperformance/Android.bp
index 35d3dea..5beee35 100644
--- a/libs/vr/libperformance/Android.bp
+++ b/libs/vr/libperformance/Android.bp
@@ -12,6 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 sourceFiles = [
     "performance_client.cpp",
     "performance_rpc.cpp",
diff --git a/libs/vr/libvr_manager/Android.bp b/libs/vr/libvr_manager/Android.bp
index 2cd6a28..6f2ada4 100644
--- a/libs/vr/libvr_manager/Android.bp
+++ b/libs/vr/libvr_manager/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_static {
     name: "libvr_manager",
     srcs: [
diff --git a/libs/vr/libvrflinger/Android.bp b/libs/vr/libvrflinger/Android.bp
index abc64bd..8aca9a5 100644
--- a/libs/vr/libvrflinger/Android.bp
+++ b/libs/vr/libvrflinger/Android.bp
@@ -12,6 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 sourceFiles = [
     "acquired_buffer.cpp",
     "epoll_event_dispatcher.cpp",
diff --git a/libs/vr/libvrflinger/tests/Android.bp b/libs/vr/libvrflinger/tests/Android.bp
index 7fafd3b..dafd354 100644
--- a/libs/vr/libvrflinger/tests/Android.bp
+++ b/libs/vr/libvrflinger/tests/Android.bp
@@ -1,3 +1,14 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 shared_libs = [
     "android.hardware.configstore-utils",
     "android.hardware.configstore@1.0",
diff --git a/libs/vr/libvrsensor/Android.bp b/libs/vr/libvrsensor/Android.bp
index 8542790..8f566a0 100644
--- a/libs/vr/libvrsensor/Android.bp
+++ b/libs/vr/libvrsensor/Android.bp
@@ -12,6 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 sourceFiles = [
     "pose_client.cpp",
     "latency_model.cpp",
@@ -52,4 +63,3 @@
     header_libs: ["libdvr_headers"],
     name: "libvrsensor",
 }
-
diff --git a/opengl/Android.bp b/opengl/Android.bp
index 8b94f61..3878cb1 100644
--- a/opengl/Android.bp
+++ b/opengl/Android.bp
@@ -12,6 +12,18 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-BSD
+    //   SPDX-license-identifier-MIT
+    //   legacy_notice
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 ndk_headers {
     name: "libEGL_headers",
     from: "include",
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 5d17561..7861d62 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -1,4 +1,13 @@
 // Build the ETC1 library
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library {
     name: "libETC1",
     srcs: ["ETC1/etc1.cpp"],
diff --git a/opengl/tests/Android.bp b/opengl/tests/Android.bp
index 639f351..da717bd 100644
--- a/opengl/tests/Android.bp
+++ b/opengl/tests/Android.bp
@@ -1,4 +1,16 @@
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-BSD
+    //   SPDX-license-identifier-MIT
+    //   legacy_notice
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 subdirs = [
     "angeles",
     "configdump",
@@ -16,4 +28,3 @@
     "hwc",
     "lib",
 ]
-
diff --git a/opengl/tests/EGLTest/Android.bp b/opengl/tests/EGLTest/Android.bp
index e3912a8..51c9376 100644
--- a/opengl/tests/EGLTest/Android.bp
+++ b/opengl/tests/EGLTest/Android.bp
@@ -1,4 +1,13 @@
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
 
     name: "EGL_test",
diff --git a/opengl/tests/angeles/Android.bp b/opengl/tests/angeles/Android.bp
index 5c398a6..5b81501 100644
--- a/opengl/tests/angeles/Android.bp
+++ b/opengl/tests/angeles/Android.bp
@@ -1,5 +1,50 @@
 // Copyright 2006 The Android Open Source Project
 
+package {
+    default_applicable_licenses: [
+        "frameworks_native_opengl_tests_angeles_license",
+    ],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+//
+// large-scale-change included anything that looked like it might be a license
+// text as a license_text. e.g. LICENSE, NOTICE, COPYING etc.
+//
+// Please consider removing redundant or irrelevant files from 'license_text:'.
+//
+// large-scale-change filtered out the below license kinds as false-positives:
+//   SPDX-license-identifier-LGPL
+//   SPDX-license-identifier-LGPL-2.1
+//   SPDX-license-identifier-LGPL-3.0
+// See: http://go/android-license-faq
+license {
+    name: "frameworks_native_opengl_tests_angeles_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-BSD",
+        "SPDX-license-identifier-MIT",
+        "legacy_notice",
+    ],
+    license_text: [
+        "license-BSD.txt",
+        "license-LGPL.txt",
+        "license.txt",
+    ],
+}
+
 cc_test {
     name: "angeles",
 
diff --git a/opengl/tests/configdump/Android.bp b/opengl/tests/configdump/Android.bp
index ee967970..ffb0c1f 100644
--- a/opengl/tests/configdump/Android.bp
+++ b/opengl/tests/configdump/Android.bp
@@ -1,3 +1,14 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "test-opengl-configdump",
 
diff --git a/opengl/tests/fillrate/Android.bp b/opengl/tests/fillrate/Android.bp
index 689cee4..e4bff01 100644
--- a/opengl/tests/fillrate/Android.bp
+++ b/opengl/tests/fillrate/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "test-opengl-fillrate",
 
diff --git a/opengl/tests/filter/Android.bp b/opengl/tests/filter/Android.bp
index 23241e1..3b92b37 100644
--- a/opengl/tests/filter/Android.bp
+++ b/opengl/tests/filter/Android.bp
@@ -1,3 +1,14 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "test-opengl-filter",
 
diff --git a/opengl/tests/finish/Android.bp b/opengl/tests/finish/Android.bp
index be20851..c2dfbc3 100644
--- a/opengl/tests/finish/Android.bp
+++ b/opengl/tests/finish/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "test-opengl-finish",
 
diff --git a/opengl/tests/gl2_basic/Android.bp b/opengl/tests/gl2_basic/Android.bp
index f4538ad..c54bdf3 100644
--- a/opengl/tests/gl2_basic/Android.bp
+++ b/opengl/tests/gl2_basic/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "test-opengl-gl2_basic",
 
diff --git a/opengl/tests/gl2_cameraeye/Android.bp b/opengl/tests/gl2_cameraeye/Android.bp
index 00e00df..6b8ee85 100644
--- a/opengl/tests/gl2_cameraeye/Android.bp
+++ b/opengl/tests/gl2_cameraeye/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 android_app {
     name: "GL2CameraEye",
     // Only compile source java files in this apk.
diff --git a/opengl/tests/gl2_copyTexImage/Android.bp b/opengl/tests/gl2_copyTexImage/Android.bp
index 87fa7ea..0a84d25 100644
--- a/opengl/tests/gl2_copyTexImage/Android.bp
+++ b/opengl/tests/gl2_copyTexImage/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "test-opengl-gl2_copyTexImage",
 
diff --git a/opengl/tests/gl2_java/Android.bp b/opengl/tests/gl2_java/Android.bp
index a8e5d7d..a33075e 100644
--- a/opengl/tests/gl2_java/Android.bp
+++ b/opengl/tests/gl2_java/Android.bp
@@ -1,6 +1,15 @@
 //########################################################################
 // OpenGL ES 2.0 Java sample
 //########################################################################
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 android_app {
     name: "GL2Java",
     srcs: ["**/*.java"],
diff --git a/opengl/tests/gl2_jni/Android.bp b/opengl/tests/gl2_jni/Android.bp
index 8d4323f..79773cb 100644
--- a/opengl/tests/gl2_jni/Android.bp
+++ b/opengl/tests/gl2_jni/Android.bp
@@ -3,6 +3,15 @@
 // This makefile builds both an activity and a shared library.
 //########################################################################
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 android_app {
     name: "GL2JNI",
     srcs: ["**/*.java"],
diff --git a/opengl/tests/gl2_yuvtex/Android.bp b/opengl/tests/gl2_yuvtex/Android.bp
index b64d94d..fadf0e8 100644
--- a/opengl/tests/gl2_yuvtex/Android.bp
+++ b/opengl/tests/gl2_yuvtex/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "test-opengl-gl2_yuvtex",
 
diff --git a/opengl/tests/gl_basic/Android.bp b/opengl/tests/gl_basic/Android.bp
index 5eed17e..f777401 100644
--- a/opengl/tests/gl_basic/Android.bp
+++ b/opengl/tests/gl_basic/Android.bp
@@ -1,3 +1,14 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "test-opengl-gl_basic",
 
diff --git a/opengl/tests/gl_jni/Android.bp b/opengl/tests/gl_jni/Android.bp
index 0cb129a..dc46483 100644
--- a/opengl/tests/gl_jni/Android.bp
+++ b/opengl/tests/gl_jni/Android.bp
@@ -4,6 +4,15 @@
 //########################################################################
 // Build activity
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 android_app {
     name: "GLJNI",
     srcs: ["**/*.java"],
diff --git a/opengl/tests/gl_perf/Android.bp b/opengl/tests/gl_perf/Android.bp
index 25a317c..ca0f7e8 100644
--- a/opengl/tests/gl_perf/Android.bp
+++ b/opengl/tests/gl_perf/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "test-opengl-gl2_perf",
 
diff --git a/opengl/tests/gl_perfapp/Android.bp b/opengl/tests/gl_perfapp/Android.bp
index 66afb6a..2f62346 100644
--- a/opengl/tests/gl_perfapp/Android.bp
+++ b/opengl/tests/gl_perfapp/Android.bp
@@ -2,6 +2,15 @@
 // OpenGL ES Perf App
 // This makefile builds both an activity and a shared library.
 //########################################################################
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 android_app {
     name: "GLPerf",
     srcs: ["**/*.java"],
diff --git a/opengl/tests/gl_yuvtex/Android.bp b/opengl/tests/gl_yuvtex/Android.bp
index 9b4924a..7844186 100644
--- a/opengl/tests/gl_yuvtex/Android.bp
+++ b/opengl/tests/gl_yuvtex/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "test-opengl-gl_yuvtex",
 
diff --git a/opengl/tests/gldual/Android.bp b/opengl/tests/gldual/Android.bp
index 1006d44..3d6e677 100644
--- a/opengl/tests/gldual/Android.bp
+++ b/opengl/tests/gldual/Android.bp
@@ -4,6 +4,15 @@
 //########################################################################
 // Build activity
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 android_app {
     name: "GLDual",
     srcs: ["**/*.java"],
diff --git a/opengl/tests/gralloc/Android.bp b/opengl/tests/gralloc/Android.bp
index 33c3dba..5fb4556 100644
--- a/opengl/tests/gralloc/Android.bp
+++ b/opengl/tests/gralloc/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "test-opengl-gralloc",
 
diff --git a/opengl/tests/hwc/Android.bp b/opengl/tests/hwc/Android.bp
index 55f058f..719eb11 100644
--- a/opengl/tests/hwc/Android.bp
+++ b/opengl/tests/hwc/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
 
     name: "hwc_tests_defaults",
diff --git a/opengl/tests/lib/Android.bp b/opengl/tests/lib/Android.bp
index 2f6095d..05c9397 100644
--- a/opengl/tests/lib/Android.bp
+++ b/opengl/tests/lib/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_static {
 
     name: "libglTest",
diff --git a/opengl/tests/lighting1709/Android.bp b/opengl/tests/lighting1709/Android.bp
index e734dd1..79daa26 100644
--- a/opengl/tests/lighting1709/Android.bp
+++ b/opengl/tests/lighting1709/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 android_test {
     name: "LightingTest",
     srcs: ["**/*.java"],
diff --git a/opengl/tests/linetex/Android.bp b/opengl/tests/linetex/Android.bp
index dbc2cdb..61976e5 100644
--- a/opengl/tests/linetex/Android.bp
+++ b/opengl/tests/linetex/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_binary {
     name: "test-opengl-linetex",
     srcs: ["linetex.cpp"],
diff --git a/opengl/tests/swapinterval/Android.bp b/opengl/tests/swapinterval/Android.bp
index eed4dff..a76f4cf 100644
--- a/opengl/tests/swapinterval/Android.bp
+++ b/opengl/tests/swapinterval/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_binary {
     name: "test-opengl-swapinterval",
     srcs: ["swapinterval.cpp"],
diff --git a/opengl/tests/testFramerate/Android.bp b/opengl/tests/testFramerate/Android.bp
index 5aa83b0..4334d88 100644
--- a/opengl/tests/testFramerate/Android.bp
+++ b/opengl/tests/testFramerate/Android.bp
@@ -2,6 +2,15 @@
 // Test framerate and look for hiccups
 //########################################################################
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 android_app {
     name: "TestFramerate",
     srcs: ["**/*.java"],
diff --git a/opengl/tests/testLatency/Android.bp b/opengl/tests/testLatency/Android.bp
index c516dc3..473cb42 100644
--- a/opengl/tests/testLatency/Android.bp
+++ b/opengl/tests/testLatency/Android.bp
@@ -1,6 +1,15 @@
 //########################################################################
 // Test end-to-end latency.
 //########################################################################
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 android_app {
     name: "TestLatency",
     sdk_version: "8",
diff --git a/opengl/tests/testPauseResume/Android.bp b/opengl/tests/testPauseResume/Android.bp
index 810e895..8171e1f 100644
--- a/opengl/tests/testPauseResume/Android.bp
+++ b/opengl/tests/testPauseResume/Android.bp
@@ -1,4 +1,13 @@
 // OpenGL ES JNI sample
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 android_app {
     name: "TestEGL",
     srcs: ["**/*.java"],
diff --git a/opengl/tests/testViewport/Android.bp b/opengl/tests/testViewport/Android.bp
index 629b573..13ce3ad 100644
--- a/opengl/tests/testViewport/Android.bp
+++ b/opengl/tests/testViewport/Android.bp
@@ -2,6 +2,15 @@
 // OpenGL ES JNI sample
 // This makefile builds both an activity and a shared library.
 //########################################################################
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 android_app {
     name: "TestViewport",
     srcs: ["**/*.java"],
diff --git a/opengl/tests/textures/Android.bp b/opengl/tests/textures/Android.bp
index 84adda2..f113ff7 100644
--- a/opengl/tests/textures/Android.bp
+++ b/opengl/tests/textures/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_binary {
     name: "test-opengl-textures",
     srcs: ["textures.cpp"],
diff --git a/opengl/tests/tritex/Android.bp b/opengl/tests/tritex/Android.bp
index 390397b..759582c 100644
--- a/opengl/tests/tritex/Android.bp
+++ b/opengl/tests/tritex/Android.bp
@@ -1,3 +1,14 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_binary {
     name: "test-opengl-tritex",
     srcs: ["tritex.cpp"],
diff --git a/services/audiomanager/Android.bp b/services/audiomanager/Android.bp
index 12ad47e..e6fb2c3 100644
--- a/services/audiomanager/Android.bp
+++ b/services/audiomanager/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libaudiomanager",
 
diff --git a/services/automotive/display/Android.bp b/services/automotive/display/Android.bp
index c3da216..72bd292 100644
--- a/services/automotive/display/Android.bp
+++ b/services/automotive/display/Android.bp
@@ -14,6 +14,15 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_binary {
     name: "android.frameworks.automotive.display@1.0-service",
     defaults: ["hidl_defaults"],
diff --git a/services/batteryservice/Android.bp b/services/batteryservice/Android.bp
index 66ee8ff..1e37991 100644
--- a/services/batteryservice/Android.bp
+++ b/services/batteryservice/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_headers {
     name: "libbatteryservice_headers",
     vendor_available: true,
diff --git a/services/displayservice/Android.bp b/services/displayservice/Android.bp
index 4d2d873..8681784 100644
--- a/services/displayservice/Android.bp
+++ b/services/displayservice/Android.bp
@@ -14,6 +14,15 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libdisplayservicehidl",
 
diff --git a/services/gpuservice/Android.bp b/services/gpuservice/Android.bp
index 9a9bca1..b9b6a19 100644
--- a/services/gpuservice/Android.bp
+++ b/services/gpuservice/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
     name: "gpuservice_defaults",
     cflags: [
diff --git a/services/gpuservice/bpfprogs/Android.bp b/services/gpuservice/bpfprogs/Android.bp
index b875814..9842ed7 100644
--- a/services/gpuservice/bpfprogs/Android.bp
+++ b/services/gpuservice/bpfprogs/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 bpf {
     name: "gpu_mem.o",
     srcs: ["gpu_mem.c"],
diff --git a/services/gpuservice/gpumem/Android.bp b/services/gpuservice/gpumem/Android.bp
index b2230b6..830e53d 100644
--- a/services/gpuservice/gpumem/Android.bp
+++ b/services/gpuservice/gpumem/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libgpumem",
     srcs: [
diff --git a/services/gpuservice/gpustats/Android.bp b/services/gpuservice/gpustats/Android.bp
index f52602a..54291ad 100644
--- a/services/gpuservice/gpustats/Android.bp
+++ b/services/gpuservice/gpustats/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libgfxstats",
     srcs: [
diff --git a/services/gpuservice/tests/unittests/Android.bp b/services/gpuservice/tests/unittests/Android.bp
index 9606daa..6d87c45 100644
--- a/services/gpuservice/tests/unittests/Android.bp
+++ b/services/gpuservice/tests/unittests/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "gpuservice_unittest",
     test_suites: ["device-tests"],
diff --git a/services/gpuservice/tracing/Android.bp b/services/gpuservice/tracing/Android.bp
index 919fed3..a1bc1ed 100644
--- a/services/gpuservice/tracing/Android.bp
+++ b/services/gpuservice/tracing/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libgpumemtracer",
     srcs: [
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index b640e9c..9b98a17 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -13,6 +13,15 @@
 // limitations under the License.
 
 // Default flags to be used throughout all libraries in inputflinger.
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
     name: "inputflinger_defaults",
     cflags: [
diff --git a/services/inputflinger/benchmarks/Android.bp b/services/inputflinger/benchmarks/Android.bp
index bd275a7..ea37f4d 100644
--- a/services/inputflinger/benchmarks/Android.bp
+++ b/services/inputflinger/benchmarks/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_benchmark {
     name: "inputflinger_benchmarks",
     srcs: [
diff --git a/services/inputflinger/dispatcher/Android.bp b/services/inputflinger/dispatcher/Android.bp
index e5b131e..393f649 100644
--- a/services/inputflinger/dispatcher/Android.bp
+++ b/services/inputflinger/dispatcher/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_headers {
     name: "libinputdispatcher_headers",
     export_include_dirs: [
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index e4237b5..9898e9d 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -1673,9 +1673,7 @@
 
     if (!mKeyIsWaitingForEventsTimeout.has_value()) {
         // Start the timer
-        ALOGD("Waiting to send key to %s because there are unprocessed events that may cause "
-              "focus to change",
-              focusedWindowName);
+        // Wait to send key because there are unprocessed events that may cause focus to change
         mKeyIsWaitingForEventsTimeout = currentTime +
                 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
                         .count();
@@ -2834,10 +2832,6 @@
  * This includes situations like the soft BACK button key. When the user releases (lifts up the
  * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
  * Both of those ACTION_UP events would not be logged
- * Monitors (both gesture and global): any gesture monitors or global monitors receiving events
- * will not be logged. This is omitted to reduce the amount of data printed.
- * If you see <none>, it's likely that one of the gesture monitors pilfered the event, and therefore
- * gesture monitor is the only connection receiving the remainder of the gesture.
  */
 void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
                                                     const std::vector<InputTarget>& targets) {
@@ -2867,8 +2861,8 @@
 
         sp<IBinder> token = target.inputChannel->getConnectionToken();
         sp<Connection> connection = getConnectionLocked(token);
-        if (connection == nullptr || connection->monitor) {
-            continue; // We only need to keep track of the non-monitor connections.
+        if (connection == nullptr) {
+            continue;
         }
         newConnectionTokens.insert(std::move(token));
         newConnections.emplace_back(connection);
@@ -2878,12 +2872,12 @@
     }
     mInteractionConnectionTokens = newConnectionTokens;
 
-    std::string windowList;
+    std::string targetList;
     for (const sp<Connection>& connection : newConnections) {
-        windowList += connection->getWindowName() + ", ";
+        targetList += connection->getWindowName() + ", ";
     }
-    std::string message = "Interaction with windows: " + windowList;
-    if (windowList.empty()) {
+    std::string message = "Interaction with: " + targetList;
+    if (targetList.empty()) {
         message += "<none>";
     }
     android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
@@ -3221,8 +3215,7 @@
             }
         } else {
             // Monitor channels are never explicitly unregistered.
-            // We do it automatically when the remote endpoint is closed so don't warn
-            // about them.
+            // We do it automatically when the remote endpoint is closed so don't warn about them.
             const bool stillHaveWindowHandle =
                     d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
                     nullptr;
@@ -4978,7 +4971,7 @@
                                                    bool notify) {
     sp<Connection> connection = getConnectionLocked(connectionToken);
     if (connection == nullptr) {
-        ALOGW("Attempted to unregister already unregistered input channel");
+        // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
         return BAD_VALUE;
     }
 
@@ -5042,9 +5035,11 @@
         }
 
         TouchState& state = stateIt->second;
+        std::shared_ptr<InputChannel> requestingChannel;
         std::optional<int32_t> foundDeviceId;
         for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
             if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
+                requestingChannel = touchedMonitor.monitor.inputChannel;
                 foundDeviceId = state.deviceId;
             }
         }
@@ -5060,13 +5055,19 @@
                                    "gesture monitor stole pointer stream");
         options.deviceId = deviceId;
         options.displayId = displayId;
+        std::string canceledWindows = "[";
         for (const TouchedWindow& window : state.windows) {
             std::shared_ptr<InputChannel> channel =
                     getInputChannelLocked(window.windowHandle->getToken());
             if (channel != nullptr) {
                 synthesizeCancelationEventsForInputChannelLocked(channel, options);
+                canceledWindows += channel->getName() + ", ";
             }
         }
+        canceledWindows += "]";
+        ALOGI("Monitor %s is stealing touch from %s", requestingChannel->getName().c_str(),
+              canceledWindows.c_str());
+
         // Then clear the current touch state so we stop dispatching to them as well.
         state.filterNonMonitors();
     }
diff --git a/services/inputflinger/host/Android.bp b/services/inputflinger/host/Android.bp
index 9e797e4..18d0226 100644
--- a/services/inputflinger/host/Android.bp
+++ b/services/inputflinger/host/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libinputflingerhost",
 
diff --git a/services/inputflinger/reader/Android.bp b/services/inputflinger/reader/Android.bp
index 7f979f2..518e295 100644
--- a/services/inputflinger/reader/Android.bp
+++ b/services/inputflinger/reader/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_headers {
     name: "libinputreader_headers",
     export_include_dirs: [
diff --git a/services/inputflinger/reporter/Android.bp b/services/inputflinger/reporter/Android.bp
index fbc51da..7430731 100644
--- a/services/inputflinger/reporter/Android.bp
+++ b/services/inputflinger/reporter/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_headers {
     name: "libinputreporter_headers",
     export_include_dirs: ["."],
@@ -46,4 +55,3 @@
         "libinputreporter_headers",
     ],
 }
-
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp
index 959dadc..42b54c7 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "inputflinger_tests",
     defaults: [
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 01945db..209639c 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -31,6 +31,7 @@
 using android::base::StringPrintf;
 using android::os::InputEventInjectionResult;
 using android::os::InputEventInjectionSync;
+using android::os::TouchOcclusionMode;
 using namespace android::flag_operators;
 
 namespace android::inputdispatcher {
@@ -727,8 +728,9 @@
         ASSERT_EQ(OK, status) << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
     }
 
-    void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
-                      int32_t expectedFlags) {
+    void consumeEvent(int32_t expectedEventType, int32_t expectedAction,
+                      std::optional<int32_t> expectedDisplayId,
+                      std::optional<int32_t> expectedFlags) {
         InputEvent* event = consume();
 
         ASSERT_NE(nullptr, event) << mName.c_str()
@@ -737,19 +739,25 @@
                 << mName.c_str() << " expected " << inputEventTypeToString(expectedEventType)
                 << " event, got " << inputEventTypeToString(event->getType()) << " event";
 
-        EXPECT_EQ(expectedDisplayId, event->getDisplayId());
+        if (expectedDisplayId.has_value()) {
+            EXPECT_EQ(expectedDisplayId, event->getDisplayId());
+        }
 
         switch (expectedEventType) {
             case AINPUT_EVENT_TYPE_KEY: {
                 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*event);
                 EXPECT_EQ(expectedAction, keyEvent.getAction());
-                EXPECT_EQ(expectedFlags, keyEvent.getFlags());
+                if (expectedFlags.has_value()) {
+                    EXPECT_EQ(expectedFlags.value(), keyEvent.getFlags());
+                }
                 break;
             }
             case AINPUT_EVENT_TYPE_MOTION: {
                 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
                 EXPECT_EQ(expectedAction, motionEvent.getAction());
-                EXPECT_EQ(expectedFlags, motionEvent.getFlags());
+                if (expectedFlags.has_value()) {
+                    EXPECT_EQ(expectedFlags.value(), motionEvent.getFlags());
+                }
                 break;
             }
             case AINPUT_EVENT_TYPE_FOCUS: {
@@ -854,6 +862,7 @@
         mInfo.name = name;
         mInfo.type = InputWindowInfo::Type::APPLICATION;
         mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
+        mInfo.alpha = 1.0;
         mInfo.frameLeft = 0;
         mInfo.frameTop = 0;
         mInfo.frameRight = WIDTH;
@@ -883,6 +892,12 @@
 
     void setPaused(bool paused) { mInfo.paused = paused; }
 
+    void setAlpha(float alpha) { mInfo.alpha = alpha; }
+
+    void setTouchOcclusionMode(android::os::TouchOcclusionMode mode) {
+        mInfo.touchOcclusionMode = mode;
+    }
+
     void setFrame(const Rect& frame) {
         mInfo.frameLeft = frame.left;
         mInfo.frameTop = frame.top;
@@ -928,6 +943,11 @@
 
     void consumeMotionDown(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
                            int32_t expectedFlags = 0) {
+        consumeAnyMotionDown(expectedDisplayId, expectedFlags);
+    }
+
+    void consumeAnyMotionDown(std::optional<int32_t> expectedDisplayId = std::nullopt,
+                              std::optional<int32_t> expectedFlags = std::nullopt) {
         consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN, expectedDisplayId,
                      expectedFlags);
     }
@@ -971,8 +991,9 @@
         mInputReceiver->consumeCaptureEvent(hasCapture);
     }
 
-    void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
-                      int32_t expectedFlags) {
+    void consumeEvent(int32_t expectedEventType, int32_t expectedAction,
+                      std::optional<int32_t> expectedDisplayId,
+                      std::optional<int32_t> expectedFlags) {
         ASSERT_NE(mInputReceiver, nullptr) << "Invalid consume event on window with no receiver";
         mInputReceiver->consumeEvent(expectedEventType, expectedAction, expectedDisplayId,
                                      expectedFlags);
@@ -4240,4 +4261,264 @@
     mSecondWindow->consumeCaptureEvent(true);
 }
 
+class InputDispatcherUntrustedTouchesTest : public InputDispatcherTest {
+protected:
+    constexpr static const float MAXIMUM_OBSCURING_OPACITY = 0.8;
+    static const int32_t TOUCHED_APP_UID = 10001;
+    static const int32_t APP_B_UID = 10002;
+    static const int32_t APP_C_UID = 10003;
+
+    sp<FakeWindowHandle> mTouchWindow;
+
+    virtual void SetUp() override {
+        InputDispatcherTest::SetUp();
+        mTouchWindow = getWindow(TOUCHED_APP_UID, "Touched");
+        mDispatcher->setBlockUntrustedTouchesMode(android::os::BlockUntrustedTouchesMode::BLOCK);
+        mDispatcher->setMaximumObscuringOpacityForTouch(MAXIMUM_OBSCURING_OPACITY);
+    }
+
+    virtual void TearDown() override {
+        InputDispatcherTest::TearDown();
+        mTouchWindow.clear();
+    }
+
+    sp<FakeWindowHandle> getOccludingWindow(int32_t uid, std::string name,
+                                            os::TouchOcclusionMode mode, float alpha = 1.0f) {
+        sp<FakeWindowHandle> window = getWindow(uid, name);
+        window->setFlags(InputWindowInfo::Flag::NOT_TOUCHABLE);
+        window->setTouchOcclusionMode(mode);
+        window->setAlpha(alpha);
+        return window;
+    }
+
+    sp<FakeWindowHandle> getWindow(int32_t uid, std::string name) {
+        std::shared_ptr<FakeApplicationHandle> app = std::make_shared<FakeApplicationHandle>();
+        sp<FakeWindowHandle> window =
+                new FakeWindowHandle(app, mDispatcher, name, ADISPLAY_ID_DEFAULT);
+        // Generate an arbitrary PID based on the UID
+        window->setOwnerInfo(1777 + (uid % 10000), uid);
+        return window;
+    }
+
+    void touch(const std::vector<PointF>& points = {PointF{100, 200}}) {
+        NotifyMotionArgs args =
+                generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
+                                   ADISPLAY_ID_DEFAULT, points);
+        mDispatcher->notifyMotion(&args);
+    }
+};
+
+TEST_F(InputDispatcherUntrustedTouchesTest, WindowWithBlockUntrustedOcclusionMode_BlocksTouch) {
+    const sp<FakeWindowHandle>& w =
+            getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::BLOCK_UNTRUSTED);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->assertNoEvents();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest, WindowWithAllowOcclusionMode_AllowsTouch) {
+    const sp<FakeWindowHandle>& w = getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::ALLOW);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->consumeAnyMotionDown();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest, TouchOutsideOccludingWindow_AllowsTouch) {
+    const sp<FakeWindowHandle>& w =
+            getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::BLOCK_UNTRUSTED);
+    w->setFrame(Rect(0, 0, 50, 50));
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
+
+    touch({PointF{100, 100}});
+
+    mTouchWindow->consumeAnyMotionDown();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest, WindowFromSameUid_AllowsTouch) {
+    const sp<FakeWindowHandle>& w =
+            getOccludingWindow(TOUCHED_APP_UID, "A", TouchOcclusionMode::BLOCK_UNTRUSTED);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->consumeAnyMotionDown();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest, WindowWithZeroOpacity_AllowsTouch) {
+    const sp<FakeWindowHandle>& w =
+            getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::BLOCK_UNTRUSTED, 0.0f);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->consumeAnyMotionDown();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest, WindowWithOpacityBelowThreshold_AllowsTouch) {
+    const sp<FakeWindowHandle>& w =
+            getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::USE_OPACITY, 0.7f);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->consumeAnyMotionDown();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest, WindowWithOpacityAtThreshold_AllowsTouch) {
+    const sp<FakeWindowHandle>& w =
+            getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::USE_OPACITY,
+                               MAXIMUM_OBSCURING_OPACITY);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->consumeAnyMotionDown();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest, WindowWithOpacityAboveThreshold_BlocksTouch) {
+    const sp<FakeWindowHandle>& w =
+            getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::USE_OPACITY, 0.9f);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->assertNoEvents();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest, WindowsWithCombinedOpacityAboveThreshold_BlocksTouch) {
+    // Resulting opacity = 1 - (1 - 0.7)*(1 - 0.7) = .91
+    const sp<FakeWindowHandle>& w1 =
+            getOccludingWindow(APP_B_UID, "B1", TouchOcclusionMode::USE_OPACITY, 0.7f);
+    const sp<FakeWindowHandle>& w2 =
+            getOccludingWindow(APP_B_UID, "B2", TouchOcclusionMode::USE_OPACITY, 0.7f);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w1, w2, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->assertNoEvents();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest, WindowsWithCombinedOpacityBelowThreshold_AllowsTouch) {
+    // Resulting opacity = 1 - (1 - 0.5)*(1 - 0.5) = .75
+    const sp<FakeWindowHandle>& w1 =
+            getOccludingWindow(APP_B_UID, "B1", TouchOcclusionMode::USE_OPACITY, 0.5f);
+    const sp<FakeWindowHandle>& w2 =
+            getOccludingWindow(APP_B_UID, "B2", TouchOcclusionMode::USE_OPACITY, 0.5f);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w1, w2, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->consumeAnyMotionDown();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest,
+       WindowsFromDifferentAppsEachBelowThreshold_AllowsTouch) {
+    const sp<FakeWindowHandle>& wB =
+            getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::USE_OPACITY, 0.7f);
+    const sp<FakeWindowHandle>& wC =
+            getOccludingWindow(APP_C_UID, "C", TouchOcclusionMode::USE_OPACITY, 0.7f);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {wB, wC, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->consumeAnyMotionDown();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest, WindowsFromDifferentAppsOneAboveThreshold_BlocksTouch) {
+    const sp<FakeWindowHandle>& wB =
+            getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::USE_OPACITY, 0.7f);
+    const sp<FakeWindowHandle>& wC =
+            getOccludingWindow(APP_C_UID, "C", TouchOcclusionMode::USE_OPACITY, 0.9f);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {wB, wC, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->assertNoEvents();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest,
+       WindowWithOpacityAboveThresholdAndSelfWindow_BlocksTouch) {
+    const sp<FakeWindowHandle>& wA =
+            getOccludingWindow(TOUCHED_APP_UID, "T", TouchOcclusionMode::USE_OPACITY, 0.7f);
+    const sp<FakeWindowHandle>& wB =
+            getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::USE_OPACITY, 0.9f);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {wA, wB, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->assertNoEvents();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest,
+       WindowWithOpacityBelowThresholdAndSelfWindow_AllowsTouch) {
+    const sp<FakeWindowHandle>& wA =
+            getOccludingWindow(TOUCHED_APP_UID, "T", TouchOcclusionMode::USE_OPACITY, 0.9f);
+    const sp<FakeWindowHandle>& wB =
+            getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::USE_OPACITY, 0.7f);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {wA, wB, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->consumeAnyMotionDown();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest, SelfWindowWithOpacityAboveThreshold_AllowsTouch) {
+    const sp<FakeWindowHandle>& w =
+            getOccludingWindow(TOUCHED_APP_UID, "T", TouchOcclusionMode::USE_OPACITY, 0.9f);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->consumeAnyMotionDown();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest, SelfWindowWithBlockUntrustedMode_AllowsTouch) {
+    const sp<FakeWindowHandle>& w =
+            getOccludingWindow(TOUCHED_APP_UID, "T", TouchOcclusionMode::BLOCK_UNTRUSTED);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->consumeAnyMotionDown();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest,
+       OpacityThresholdIs0AndWindowAboveThreshold_BlocksTouch) {
+    mDispatcher->setMaximumObscuringOpacityForTouch(0.0f);
+    const sp<FakeWindowHandle>& w =
+            getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::USE_OPACITY, 0.1f);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->assertNoEvents();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest, OpacityThresholdIs0AndWindowAtThreshold_AllowsTouch) {
+    mDispatcher->setMaximumObscuringOpacityForTouch(0.0f);
+    const sp<FakeWindowHandle>& w =
+            getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::USE_OPACITY, 0.0f);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->consumeAnyMotionDown();
+}
+
+TEST_F(InputDispatcherUntrustedTouchesTest,
+       OpacityThresholdIs1AndWindowBelowThreshold_AllowsTouch) {
+    mDispatcher->setMaximumObscuringOpacityForTouch(1.0f);
+    const sp<FakeWindowHandle>& w =
+            getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::USE_OPACITY, 0.9f);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
+
+    touch();
+
+    mTouchWindow->consumeAnyMotionDown();
+}
+
 } // namespace android::inputdispatcher
diff --git a/services/powermanager/Android.bp b/services/powermanager/Android.bp
index 68f4f28..1d3e5b5 100644
--- a/services/powermanager/Android.bp
+++ b/services/powermanager/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libpowermanager",
 
diff --git a/services/schedulerservice/Android.bp b/services/schedulerservice/Android.bp
index 73802db..4ef72d0 100644
--- a/services/schedulerservice/Android.bp
+++ b/services/schedulerservice/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libschedulerservicehidl",
     srcs: [
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index 532a2e5..ca9ff7c 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 subdirs = [
     "hidl"
 ]
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 2810bff..23893ea 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -914,6 +914,21 @@
     return mActivationCount.valueAt(activationIndex).numActiveClients() > 0;
 }
 
+void SensorDevice::onMicSensorAccessChanged(void* ident, int handle, nsecs_t samplingPeriodNs) {
+    Mutex::Autolock _l(mLock);
+    ssize_t activationIndex = mActivationCount.indexOfKey(handle);
+    if (activationIndex < 0) {
+        ALOGW("Handle %d cannot be found in activation record", handle);
+        return;
+    }
+    Info& info(mActivationCount.editValueAt(activationIndex));
+    if (info.hasBatchParamsForIdent(ident)) {
+        ssize_t index = info.batchParams.indexOfKey(ident);
+        BatchParams& params = info.batchParams.editValueAt(index);
+        params.mTSample = samplingPeriodNs;
+    }
+}
+
 void SensorDevice::enableAllSensors() {
     if (mSensors == nullptr) return;
     Mutex::Autolock _l(mLock);
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 5e7d3da..75da7bb 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -125,6 +125,10 @@
 
     bool isSensorActive(int handle) const;
 
+    // To update the BatchParams of a SensorEventConnection when the mic toggle changes its state
+    // while the Sensors Off toggle is on.
+    void onMicSensorAccessChanged(void* ident, int handle, nsecs_t samplingPeriodNs);
+
     // Dumpable
     virtual std::string dump() const override;
     virtual void dump(util::ProtoOutputStream* proto) const override;
diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp
index e4c33da..af86d09 100644
--- a/services/sensorservice/SensorDirectConnection.cpp
+++ b/services/sensorservice/SensorDirectConnection.cpp
@@ -32,6 +32,8 @@
         : mService(service), mUid(uid), mMem(*mem),
         mHalChannelHandle(halChannelHandle),
         mOpPackageName(opPackageName), mDestroyed(false) {
+    mIsRateCappedBasedOnPermission = mService->isRateCappedBasedOnPermission(mOpPackageName);
+    mUserId = multiuser_get_user_id(mUid);
     ALOGD_IF(DEBUG_CONNECTIONS, "Created SensorDirectConnection");
 }
 
@@ -101,6 +103,14 @@
     }
 }
 
+void SensorService::SensorDirectConnection::onMicSensorAccessChanged(bool isMicToggleOn) {
+    if (isMicToggleOn) {
+        capRates();
+    } else {
+        uncapRates();
+    }
+}
+
 bool SensorService::SensorDirectConnection::hasSensorAccess() const {
     return mService->hasSensorAccess(mUid, mOpPackageName);
 }
@@ -134,6 +144,7 @@
 
     if (handle == -1 && rateLevel == SENSOR_DIRECT_RATE_STOP) {
         stopAll();
+        mMicRateBackup.clear();
         return NO_ERROR;
     }
 
@@ -157,6 +168,14 @@
         return INVALID_OPERATION;
     }
 
+    int requestedRateLevel = rateLevel;
+    if (mService->isSensorInCappedSet(s.getType()) && rateLevel != SENSOR_DIRECT_RATE_STOP) {
+        status_t err = mService->adjustRateLevelBasedOnMicAndPermission(&rateLevel, mOpPackageName);
+        if (err != OK) {
+            return err;
+        }
+    }
+
     struct sensors_direct_cfg_t config = {
         .rate_level = rateLevel
     };
@@ -168,18 +187,100 @@
     if (rateLevel == SENSOR_DIRECT_RATE_STOP) {
         if (ret == NO_ERROR) {
             mActivated.erase(handle);
+            mMicRateBackup.erase(handle);
         } else if (ret > 0) {
             ret = UNKNOWN_ERROR;
         }
     } else {
         if (ret > 0) {
             mActivated[handle] = rateLevel;
+            if (mService->isSensorInCappedSet(s.getType())) {
+                // Back up the rates that the app is allowed to have if the mic toggle is off
+                // This is used in the uncapRates() function.
+                if (!mIsRateCappedBasedOnPermission ||
+                            requestedRateLevel <= SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL) {
+                    mMicRateBackup[handle] = requestedRateLevel;
+                } else {
+                    mMicRateBackup[handle] = SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL;
+                }
+            }
         }
     }
 
     return ret;
 }
 
+void SensorService::SensorDirectConnection::capRates() {
+    Mutex::Autolock _l(mConnectionLock);
+    const struct sensors_direct_cfg_t capConfig = {
+        .rate_level = SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL
+    };
+
+    const struct sensors_direct_cfg_t stopConfig = {
+        .rate_level = SENSOR_DIRECT_RATE_STOP
+    };
+
+    // If our requests are in the backup, then we shouldn't activate sensors from here
+    bool temporarilyStopped = mActivated.empty() && !mActivatedBackup.empty();
+    std::unordered_map<int, int>& existingConnections =
+                    (!temporarilyStopped) ? mActivated : mActivatedBackup;
+
+    SensorDevice& dev(SensorDevice::getInstance());
+    for (auto &i : existingConnections) {
+        int handle = i.first;
+        int rateLevel = i.second;
+        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
+        if (si != nullptr) {
+            const Sensor& s = si->getSensor();
+            if (mService->isSensorInCappedSet(s.getType()) &&
+                        rateLevel > SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL) {
+                mMicRateBackup[handle] = rateLevel;
+                // Modify the rate kept by the existing map
+                existingConnections[handle] = SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL;
+                // Only reconfigure the channel if it's ongoing
+                if (!temporarilyStopped) {
+                    // Stopping before reconfiguring is the well-tested path in CTS
+                    dev.configureDirectChannel(handle, getHalChannelHandle(), &stopConfig);
+                    dev.configureDirectChannel(handle, getHalChannelHandle(), &capConfig);
+                }
+            }
+        }
+    }
+}
+
+void SensorService::SensorDirectConnection::uncapRates() {
+    Mutex::Autolock _l(mConnectionLock);
+
+    // If our requests are in the backup, then we shouldn't activate sensors from here
+    bool temporarilyStopped = mActivated.empty() && !mActivatedBackup.empty();
+    std::unordered_map<int, int>& existingConnections =
+                    (!temporarilyStopped) ? mActivated : mActivatedBackup;
+
+    const struct sensors_direct_cfg_t stopConfig = {
+        .rate_level = SENSOR_DIRECT_RATE_STOP
+    };
+    SensorDevice& dev(SensorDevice::getInstance());
+    for (auto &i : mMicRateBackup) {
+        int handle = i.first;
+        int rateLevel = i.second;
+
+        const struct sensors_direct_cfg_t config = {
+            .rate_level = rateLevel
+        };
+
+        // Modify the rate kept by the existing map
+        existingConnections[handle] = rateLevel;
+
+        // Only reconfigure the channel if it's ongoing
+        if (!temporarilyStopped) {
+            // Stopping before reconfiguring is the well-tested path in CTS
+            dev.configureDirectChannel(handle, getHalChannelHandle(), &stopConfig);
+            dev.configureDirectChannel(handle, getHalChannelHandle(), &config);
+        }
+    }
+    mMicRateBackup.clear();
+}
+
 void SensorService::SensorDirectConnection::stopAll(bool backupRecord) {
     Mutex::Autolock _l(mConnectionLock);
     stopAllLocked(backupRecord);
diff --git a/services/sensorservice/SensorDirectConnection.h b/services/sensorservice/SensorDirectConnection.h
index 4181b65..a3f348b 100644
--- a/services/sensorservice/SensorDirectConnection.h
+++ b/services/sensorservice/SensorDirectConnection.h
@@ -50,6 +50,8 @@
     // regained due to changes in the sensor restricted/privacy mode or the
     // app changed to idle/active status.
     void onSensorAccessChanged(bool hasAccess);
+    void onMicSensorAccessChanged(bool isMicToggleOn);
+    userid_t getUserId() const { return mUserId; }
 
 protected:
     virtual ~SensorDirectConnection();
@@ -82,6 +84,11 @@
     // If no requests are backed up by stopAll(), this method is no-op.
     void recoverAll();
 
+    // Limits all active sensor direct report requests when the mic toggle is flipped to on.
+    void capRates();
+    // Recover sensor requests previously capped by capRates().
+    void uncapRates();
+
     const sp<SensorService> mService;
     const uid_t mUid;
     const sensors_direct_mem_t mMem;
@@ -91,9 +98,12 @@
     mutable Mutex mConnectionLock;
     std::unordered_map<int, int> mActivated;
     std::unordered_map<int, int> mActivatedBackup;
+    std::unordered_map<int, int> mMicRateBackup;
 
+    std::atomic_bool mIsRateCappedBasedOnPermission;
     mutable Mutex mDestroyLock;
     bool mDestroyed;
+    userid_t mUserId;
 };
 
 } // namepsace android
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index 6810c1b7..a2e7f23 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -44,6 +44,8 @@
       mCacheSize(0), mMaxCacheSize(0), mTimeOfLastEventDrop(0), mEventsDropped(0),
       mPackageName(packageName), mOpPackageName(opPackageName), mTargetSdk(kTargetSdkUnknown),
       mDestroyed(false) {
+    mIsRateCappedBasedOnPermission = mService->isRateCappedBasedOnPermission(mOpPackageName);
+    mUserId = multiuser_get_user_id(mUid);
     mChannel = new BitTube(mService->mSocketBufferSize);
 #if DEBUG_CONNECTIONS
     mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
@@ -285,6 +287,29 @@
     }
 }
 
+// TODO(b/179649922): A better algorithm to guarantee that capped connections will get a sampling
+// rate close to 200 Hz. With the current algorithm, apps might be punished unfairly: E.g.,two apps
+// make requests to the sensor service at the same time, one is not capped and uses 250 Hz, and one
+//is capped, the capped connection will only get 125 Hz.
+void SensorService::SensorEventConnection::addSensorEventsToBuffer(bool shouldResample,
+    const sensors_event_t& sensorEvent, sensors_event_t* buffer, int* index) {
+    if (!shouldResample || !mService->isSensorInCappedSet(sensorEvent.type)) {
+        buffer[(*index)++] = sensorEvent;
+    } else {
+        int64_t lastTimestamp = -1;
+        auto entry = mSensorLastTimestamp.find(sensorEvent.sensor);
+        if (entry != mSensorLastTimestamp.end()) {
+            lastTimestamp = entry->second;
+        }
+        // Allow 10% headroom here because the clocks are not perfect.
+        if (lastTimestamp == -1  || sensorEvent.timestamp - lastTimestamp
+                                        >= 0.9 * SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS) {
+            mSensorLastTimestamp[sensorEvent.sensor] = sensorEvent.timestamp;
+            buffer[(*index)++] = sensorEvent;
+        }
+    }
+}
+
 status_t SensorService::SensorEventConnection::sendEvents(
         sensors_event_t const* buffer, size_t numEvents,
         sensors_event_t* scratch,
@@ -293,6 +318,8 @@
 
     std::unique_ptr<sensors_event_t[]> sanitizedBuffer;
 
+    bool shouldResample = mService->isMicSensorPrivacyEnabledForUid(mUid) ||
+                            mIsRateCappedBasedOnPermission;
     int count = 0;
     Mutex::Autolock _l(mConnectionLock);
     if (scratch) {
@@ -346,7 +373,7 @@
                     // Regular sensor event, just copy it to the scratch buffer after checking
                     // the AppOp.
                     if (hasSensorAccess() && noteOpIfRequired(buffer[i])) {
-                        scratch[count++] = buffer[i];
+                        addSensorEventsToBuffer(shouldResample, buffer[i], scratch, &count);
                     }
                 }
                 i++;
@@ -356,12 +383,13 @@
                                         buffer[i].meta_data.sensor == sensor_handle)));
         }
     } else {
+        sanitizedBuffer.reset(new sensors_event_t[numEvents]);
+        scratch = sanitizedBuffer.get();
         if (hasSensorAccess()) {
-            scratch = const_cast<sensors_event_t *>(buffer);
-            count = numEvents;
+            for (size_t i = 0; i < numEvents; i++) {
+                addSensorEventsToBuffer(shouldResample, buffer[i], scratch, &count);
+            }
         } else {
-            sanitizedBuffer.reset(new sensors_event_t[numEvents]);
-            scratch = sanitizedBuffer.get();
             for (size_t i = 0; i < numEvents; i++) {
                 if (buffer[i].type == SENSOR_TYPE_META_DATA) {
                     scratch[count++] = buffer[i++];
@@ -684,24 +712,118 @@
 
     status_t err;
     if (enabled) {
+        nsecs_t requestedSamplingPeriodNs = samplingPeriodNs;
+        bool isSensorCapped = false;
+        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
+        if (si != nullptr) {
+            const Sensor& s = si->getSensor();
+            if (mService->isSensorInCappedSet(s.getType())) {
+                isSensorCapped = true;
+            }
+        }
+        if (isSensorCapped) {
+            err = mService->adjustSamplingPeriodBasedOnMicAndPermission(&samplingPeriodNs,
+                                String16(mOpPackageName));
+            if (err != OK) {
+                return err;
+            }
+        }
         err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
                                reservedFlags, mOpPackageName);
+        if (err == OK && isSensorCapped) {
+            if (!mIsRateCappedBasedOnPermission ||
+                        requestedSamplingPeriodNs >= SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS) {
+                mMicSamplingPeriodBackup[handle] = requestedSamplingPeriodNs;
+            } else {
+                mMicSamplingPeriodBackup[handle] = SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS;
+            }
+        }
 
     } else {
         err = mService->disable(this, handle);
+        mMicSamplingPeriodBackup.erase(handle);
     }
     return err;
 }
 
-status_t SensorService::SensorEventConnection::setEventRate(
-        int handle, nsecs_t samplingPeriodNs)
-{
+status_t SensorService::SensorEventConnection::setEventRate(int handle, nsecs_t samplingPeriodNs) {
     if (mDestroyed) {
         android_errorWriteLog(0x534e4554, "168211968");
         return DEAD_OBJECT;
     }
 
-    return mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
+    nsecs_t requestedSamplingPeriodNs = samplingPeriodNs;
+    bool isSensorCapped = false;
+    sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
+    if (si != nullptr) {
+        const Sensor& s = si->getSensor();
+        if (mService->isSensorInCappedSet(s.getType())) {
+            isSensorCapped = true;
+        }
+    }
+    if (isSensorCapped) {
+        status_t err = mService->adjustSamplingPeriodBasedOnMicAndPermission(&samplingPeriodNs,
+                            String16(mOpPackageName));
+        if (err != OK) {
+            return err;
+        }
+    }
+    status_t ret = mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
+    if (ret == OK && isSensorCapped) {
+        if (!mIsRateCappedBasedOnPermission ||
+                    requestedSamplingPeriodNs >= SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS) {
+            mMicSamplingPeriodBackup[handle] = requestedSamplingPeriodNs;
+        } else {
+            mMicSamplingPeriodBackup[handle] = SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS;
+        }
+    }
+    return ret;
+}
+
+void SensorService::SensorEventConnection::onMicSensorAccessChanged(bool isMicToggleOn) {
+    if (isMicToggleOn) {
+        capRates();
+    } else {
+        uncapRates();
+    }
+}
+
+void SensorService::SensorEventConnection::capRates() {
+    Mutex::Autolock _l(mConnectionLock);
+    SensorDevice& dev(SensorDevice::getInstance());
+    for (auto &i : mMicSamplingPeriodBackup) {
+        int handle = i.first;
+        nsecs_t samplingPeriodNs = i.second;
+        if (samplingPeriodNs < SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS) {
+            if (hasSensorAccess()) {
+                mService->setEventRate(this, handle, SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS,
+                                       mOpPackageName);
+            } else {
+                // Update SensorDevice with the capped rate so that when sensor access is restored,
+                // the correct event rate is used.
+                dev.onMicSensorAccessChanged(this, handle,
+                                             SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS);
+            }
+        }
+    }
+}
+
+void SensorService::SensorEventConnection::uncapRates() {
+    Mutex::Autolock _l(mConnectionLock);
+    SensorDevice& dev(SensorDevice::getInstance());
+    for (auto &i : mMicSamplingPeriodBackup) {
+        int handle = i.first;
+        nsecs_t samplingPeriodNs = i.second;
+        if (samplingPeriodNs < SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS) {
+            if (hasSensorAccess()) {
+                mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
+            } else {
+                // Update SensorDevice with the uncapped rate so that when sensor access is
+                // restored, the correct event rate is used.
+                dev.onMicSensorAccessChanged(this, handle, samplingPeriodNs);
+            }
+        }
+    }
 }
 
 status_t  SensorService::SensorEventConnection::flush() {
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index 9487a39..7bd9d47 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -68,6 +68,9 @@
     String8 getPackageName() const;
 
     uid_t getUid() const { return mUid; }
+    // cap/uncap existing connection depending on the state of the mic toggle.
+    void onMicSensorAccessChanged(bool isMicToggleOn);
+    userid_t getUserId() const { return mUserId; }
 
 private:
     virtual ~SensorEventConnection();
@@ -137,10 +140,20 @@
 
     // Call noteOp for the sensor if the sensor requires a permission
     bool noteOpIfRequired(const sensors_event_t& event);
+    // Limits all active connections when the mic toggle is flipped to on.
+    void capRates();
+    // Recover sensor connection previously capped by capRates().
+    void uncapRates();
 
+    // Add sensorEvent to buffer at position index if the sensorEvent satisfies throttling rules.
+    void addSensorEventsToBuffer(bool shouldResample, const sensors_event_t& sensorEvent,
+                        sensors_event_t* buffer, int* index);
     sp<SensorService> const mService;
     sp<BitTube> mChannel;
     uid_t mUid;
+    std::atomic_bool mIsRateCappedBasedOnPermission;
+    // Store a mapping of sensor to the timestamp of their last sensor event.
+    std::unordered_map<int, int64_t> mSensorLastTimestamp;
     mutable Mutex mConnectionLock;
     // Number of events from wake up sensors which are still pending and haven't been delivered to
     // the corresponding application. It is incremented by one unit for each write to the socket.
@@ -189,6 +202,9 @@
     // Store a mapping of sensor handles to required AppOp for a sensor. This map only contains a
     // valid mapping for sensors that require a permission in order to reduce the lookup time.
     std::unordered_map<int32_t, int32_t> mHandleToAppOp;
+    // Mapping of sensor handles to its rate before being capped by the mic toggle.
+    std::unordered_map<int, nsecs_t> mMicSamplingPeriodBackup;
+    userid_t mUserId;
 };
 
 } // namepsace android
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 8f25bdb..89d1c42 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <android-base/strings.h>
 #include <android/content/pm/IPackageManagerNative.h>
 #include <android/util/ProtoOutputStream.h>
 #include <frameworks/base/core/proto/android/service/sensor_service.proto.h>
@@ -88,6 +89,8 @@
 #define SENSOR_SERVICE_SCHED_FIFO_PRIORITY 10
 
 // Permissions.
+static const String16 sAccessHighSensorSamplingRatePermission(
+        "android.permission.HIGH_SAMPLING_RATE_SENSORS");
 static const String16 sDumpPermission("android.permission.DUMP");
 static const String16 sLocationHardwarePermission("android.permission.LOCATION_HARDWARE");
 static const String16 sManageSensorsPermission("android.permission.MANAGE_SENSORS");
@@ -366,6 +369,9 @@
     }
     mUidPolicy->unregisterSelf();
     mSensorPrivacyPolicy->unregisterSelf();
+    for (auto const& [userId, policy] : mMicSensorPrivacyPolicies) {
+        policy->unregisterSelf();
+    }
 }
 
 status_t SensorService::dump(int fd, const Vector<String16>& args) {
@@ -695,6 +701,35 @@
     }
 }
 
+void SensorService::capRates(userid_t userId) {
+    ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
+    for (const sp<SensorDirectConnection>& conn : connLock.getDirectConnections()) {
+        if (conn->getUserId() == userId) {
+            conn->onMicSensorAccessChanged(true);
+        }
+    }
+
+    for (const sp<SensorEventConnection>& conn : connLock.getActiveConnections()) {
+        if (conn->getUserId() == userId) {
+            conn->onMicSensorAccessChanged(true);
+        }
+    }
+}
+
+void SensorService::uncapRates(userid_t userId) {
+    ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
+    for (const sp<SensorDirectConnection>& conn : connLock.getDirectConnections()) {
+        if (conn->getUserId() == userId) {
+            conn->onMicSensorAccessChanged(false);
+        }
+    }
+
+    for (const sp<SensorEventConnection>& conn : connLock.getActiveConnections()) {
+        if (conn->getUserId() == userId) {
+            conn->onMicSensorAccessChanged(false);
+        }
+    }
+}
 
 // NOTE: This is a remote API - make sure all args are validated
 status_t SensorService::shellCommand(int in, int out, int err, Vector<String16>& args) {
@@ -1209,14 +1244,20 @@
     }
 }
 
-Vector<Sensor> SensorService::getSensorList(const String16& /* opPackageName */) {
+Vector<Sensor> SensorService::getSensorList(const String16& opPackageName) {
     char value[PROPERTY_VALUE_MAX];
     property_get("debug.sensors", value, "0");
     const Vector<Sensor>& initialSensorList = (atoi(value)) ?
             mSensors.getUserDebugSensors() : mSensors.getUserSensors();
     Vector<Sensor> accessibleSensorList;
+
+    bool isCapped = isRateCappedBasedOnPermission(opPackageName);
     for (size_t i = 0; i < initialSensorList.size(); i++) {
         Sensor sensor = initialSensorList[i];
+        if (isCapped && isSensorInCappedSet(sensor.getType())) {
+            sensor.capMinDelayMicros(SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS / 1000);
+            sensor.capHighestDirectReportRateLevel(SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL);
+        }
         accessibleSensorList.add(sensor);
     }
     makeUuidsIntoIdsForSensorList(accessibleSensorList);
@@ -2024,6 +2065,69 @@
     return mUidPolicy->isUidActive(uid);
 }
 
+bool SensorService::isRateCappedBasedOnPermission(const String16& opPackageName) {
+    int targetSdk = getTargetSdkVersion(opPackageName);
+    bool hasSamplingRatePermission = PermissionCache::checkCallingPermission(
+                    sAccessHighSensorSamplingRatePermission);
+    if (targetSdk < __ANDROID_API_S__ ||
+            (targetSdk >= __ANDROID_API_S__ && hasSamplingRatePermission)) {
+        return false;
+    }
+    return true;
+}
+
+bool SensorService::isSensorInCappedSet(int sensorType) {
+    return (sensorType == SENSOR_TYPE_ACCELEROMETER
+            || sensorType == SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED
+            || sensorType == SENSOR_TYPE_GYROSCOPE
+            || sensorType == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED
+            || sensorType == SENSOR_TYPE_MAGNETIC_FIELD
+            || sensorType == SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED);
+}
+
+status_t SensorService::adjustSamplingPeriodBasedOnMicAndPermission(nsecs_t* requestedPeriodNs,
+        const String16& opPackageName) {
+    uid_t uid = IPCThreadState::self()->getCallingUid();
+    bool shouldCapBasedOnPermission = isRateCappedBasedOnPermission(opPackageName);
+    if (*requestedPeriodNs >= SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS) {
+        return OK;
+    }
+    if (shouldCapBasedOnPermission) {
+        *requestedPeriodNs = SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS;
+        if (isPackageDebuggable(opPackageName)) {
+            return PERMISSION_DENIED;
+        }
+        return OK;
+    }
+    if (isMicSensorPrivacyEnabledForUid(uid)) {
+        *requestedPeriodNs = SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS;
+        return OK;
+    }
+    return OK;
+}
+
+status_t SensorService::adjustRateLevelBasedOnMicAndPermission(int* requestedRateLevel,
+        const String16& opPackageName) {
+    uid_t uid = IPCThreadState::self()->getCallingUid();
+    bool shouldCapBasedOnPermission = isRateCappedBasedOnPermission(opPackageName);
+
+    if (*requestedRateLevel <= SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL) {
+        return OK;
+    }
+    if (shouldCapBasedOnPermission) {
+        *requestedRateLevel = SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL;
+        if (isPackageDebuggable(opPackageName)) {
+            return PERMISSION_DENIED;
+        }
+        return OK;
+    }
+    if (isMicSensorPrivacyEnabledForUid(uid)) {
+        *requestedRateLevel = SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL;
+        return OK;
+    }
+    return OK;
+}
+
 void SensorService::SensorPrivacyPolicy::registerSelf() {
     SensorPrivacyManager spm;
     mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
@@ -2042,16 +2146,56 @@
 binder::Status SensorService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool enabled) {
     mSensorPrivacyEnabled = enabled;
     sp<SensorService> service = mService.promote();
+
     if (service != nullptr) {
-        if (enabled) {
-            service->disableAllSensors();
+        if (mIsIndividualMic) {
+            if (enabled) {
+                service->capRates(mUserId);
+            } else {
+                service->uncapRates(mUserId);
+            }
         } else {
-            service->enableAllSensors();
+            if (enabled) {
+                service->disableAllSensors();
+            } else {
+                service->enableAllSensors();
+            }
         }
     }
     return binder::Status::ok();
 }
 
+status_t SensorService::SensorPrivacyPolicy::registerSelfForIndividual(int userId) {
+    Mutex::Autolock _l(mSensorPrivacyLock);
+
+    SensorPrivacyManager spm;
+    status_t err = spm.addIndividualSensorPrivacyListener(userId,
+            SensorPrivacyManager::INDIVIDUAL_SENSOR_MICROPHONE, this);
+
+    if (err != OK) {
+        ALOGE("Cannot register a mic listener.");
+        return err;
+    }
+    mSensorPrivacyEnabled = spm.isIndividualSensorPrivacyEnabled(userId,
+                SensorPrivacyManager::INDIVIDUAL_SENSOR_MICROPHONE);
+
+    mIsIndividualMic = true;
+    mUserId = userId;
+    return OK;
+}
+
+bool SensorService::isMicSensorPrivacyEnabledForUid(uid_t uid) {
+    userid_t userId = multiuser_get_user_id(uid);
+    if (mMicSensorPrivacyPolicies.find(userId) == mMicSensorPrivacyPolicies.end()) {
+        sp<SensorPrivacyPolicy> userPolicy = new SensorPrivacyPolicy(this);
+        if (userPolicy->registerSelfForIndividual(userId) != OK) {
+            return false;
+        }
+        mMicSensorPrivacyPolicies[userId] = userPolicy;
+    }
+    return mMicSensorPrivacyPolicies[userId]->isSensorPrivacyEnabled();
+}
+
 SensorService::ConnectionSafeAutolock::ConnectionSafeAutolock(
         SensorService::SensorConnectionHolder& holder, Mutex& mutex)
         : mConnectionHolder(holder), mAutolock(mutex) {}
@@ -2109,4 +2253,17 @@
     return ConnectionSafeAutolock(*this, mutex);
 }
 
+bool SensorService::isPackageDebuggable(const String16& opPackageName) {
+    bool debugMode = false;
+    sp<IBinder> binder = defaultServiceManager()->getService(String16("package_native"));
+    if (binder != nullptr) {
+        sp<content::pm::IPackageManagerNative> packageManager =
+                interface_cast<content::pm::IPackageManagerNative>(binder);
+        if (packageManager != nullptr) {
+            binder::Status status = packageManager->isPackageDebuggable(
+                opPackageName, &debugMode);
+        }
+    }
+    return debugMode;
+}
 } // namespace android
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 50c7c2f..5b198d8 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -61,6 +61,15 @@
 
 #define SENSOR_REGISTRATIONS_BUF_SIZE 200
 
+// Apps that targets S+ and do not have HIGH_SAMPLING_RATE_SENSORS permission will be capped
+// at 200 Hz. The cap also applies to all requests when the mic toggle is flipped to on, regardless
+// of their target SDKs and permission.
+// Capped sampling periods for apps that have non-direct sensor connections.
+#define SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS (5 * 1000 * 1000)
+// Capped sampling rate level for apps that have direct sensor connections.
+// The enum SENSOR_DIRECT_RATE_NORMAL corresponds to a rate value of at most 110 Hz.
+#define SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL SENSOR_DIRECT_RATE_NORMAL
+
 namespace android {
 // ---------------------------------------------------------------------------
 class SensorInterface;
@@ -95,6 +104,8 @@
     status_t flushSensor(const sp<SensorEventConnection>& connection,
                          const String16& opPackageName);
 
+    // Returns true if a sensor should be throttled according to our rate-throttling rules.
+    static bool isSensorInCappedSet(int sensorType);
 
     virtual status_t shellCommand(int in, int out, int err, Vector<String16>& args);
 
@@ -212,17 +223,23 @@
     // connections will be allowed again.
     class SensorPrivacyPolicy : public hardware::BnSensorPrivacyListener {
         public:
-            explicit SensorPrivacyPolicy(wp<SensorService> service) : mService(service) {}
+            explicit SensorPrivacyPolicy(wp<SensorService> service)
+                    : mService(service), mIsIndividualMic(false), mUserId(0) {}
             void registerSelf();
             void unregisterSelf();
 
+            status_t registerSelfForIndividual(int userId);
+
             bool isSensorPrivacyEnabled();
 
             binder::Status onSensorPrivacyChanged(bool enabled);
 
         private:
             wp<SensorService> mService;
+            Mutex mSensorPrivacyLock;
             std::atomic_bool mSensorPrivacyEnabled;
+            bool mIsIndividualMic;
+            userid_t mUserId;
     };
 
     enum Mode {
@@ -346,6 +363,13 @@
     // whitelisted). mLock must be held to invoke this method.
     bool isOperationRestrictedLocked(const String16& opPackageName);
 
+    status_t adjustSamplingPeriodBasedOnMicAndPermission(nsecs_t* requestedPeriodNs,
+                                                    const String16& opPackageName);
+    status_t adjustRateLevelBasedOnMicAndPermission(int* requestedRateLevel,
+                                              const String16& opPackageName);
+    bool isRateCappedBasedOnPermission(const String16& opPackageName);
+    bool isPackageDebuggable(const String16& opPackageName);
+
     // Reset the state of SensorService to NORMAL mode.
     status_t resetToNormalMode();
     status_t resetToNormalModeLocked();
@@ -385,6 +409,11 @@
     void enableAllSensors();
     void enableAllSensorsLocked(ConnectionSafeAutolock* connLock);
 
+    // Caps active direct connections (when the mic toggle is flipped to on)
+    void capRates(userid_t userId);
+    // Removes the capped rate on active direct connections (when the mic toggle is flipped to off)
+    void uncapRates(userid_t userId);
+
     static uint8_t sHmacGlobalKey[128];
     static bool sHmacGlobalKeyIsValid;
 
@@ -426,6 +455,11 @@
     static std::map<String16, int> sPackageTargetVersion;
     static Mutex sPackageTargetVersionLock;
     static String16 sSensorInterfaceDescriptorPrefix;
+
+    // Map from user to SensorPrivacyPolicy
+    std::map<userid_t, sp<SensorPrivacyPolicy>> mMicSensorPrivacyPolicies;
+    // Checks if the mic sensor privacy is enabled for the uid
+    bool isMicSensorPrivacyEnabledForUid(uid_t uid);
 };
 
 } // namespace android
diff --git a/services/sensorservice/hidl/Android.bp b/services/sensorservice/hidl/Android.bp
index 0e1af59..9bafb3c 100644
--- a/services/sensorservice/hidl/Android.bp
+++ b/services/sensorservice/hidl/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libsensorservicehidl",
     srcs: [
diff --git a/services/sensorservice/tests/Android.bp b/services/sensorservice/tests/Android.bp
index d33c0ca..ddc03a1 100644
--- a/services/sensorservice/tests/Android.bp
+++ b/services/sensorservice/tests/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_binary {
     name: "test-sensorservice",
     srcs: ["sensorservicetest.cpp"],
diff --git a/services/stats/Android.bp b/services/stats/Android.bp
index 1ce0524..58e5993 100644
--- a/services/stats/Android.bp
+++ b/services/stats/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libstatshidl",
     srcs: [
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 8d1258a..c39c983 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
     name: "surfaceflinger_defaults",
     cflags: [
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 579130a..f30e1eb 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -236,10 +236,6 @@
 bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) {
     mCurrentStateModified = mCurrentState.modified;
     bool stateUpdateAvailable = Layer::applyPendingStates(stateToCommit);
-    if (stateUpdateAvailable && mCallbackHandleAcquireTime != -1) {
-        // Update the acquire fence time if we have a buffer
-        mSurfaceFrame->setAcquireFenceTime(mCallbackHandleAcquireTime);
-    }
     mCurrentStateModified = stateUpdateAvailable && mCurrentStateModified;
     mCurrentState.modified = false;
     return stateUpdateAvailable;
@@ -612,11 +608,12 @@
 }
 
 std::optional<nsecs_t> BufferStateLayer::nextPredictedPresentTime() const {
-    if (!getDrawingState().isAutoTimestamp || !mSurfaceFrame) {
+    const State& drawingState(getDrawingState());
+    if (!drawingState.isAutoTimestamp || !drawingState.bufferSurfaceFrameTX) {
         return std::nullopt;
     }
 
-    return mSurfaceFrame->getPredictions().presentTime;
+    return drawingState.bufferSurfaceFrameTX->getPredictions().presentTime;
 }
 
 status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime,
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index 57dc60b..50bc5ed 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
     name: "libcompositionengine_defaults",
     defaults: ["surfaceflinger_defaults"],
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index eb0c724..da04202 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -30,6 +30,7 @@
 
 using base::StringAppendF;
 using FrameTimelineEvent = perfetto::protos::pbzero::FrameTimelineEvent;
+using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
 
 void dumpTable(std::string& result, TimelineItem predictions, TimelineItem actuals,
                const std::string& indent, PredictionState predictionState, nsecs_t baseTime) {
@@ -305,11 +306,17 @@
     std::scoped_lock lock(mMutex);
     mActualQueueTime = actualQueueTime;
 }
+
 void SurfaceFrame::setAcquireFenceTime(nsecs_t acquireFenceTime) {
     std::scoped_lock lock(mMutex);
     mActuals.endTime = std::max(acquireFenceTime, mActualQueueTime);
 }
 
+void SurfaceFrame::setDropTime(nsecs_t dropTime) {
+    std::scoped_lock lock(mMutex);
+    mDropTime = dropTime;
+}
+
 void SurfaceFrame::setPresentState(PresentState presentState, nsecs_t lastLatchTime) {
     std::scoped_lock lock(mMutex);
     LOG_ALWAYS_FATAL_IF(mPresentState != PresentState::Unknown,
@@ -327,7 +334,12 @@
 
 std::optional<int32_t> SurfaceFrame::getJankType() const {
     std::scoped_lock lock(mMutex);
+    if (mPresentState == PresentState::Dropped) {
+        // Return no jank if it's a dropped frame since we cannot attribute a jank to a it.
+        return JankType::None;
+    }
     if (mActuals.presentTime == 0) {
+        // Frame hasn't been presented yet.
         return std::nullopt;
     }
     return mJankType;
@@ -343,6 +355,11 @@
     return mActuals;
 }
 
+PredictionState SurfaceFrame::getPredictionState() const {
+    std::scoped_lock lock(mMutex);
+    return mPredictionState;
+}
+
 SurfaceFrame::PresentState SurfaceFrame::getPresentState() const {
     std::scoped_lock lock(mMutex);
     return mPresentState;
@@ -358,6 +375,11 @@
     return mFrameReadyMetadata;
 }
 
+nsecs_t SurfaceFrame::getDropTime() const {
+    std::scoped_lock lock(mMutex);
+    return mDropTime;
+}
+
 void SurfaceFrame::dump(std::string& result, const std::string& indent, nsecs_t baseTime) const {
     std::scoped_lock lock(mMutex);
     StringAppendF(&result, "%s", indent.c_str());
@@ -377,6 +399,12 @@
     StringAppendF(&result, "%s", indent.c_str());
     StringAppendF(&result, "Present State : %s\n", toString(mPresentState).c_str());
     StringAppendF(&result, "%s", indent.c_str());
+    if (mPresentState == PresentState::Dropped) {
+        std::chrono::nanoseconds dropTime(mDropTime - baseTime);
+        StringAppendF(&result, "Drop time : %10f\n",
+                      std::chrono::duration<double, std::milli>(dropTime).count());
+        StringAppendF(&result, "%s", indent.c_str());
+    }
     StringAppendF(&result, "Prediction State : %s\n", toString(mPredictionState).c_str());
     StringAppendF(&result, "%s", indent.c_str());
     StringAppendF(&result, "Jank Type : %s\n", jankTypeBitmaskToString(mJankType).c_str());
@@ -500,27 +528,12 @@
                                       displayDeadlineDelta, displayPresentDelta, deadlineDelta});
 }
 
-/**
- * TODO(b/178637512): add inputEventId to the perfetto trace.
- */
-void SurfaceFrame::trace(int64_t displayFrameToken) {
-    using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
-
+void SurfaceFrame::tracePredictions(int64_t displayFrameToken) const {
     int64_t expectedTimelineCookie = mTraceCookieCounter.getCookieForTracing();
-    bool missingToken = false;
+
     // Expected timeline start
     FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) {
         std::scoped_lock lock(mMutex);
-        if (mToken == FrameTimelineInfo::INVALID_VSYNC_ID) {
-            ALOGD("Cannot trace SurfaceFrame - %s with invalid token", mLayerName.c_str());
-            missingToken = true;
-            return;
-        } else if (displayFrameToken == FrameTimelineInfo::INVALID_VSYNC_ID) {
-            ALOGD("Cannot trace SurfaceFrame  - %s with invalid displayFrameToken",
-                  mLayerName.c_str());
-            missingToken = true;
-            return;
-        }
         auto packet = ctx.NewTracePacket();
         packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
         packet->set_timestamp(static_cast<uint64_t>(mPredictions.startTime));
@@ -537,12 +550,6 @@
         expectedSurfaceFrameStartEvent->set_layer_name(mDebugName);
     });
 
-    if (missingToken) {
-        // If one packet can't be traced because of missing token, then no packets can be traced.
-        // Exit early in this case.
-        return;
-    }
-
     // Expected timeline end
     FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) {
         std::scoped_lock lock(mMutex);
@@ -555,15 +562,26 @@
 
         expectedSurfaceFrameEndEvent->set_cookie(expectedTimelineCookie);
     });
+}
 
+void SurfaceFrame::traceActuals(int64_t displayFrameToken) const {
     int64_t actualTimelineCookie = mTraceCookieCounter.getCookieForTracing();
+
     // Actual timeline start
     FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) {
         std::scoped_lock lock(mMutex);
         auto packet = ctx.NewTracePacket();
         packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
         // Actual start time is not yet available, so use expected start instead
-        packet->set_timestamp(static_cast<uint64_t>(mPredictions.startTime));
+        if (mPredictionState == PredictionState::Expired) {
+            // If prediction is expired, we can't use the predicted start time. Instead, just use a
+            // start time a little earlier than the end time so that we have some info about this
+            // frame in the trace.
+            packet->set_timestamp(
+                    static_cast<uint64_t>(mActuals.endTime - kPredictionExpiredStartTimeDelta));
+        } else {
+            packet->set_timestamp(static_cast<uint64_t>(mPredictions.startTime));
+        }
 
         auto* event = packet->set_frame_timeline_event();
         auto* actualSurfaceFrameStartEvent = event->set_actual_surface_frame_start();
@@ -588,12 +606,17 @@
         actualSurfaceFrameStartEvent->set_gpu_composition(mGpuComposition);
         actualSurfaceFrameStartEvent->set_jank_type(jankTypeBitmaskToProto(mJankType));
     });
+
     // Actual timeline end
     FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) {
         std::scoped_lock lock(mMutex);
         auto packet = ctx.NewTracePacket();
         packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
-        packet->set_timestamp(static_cast<uint64_t>(mActuals.endTime));
+        if (mPresentState == PresentState::Dropped) {
+            packet->set_timestamp(static_cast<uint64_t>(mDropTime));
+        } else {
+            packet->set_timestamp(static_cast<uint64_t>(mActuals.endTime));
+        }
 
         auto* event = packet->set_frame_timeline_event();
         auto* actualSurfaceFrameEndEvent = event->set_frame_end();
@@ -602,6 +625,23 @@
     });
 }
 
+/**
+ * TODO(b/178637512): add inputEventId to the perfetto trace.
+ */
+void SurfaceFrame::trace(int64_t displayFrameToken) const {
+    if (mToken == FrameTimelineInfo::INVALID_VSYNC_ID ||
+        displayFrameToken == FrameTimelineInfo::INVALID_VSYNC_ID) {
+        // No packets can be traced with a missing token.
+        return;
+    }
+    if (getPredictionState() != PredictionState::Expired) {
+        // Expired predictions have zeroed timestamps. This cannot be used in any meaningful way in
+        // a trace.
+        tracePredictions(displayFrameToken);
+    }
+    traceActuals(displayFrameToken);
+}
+
 namespace impl {
 
 int64_t TokenManager::generateTokenForPredictions(TimelineItem&& predictions) {
@@ -750,6 +790,11 @@
 
 void FrameTimeline::DisplayFrame::onPresent(nsecs_t signalTime) {
     mSurfaceFlingerActuals.presentTime = signalTime;
+    if (mPredictionState == PredictionState::Expired) {
+        // Cannot do jank classification with expired predictions
+        mJankType = JankType::Unknown;
+        return;
+    }
 
     // Delta between the expected present and the actual present
     const nsecs_t presentDelta =
@@ -836,17 +881,12 @@
     }
 }
 
-void FrameTimeline::DisplayFrame::trace(pid_t surfaceFlingerPid) const {
+void FrameTimeline::DisplayFrame::tracePredictions(pid_t surfaceFlingerPid) const {
     int64_t expectedTimelineCookie = mTraceCookieCounter.getCookieForTracing();
-    bool missingToken = false;
+
     // Expected timeline start
     FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) {
         auto packet = ctx.NewTracePacket();
-        if (mToken == FrameTimelineInfo::INVALID_VSYNC_ID) {
-            ALOGD("Cannot trace DisplayFrame with invalid token");
-            missingToken = true;
-            return;
-        }
         packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
         packet->set_timestamp(static_cast<uint64_t>(mSurfaceFlingerPredictions.startTime));
 
@@ -859,12 +899,6 @@
         expectedDisplayFrameStartEvent->set_pid(surfaceFlingerPid);
     });
 
-    if (missingToken) {
-        // If one packet can't be traced because of missing token, then no packets can be traced.
-        // Exit early in this case.
-        return;
-    }
-
     // Expected timeline end
     FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) {
         auto packet = ctx.NewTracePacket();
@@ -876,9 +910,12 @@
 
         expectedDisplayFrameEndEvent->set_cookie(expectedTimelineCookie);
     });
+}
 
+void FrameTimeline::DisplayFrame::traceActuals(pid_t surfaceFlingerPid) const {
     int64_t actualTimelineCookie = mTraceCookieCounter.getCookieForTracing();
-    // Expected timeline start
+
+    // Actual timeline start
     FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) {
         auto packet = ctx.NewTracePacket();
         packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
@@ -898,7 +935,8 @@
         actualDisplayFrameStartEvent->set_gpu_composition(mGpuComposition);
         actualDisplayFrameStartEvent->set_jank_type(jankTypeBitmaskToProto(mJankType));
     });
-    // Expected timeline end
+
+    // Actual timeline end
     FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) {
         auto packet = ctx.NewTracePacket();
         packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
@@ -909,6 +947,21 @@
 
         actualDisplayFrameEndEvent->set_cookie(actualTimelineCookie);
     });
+}
+
+void FrameTimeline::DisplayFrame::trace(pid_t surfaceFlingerPid) const {
+    if (mToken == FrameTimelineInfo::INVALID_VSYNC_ID) {
+        // DisplayFrame should not have an invalid token.
+        ALOGE("Cannot trace DisplayFrame with invalid token");
+        return;
+    }
+
+    if (mPredictionState == PredictionState::Valid) {
+        // Expired and unknown predictions have zeroed timestamps. This cannot be used in any
+        // meaningful way in a trace.
+        tracePredictions(surfaceFlingerPid);
+    }
+    traceActuals(surfaceFlingerPid);
 
     for (auto& surfaceFrame : mSurfaceFrames) {
         surfaceFrame->trace(mToken);
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.h b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
index 4739106..8f3157d 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.h
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
@@ -171,10 +171,12 @@
     TimelineItem getPredictions() const { return mPredictions; };
     // Actual timestamps of the app are set individually at different functions.
     // Start time (if the app provides) and Queue time are accessible after queueing the frame,
-    // whereas Acquire Fence time is available only during latch.
+    // whereas Acquire Fence time is available only during latch. Drop time is available at the time
+    // the buffer was dropped.
     void setActualStartTime(nsecs_t actualStartTime);
     void setActualQueueTime(nsecs_t actualQueueTime);
     void setAcquireFenceTime(nsecs_t acquireFenceTime);
+    void setDropTime(nsecs_t dropTime);
     void setPresentState(PresentState presentState, nsecs_t lastLatchTime = 0);
     void setRenderRate(Fps renderRate);
 
@@ -192,17 +194,27 @@
     // Emits a packet for perfetto tracing. The function body will be executed only if tracing is
     // enabled. The displayFrameToken is needed to link the SurfaceFrame to the corresponding
     // DisplayFrame at the trace processor side.
-    void trace(int64_t displayFrameToken);
+    void trace(int64_t displayFrameToken) const;
 
-    // Getter functions used only by FrameTimelineTests
+    // Getter functions used only by FrameTimelineTests and SurfaceFrame internally
     TimelineItem getActuals() const;
     pid_t getOwnerPid() const { return mOwnerPid; };
-    PredictionState getPredictionState() const { return mPredictionState; };
+    PredictionState getPredictionState() const;
     PresentState getPresentState() const;
     FrameReadyMetadata getFrameReadyMetadata() const;
     FramePresentMetadata getFramePresentMetadata() const;
+    nsecs_t getDropTime() const;
+
+    // For prediction expired frames, this delta is subtracted from the actual end time to get a
+    // start time decent enough to see in traces.
+    // TODO(b/172587309): Remove this when we have actual start times.
+    static constexpr nsecs_t kPredictionExpiredStartTimeDelta =
+            std::chrono::duration_cast<std::chrono::nanoseconds>(2ms).count();
 
 private:
+    void tracePredictions(int64_t displayFrameToken) const;
+    void traceActuals(int64_t displayFrameToken) const;
+
     const int64_t mToken;
     const int32_t mInputEventId;
     const pid_t mOwnerPid;
@@ -216,6 +228,7 @@
     std::shared_ptr<TimeStats> mTimeStats;
     const JankClassificationThresholds mJankClassificationThresholds;
     nsecs_t mActualQueueTime GUARDED_BY(mMutex) = 0;
+    nsecs_t mDropTime GUARDED_BY(mMutex) = 0;
     mutable std::mutex mMutex;
     // Bitmask for the type of jank
     int32_t mJankType GUARDED_BY(mMutex) = JankType::None;
@@ -359,6 +372,8 @@
 
     private:
         void dump(std::string& result, nsecs_t baseTime) const;
+        void tracePredictions(pid_t surfaceFlingerPid) const;
+        void traceActuals(pid_t surfaceFlingerPid) const;
 
         int64_t mToken = FrameTimelineInfo::INVALID_VSYNC_ID;
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 6a28da3..d2dc206 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1560,6 +1560,7 @@
 
 void Layer::addSurfaceFrameDroppedForBuffer(
         std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame) {
+    surfaceFrame->setDropTime(systemTime());
     surfaceFrame->setPresentState(PresentState::Dropped);
     mFlinger->mFrameTimeline->addSurfaceFrame(surfaceFrame);
 }
@@ -1583,7 +1584,7 @@
     surfaceFrame->setAcquireFenceTime(postTime);
     const auto fps = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
     if (fps) {
-        mSurfaceFrame->setRenderRate(*fps);
+        surfaceFrame->setRenderRate(*fps);
     }
     onSurfaceFrameCreated(surfaceFrame);
     return surfaceFrame;
@@ -1598,7 +1599,7 @@
     surfaceFrame->setActualQueueTime(queueTime);
     const auto fps = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
     if (fps) {
-        mSurfaceFrame->setRenderRate(*fps);
+        surfaceFrame->setRenderRate(*fps);
     }
     // TODO(b/178542907): Implement onSurfaceFrameCreated for BQLayer as well.
     onSurfaceFrameCreated(surfaceFrame);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index a1fdc3c..687f473 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -1145,9 +1145,6 @@
     // Window types from WindowManager.LayoutParams
     const InputWindowInfo::Type mWindowType;
 
-    // Can only be accessed with the SF state lock held.
-    std::shared_ptr<frametimeline::SurfaceFrame> mSurfaceFrame;
-
     // The owner of the layer. If created from a non system process, it will be the calling uid.
     // If created from a system process, the value can be passed in.
     uid_t mOwnerUid;
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 49ffc81..b29c624 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -125,6 +125,9 @@
                                   GRALLOC_USAGE_SW_WRITE_RARELY | GRALLOC_USAGE_HW_COMPOSER |
                                           GRALLOC_USAGE_HW_TEXTURE,
                                   "RefreshRateOverlayBuffer");
+        const status_t bufferStatus = buffer->initCheck();
+        LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "RefreshRateOverlay: Buffer failed to allocate: %d",
+                            bufferStatus);
         uint8_t* pixels;
         buffer->lock(GRALLOC_USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&pixels));
         // Clear buffer content
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 9186538..09615f9 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -447,6 +447,9 @@
                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
         buffer = new GraphicBuffer(sampledBounds.getWidth(), sampledBounds.getHeight(),
                                    PIXEL_FORMAT_RGBA_8888, 1, usage, "RegionSamplingThread");
+        const status_t bufferStatus = buffer->initCheck();
+        LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "captureSample: Buffer failed to allocate: %d",
+                            bufferStatus);
     }
 
     const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index e7a44a7..a03f793 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -627,6 +627,8 @@
 
     std::vector<const RefreshRate*> sortedModes;
     getSortedRefreshRateListLocked([](const RefreshRate&) { return true; }, &sortedModes);
+    // Reset the policy because the old one may no longer be valid.
+    mDisplayManagerPolicy = {};
     mDisplayManagerPolicy.defaultMode = currentModeId;
     mMinSupportedRefreshRate = sortedModes.front();
     mMaxSupportedRefreshRate = sortedModes.back();
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 7fada82..cb9fae3 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5851,6 +5851,10 @@
             getFactory().createGraphicBuffer(bufferSize.getWidth(), bufferSize.getHeight(),
                                              static_cast<android_pixel_format>(reqPixelFormat),
                                              1 /* layerCount */, usage, "screenshot");
+
+    const status_t bufferStatus = buffer->initCheck();
+    LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "captureScreenCommon: Buffer failed to allocate: %d",
+                        bufferStatus);
     return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer,
                                false /* regionSampling */, grayscale, captureListener);
 }
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index 1d1f0c5..b4d8a9a 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -71,12 +71,14 @@
 }
 
 void SurfaceTracing::notify(const char* where) {
+    std::scoped_lock lock(mTraceLock);
     if (mEnabled) {
         runner->notify(where);
     }
 }
 
 void SurfaceTracing::notifyLocked(const char* where) {
+    std::scoped_lock lock(mTraceLock);
     if (mEnabled) {
         runner->notifyLocked(where);
     }
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index 497ebd3..15a503d 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -81,8 +81,8 @@
 
     SurfaceFlinger& mFlinger;
     mutable std::mutex mTraceLock;
-    bool mEnabled = false;
-    std::unique_ptr<Runner> runner;
+    bool mEnabled GUARDED_BY(mTraceLock) = false;
+    std::unique_ptr<Runner> runner GUARDED_BY(mTraceLock);
 
     struct Config {
         uint32_t flags = TRACE_CRITICAL | TRACE_INPUT | TRACE_SYNC;
diff --git a/services/surfaceflinger/TimeStats/Android.bp b/services/surfaceflinger/TimeStats/Android.bp
index 0a23da2..62fddb4 100644
--- a/services/surfaceflinger/TimeStats/Android.bp
+++ b/services/surfaceflinger/TimeStats/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library {
     name: "libtimestats",
     srcs: [
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/Android.bp b/services/surfaceflinger/TimeStats/timestatsproto/Android.bp
index 9481cac..972edaa 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/Android.bp
+++ b/services/surfaceflinger/TimeStats/timestatsproto/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library {
     name: "libtimestats_proto",
     export_include_dirs: ["include"],
diff --git a/services/surfaceflinger/layerproto/Android.bp b/services/surfaceflinger/layerproto/Android.bp
index e2a28a2..c8a2b5e 100644
--- a/services/surfaceflinger/layerproto/Android.bp
+++ b/services/surfaceflinger/layerproto/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library {
     name: "liblayers_proto",
     export_include_dirs: ["include"],
diff --git a/services/surfaceflinger/sysprop/Android.bp b/services/surfaceflinger/sysprop/Android.bp
index 7721d7d2..f579119 100644
--- a/services/surfaceflinger/sysprop/Android.bp
+++ b/services/surfaceflinger/sysprop/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 sysprop_library {
     name: "SurfaceFlingerProperties",
     srcs: ["*.sysprop"],
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index 8142aad..78187f7 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "SurfaceFlinger_test",
     defaults: ["surfaceflinger_defaults"],
diff --git a/services/surfaceflinger/tests/fakehwc/Android.bp b/services/surfaceflinger/tests/fakehwc/Android.bp
index 3535fbb..2551a19 100644
--- a/services/surfaceflinger/tests/fakehwc/Android.bp
+++ b/services/surfaceflinger/tests/fakehwc/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "sffakehwc_test",
     defaults: ["surfaceflinger_defaults"],
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index e55821f..2ac6b09 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "libsurfaceflinger_unittest",
     defaults: ["surfaceflinger_defaults"],
diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
index f222129..b8c1607 100644
--- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
@@ -106,6 +106,7 @@
 
     void addEmptyDisplayFrame() {
         auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
+        // Trigger a flushPresentFence by calling setSfPresent for the next frame
         mFrameTimeline->setSfPresent(2500, presentFence1);
     }
 
@@ -231,29 +232,26 @@
 }
 
 TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
-    // Global increment
     auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
-    auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
-
     int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
-    int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
     auto surfaceFrame1 =
             mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
                                                        sLayerNameOne, sLayerNameOne);
 
     // Set up the display frame
     mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
+    surfaceFrame1->setDropTime(12);
     surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
     mFrameTimeline->addSurfaceFrame(surfaceFrame1);
     mFrameTimeline->setSfPresent(25, presentFence1);
     presentFence1->signalForTest(30);
 
-    // Trigger a flush by calling setSfPresent for the next frame
-    mFrameTimeline->setSfWakeUp(token2, 50, Fps::fromPeriodNsecs(11));
-    mFrameTimeline->setSfPresent(55, presentFence2);
+    addEmptyDisplayFrame();
 
     auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
     EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
+    EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
+    EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
     EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
 }
 
@@ -262,9 +260,7 @@
     EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
     auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
     int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
-    int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
     int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
-    int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 60});
     auto surfaceFrame1 =
             mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
                                                        sUidOne, sLayerNameOne, sLayerNameOne);
@@ -287,16 +283,7 @@
     EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
     EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
 
-    // Trigger a flush by finalizing the next DisplayFrame
-    auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
-    auto surfaceFrame3 =
-            mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
-                                                       sUidOne, sLayerNameOne, sLayerNameOne);
-    mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
-    surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Dropped);
-    mFrameTimeline->addSurfaceFrame(surfaceFrame3);
-    mFrameTimeline->setSfPresent(56, presentFence2);
-    displayFrame = getDisplayFrame(0);
+    addEmptyDisplayFrame();
 
     // Fences have flushed, so the present timestamps should be updated
     EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
@@ -651,10 +638,7 @@
 TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
     auto tracingSession = getTracingSessionForTest();
     auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
-    auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
-
     int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
-    int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
     auto surfaceFrame1 =
             mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
                                                        sLayerNameOne, sLayerNameOne);
@@ -666,10 +650,7 @@
     mFrameTimeline->setSfPresent(25, presentFence1);
     presentFence1->signalForTest(30);
 
-    // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
-    // next frame
-    mFrameTimeline->setSfWakeUp(token2, 50, Fps::fromPeriodNsecs(11));
-    mFrameTimeline->setSfPresent(55, presentFence2);
+    addEmptyDisplayFrame();
 
     auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
     EXPECT_EQ(packets.size(), 0u);
@@ -680,7 +661,6 @@
     // Layer specific increment
     EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
     auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
-    auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
 
     tracingSession->StartBlocking();
     int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
@@ -696,12 +676,7 @@
     mFrameTimeline->setSfPresent(25, presentFence1);
     presentFence1->signalForTest(30);
 
-    // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
-    // next frame
-    mFrameTimeline->setSfWakeUp(token2, 50, Fps::fromPeriodNsecs(11));
-    mFrameTimeline->setSfPresent(55, presentFence2);
-    presentFence2->signalForTest(55);
-
+    addEmptyDisplayFrame();
     flushTrace();
     tracingSession->StopBlocking();
 
@@ -713,22 +688,15 @@
 TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
     auto tracingSession = getTracingSessionForTest();
     auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
-    auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
 
     tracingSession->StartBlocking();
-    int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
 
     // Set up the display frame
     mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
     mFrameTimeline->setSfPresent(25, presentFence1);
     presentFence1->signalForTest(30);
 
-    // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
-    // next frame
-    mFrameTimeline->setSfWakeUp(token1, 50, Fps::fromPeriodNsecs(11));
-    mFrameTimeline->setSfPresent(55, presentFence2);
-    presentFence2->signalForTest(60);
-
+    addEmptyDisplayFrame();
     flushTrace();
     tracingSession->StopBlocking();
 
@@ -739,11 +707,9 @@
 TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
     auto tracingSession = getTracingSessionForTest();
     auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
-    auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
 
     tracingSession->StartBlocking();
     int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
-    int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
     auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne,
                                                                     sLayerNameOne, sLayerNameOne);
 
@@ -754,12 +720,7 @@
     mFrameTimeline->setSfPresent(25, presentFence1);
     presentFence1->signalForTest(30);
 
-    // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
-    // next frame
-    mFrameTimeline->setSfWakeUp(token2, 50, Fps::fromPeriodNsecs(11));
-    mFrameTimeline->setSfPresent(55, presentFence2);
-    presentFence2->signalForTest(60);
-
+    addEmptyDisplayFrame();
     flushTrace();
     tracingSession->StopBlocking();
 
@@ -769,6 +730,65 @@
     EXPECT_EQ(packets.size(), 4u);
 }
 
+ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
+                                                                    pid_t pid) {
+    ProtoExpectedDisplayFrameStart proto;
+    proto.set_cookie(cookie);
+    proto.set_token(token);
+    proto.set_pid(pid);
+    return proto;
+}
+
+ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
+        int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
+        bool gpuComposition, ProtoJankType jankType) {
+    ProtoActualDisplayFrameStart proto;
+    proto.set_cookie(cookie);
+    proto.set_token(token);
+    proto.set_pid(pid);
+    proto.set_present_type(presentType);
+    proto.set_on_time_finish(onTimeFinish);
+    proto.set_gpu_composition(gpuComposition);
+    proto.set_jank_type(jankType);
+    return proto;
+}
+
+ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
+                                                                    int64_t displayFrameToken,
+                                                                    pid_t pid,
+                                                                    std::string layerName) {
+    ProtoExpectedSurfaceFrameStart proto;
+    proto.set_cookie(cookie);
+    proto.set_token(token);
+    proto.set_display_frame_token(displayFrameToken);
+    proto.set_pid(pid);
+    proto.set_layer_name(layerName);
+    return proto;
+}
+
+ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
+        int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
+        ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
+        ProtoJankType jankType) {
+    ProtoActualSurfaceFrameStart proto;
+    proto.set_cookie(cookie);
+    proto.set_token(token);
+    proto.set_display_frame_token(displayFrameToken);
+    proto.set_pid(pid);
+    proto.set_layer_name(layerName);
+    proto.set_present_type(presentType);
+    proto.set_on_time_finish(onTimeFinish);
+    proto.set_gpu_composition(gpuComposition);
+    proto.set_jank_type(jankType);
+    return proto;
+}
+
+ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
+    ProtoFrameEnd proto;
+    proto.set_cookie(cookie);
+    return proto;
+}
+
 void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
                         const ProtoExpectedDisplayFrameStart& source) {
     ASSERT_TRUE(received.has_cookie());
@@ -855,11 +875,9 @@
 TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
     auto tracingSession = getTracingSessionForTest();
     auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
-    auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
 
     tracingSession->StartBlocking();
     int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
-    int64_t displayFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
 
     // Set up the display frame
     mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
@@ -867,33 +885,18 @@
     presentFence1->signalForTest(31);
 
     int64_t traceCookie = snoopCurrentTraceCookie();
-    ProtoExpectedDisplayFrameStart protoExpectedDisplayFrameStart;
-    protoExpectedDisplayFrameStart.set_cookie(traceCookie + 1);
-    protoExpectedDisplayFrameStart.set_token(displayFrameToken1);
-    protoExpectedDisplayFrameStart.set_pid(kSurfaceFlingerPid);
+    auto protoExpectedDisplayFrameStart =
+            createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
+                                                 kSurfaceFlingerPid);
+    auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
+    auto protoActualDisplayFrameStart =
+            createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
+                                               kSurfaceFlingerPid,
+                                               FrameTimelineEvent::PRESENT_ON_TIME, true, false,
+                                               FrameTimelineEvent::JANK_NONE);
+    auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
 
-    ProtoFrameEnd protoExpectedDisplayFrameEnd;
-    protoExpectedDisplayFrameEnd.set_cookie(traceCookie + 1);
-
-    ProtoActualDisplayFrameStart protoActualDisplayFrameStart;
-    protoActualDisplayFrameStart.set_cookie(traceCookie + 2);
-    protoActualDisplayFrameStart.set_token(displayFrameToken1);
-    protoActualDisplayFrameStart.set_pid(kSurfaceFlingerPid);
-    protoActualDisplayFrameStart.set_present_type(
-            ProtoPresentType(FrameTimelineEvent::PRESENT_ON_TIME));
-    protoActualDisplayFrameStart.set_on_time_finish(true);
-    protoActualDisplayFrameStart.set_gpu_composition(false);
-    protoActualDisplayFrameStart.set_jank_type(ProtoJankType(FrameTimelineEvent::JANK_NONE));
-
-    ProtoFrameEnd protoActualDisplayFrameEnd;
-    protoActualDisplayFrameEnd.set_cookie(traceCookie + 2);
-
-    // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
-    // next frame
-    mFrameTimeline->setSfWakeUp(displayFrameToken2, 50, Fps::fromPeriodNsecs(11));
-    mFrameTimeline->setSfPresent(55, presentFence2);
-    presentFence2->signalForTest(55);
-
+    addEmptyDisplayFrame();
     flushTrace();
     tracingSession->StopBlocking();
 
@@ -945,6 +948,60 @@
     validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
 }
 
+TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
+    auto tracingSession = getTracingSessionForTest();
+    auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
+
+    tracingSession->StartBlocking();
+    int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
+    // Flush the token so that it would expire
+    flushTokens(systemTime() + maxTokenRetentionTime);
+
+    // Set up the display frame
+    mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
+    mFrameTimeline->setSfPresent(26, presentFence1);
+    presentFence1->signalForTest(31);
+
+    int64_t traceCookie = snoopCurrentTraceCookie();
+
+    auto protoActualDisplayFrameStart =
+            createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
+                                               kSurfaceFlingerPid,
+                                               FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
+                                               false, FrameTimelineEvent::JANK_UNKNOWN);
+    auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
+
+    addEmptyDisplayFrame();
+    flushTrace();
+    tracingSession->StopBlocking();
+
+    auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
+    // Only actual timeline packets should be in the trace
+    EXPECT_EQ(packets.size(), 2u);
+
+    // Packet - 0 : ActualDisplayFrameStart
+    const auto& packet0 = packets[0];
+    ASSERT_TRUE(packet0.has_timestamp());
+    EXPECT_EQ(packet0.timestamp(), 20u);
+    ASSERT_TRUE(packet0.has_frame_timeline_event());
+
+    const auto& event0 = packet0.frame_timeline_event();
+    ASSERT_TRUE(event0.has_actual_display_frame_start());
+    const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
+    validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
+
+    // Packet - 1 : FrameEnd (ActualDisplayFrame)
+    const auto& packet1 = packets[1];
+    ASSERT_TRUE(packet1.has_timestamp());
+    EXPECT_EQ(packet1.timestamp(), 26u);
+    ASSERT_TRUE(packet1.has_frame_timeline_event());
+
+    const auto& event1 = packet1.frame_timeline_event();
+    ASSERT_TRUE(event1.has_frame_end());
+    const auto& actualDisplayFrameEnd = event1.frame_end();
+    validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
+}
+
 TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
     auto tracingSession = getTracingSessionForTest();
     // Layer specific increment
@@ -955,63 +1012,62 @@
     tracingSession->StartBlocking();
     int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
     int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
-    int64_t displayFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
 
     auto surfaceFrame1 =
             mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
                                                        sUidOne, sLayerNameOne, sLayerNameOne);
-    surfaceFrame1->setActualStartTime(0);
-    surfaceFrame1->setActualQueueTime(15);
-    surfaceFrame1->setAcquireFenceTime(20);
+    auto surfaceFrame2 =
+            mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
+                                                       sUidOne, sLayerNameOne, sLayerNameOne);
+    surfaceFrame1->setActualQueueTime(10);
+    surfaceFrame1->setDropTime(15);
+
+    surfaceFrame2->setActualQueueTime(15);
+    surfaceFrame2->setAcquireFenceTime(20);
 
     // First 2 cookies will be used by the DisplayFrame
     int64_t traceCookie = snoopCurrentTraceCookie() + 2;
 
-    ProtoExpectedSurfaceFrameStart protoExpectedSurfaceFrameStart;
-    protoExpectedSurfaceFrameStart.set_cookie(traceCookie + 1);
-    protoExpectedSurfaceFrameStart.set_token(surfaceFrameToken);
-    protoExpectedSurfaceFrameStart.set_display_frame_token(displayFrameToken1);
-    protoExpectedSurfaceFrameStart.set_pid(sPidOne);
-    protoExpectedSurfaceFrameStart.set_layer_name(sLayerNameOne);
+    auto protoDroppedSurfaceFrameExpectedStart =
+            createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
+                                                 displayFrameToken1, sPidOne, sLayerNameOne);
+    auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
+    auto protoDroppedSurfaceFrameActualStart =
+            createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
+                                               displayFrameToken1, sPidOne, sLayerNameOne,
+                                               FrameTimelineEvent::PRESENT_DROPPED, false, false,
+                                               FrameTimelineEvent::JANK_NONE);
+    auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
 
-    ProtoFrameEnd protoExpectedSurfaceFrameEnd;
-    protoExpectedSurfaceFrameEnd.set_cookie(traceCookie + 1);
-
-    ProtoActualSurfaceFrameStart protoActualSurfaceFrameStart;
-    protoActualSurfaceFrameStart.set_cookie(traceCookie + 2);
-    protoActualSurfaceFrameStart.set_token(surfaceFrameToken);
-    protoActualSurfaceFrameStart.set_display_frame_token(displayFrameToken1);
-    protoActualSurfaceFrameStart.set_pid(sPidOne);
-    protoActualSurfaceFrameStart.set_layer_name(sLayerNameOne);
-    protoActualSurfaceFrameStart.set_present_type(
-            ProtoPresentType(FrameTimelineEvent::PRESENT_ON_TIME));
-    protoActualSurfaceFrameStart.set_on_time_finish(true);
-    protoActualSurfaceFrameStart.set_gpu_composition(false);
-    protoActualSurfaceFrameStart.set_jank_type(ProtoJankType(FrameTimelineEvent::JANK_NONE));
-
-    ProtoFrameEnd protoActualSurfaceFrameEnd;
-    protoActualSurfaceFrameEnd.set_cookie(traceCookie + 2);
+    auto protoPresentedSurfaceFrameExpectedStart =
+            createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
+                                                 displayFrameToken1, sPidOne, sLayerNameOne);
+    auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
+    auto protoPresentedSurfaceFrameActualStart =
+            createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
+                                               displayFrameToken1, sPidOne, sLayerNameOne,
+                                               FrameTimelineEvent::PRESENT_ON_TIME, true, false,
+                                               FrameTimelineEvent::JANK_NONE);
+    auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
 
     // Set up the display frame
     mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
-    surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
+    surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
+    surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
     mFrameTimeline->addSurfaceFrame(surfaceFrame1);
+    mFrameTimeline->addSurfaceFrame(surfaceFrame2);
     mFrameTimeline->setSfPresent(26, presentFence1);
     presentFence1->signalForTest(40);
 
-    // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
-    // next frame
-    mFrameTimeline->setSfWakeUp(displayFrameToken2, 50, Fps::fromPeriodNsecs(11));
-    mFrameTimeline->setSfPresent(55, presentFence2);
-    presentFence2->signalForTest(55);
-
+    addEmptyDisplayFrame();
     flushTrace();
     tracingSession->StopBlocking();
 
     auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
-    EXPECT_EQ(packets.size(), 8u);
+    // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
+    EXPECT_EQ(packets.size(), 12u);
 
-    // Packet - 4 : ExpectedSurfaceFrameStart
+    // Packet - 4 : ExpectedSurfaceFrameStart1
     const auto& packet4 = packets[4];
     ASSERT_TRUE(packet4.has_timestamp());
     EXPECT_EQ(packet4.timestamp(), 10u);
@@ -1019,10 +1075,10 @@
 
     const auto& event4 = packet4.frame_timeline_event();
     ASSERT_TRUE(event4.has_expected_surface_frame_start());
-    const auto& expectedSurfaceFrameStart = event4.expected_surface_frame_start();
-    validateTraceEvent(expectedSurfaceFrameStart, protoExpectedSurfaceFrameStart);
+    const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
+    validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
 
-    // Packet - 5 : FrameEnd (ExpectedSurfaceFrame)
+    // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
     const auto& packet5 = packets[5];
     ASSERT_TRUE(packet5.has_timestamp());
     EXPECT_EQ(packet5.timestamp(), 25u);
@@ -1030,10 +1086,10 @@
 
     const auto& event5 = packet5.frame_timeline_event();
     ASSERT_TRUE(event5.has_frame_end());
-    const auto& expectedSurfaceFrameEnd = event5.frame_end();
-    validateTraceEvent(expectedSurfaceFrameEnd, protoExpectedSurfaceFrameEnd);
+    const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
+    validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
 
-    // Packet - 6 : ActualSurfaceFrameStart
+    // Packet - 6 : ActualSurfaceFrameStart1
     const auto& packet6 = packets[6];
     ASSERT_TRUE(packet6.has_timestamp());
     EXPECT_EQ(packet6.timestamp(), 10u);
@@ -1041,18 +1097,143 @@
 
     const auto& event6 = packet6.frame_timeline_event();
     ASSERT_TRUE(event6.has_actual_surface_frame_start());
-    const auto& actualSurfaceFrameStart = event6.actual_surface_frame_start();
-    validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
+    const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
+    validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
 
-    // Packet - 7 : FrameEnd (ActualSurfaceFrame)
+    // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
     const auto& packet7 = packets[7];
     ASSERT_TRUE(packet7.has_timestamp());
-    EXPECT_EQ(packet7.timestamp(), 20u);
+    EXPECT_EQ(packet7.timestamp(), 15u);
     ASSERT_TRUE(packet7.has_frame_timeline_event());
 
     const auto& event7 = packet7.frame_timeline_event();
     ASSERT_TRUE(event7.has_frame_end());
-    const auto& actualSurfaceFrameEnd = event7.frame_end();
+    const auto& actualSurfaceFrameEnd1 = event7.frame_end();
+    validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
+
+    // Packet - 8 : ExpectedSurfaceFrameStart2
+    const auto& packet8 = packets[8];
+    ASSERT_TRUE(packet8.has_timestamp());
+    EXPECT_EQ(packet8.timestamp(), 10u);
+    ASSERT_TRUE(packet8.has_frame_timeline_event());
+
+    const auto& event8 = packet8.frame_timeline_event();
+    ASSERT_TRUE(event8.has_expected_surface_frame_start());
+    const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
+    validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
+
+    // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
+    const auto& packet9 = packets[9];
+    ASSERT_TRUE(packet9.has_timestamp());
+    EXPECT_EQ(packet9.timestamp(), 25u);
+    ASSERT_TRUE(packet9.has_frame_timeline_event());
+
+    const auto& event9 = packet9.frame_timeline_event();
+    ASSERT_TRUE(event9.has_frame_end());
+    const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
+    validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
+
+    // Packet - 10 : ActualSurfaceFrameStart2
+    const auto& packet10 = packets[10];
+    ASSERT_TRUE(packet10.has_timestamp());
+    EXPECT_EQ(packet10.timestamp(), 10u);
+    ASSERT_TRUE(packet10.has_frame_timeline_event());
+
+    const auto& event10 = packet10.frame_timeline_event();
+    ASSERT_TRUE(event10.has_actual_surface_frame_start());
+    const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
+    validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
+
+    // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
+    const auto& packet11 = packets[11];
+    ASSERT_TRUE(packet11.has_timestamp());
+    EXPECT_EQ(packet11.timestamp(), 20u);
+    ASSERT_TRUE(packet11.has_frame_timeline_event());
+
+    const auto& event11 = packet11.frame_timeline_event();
+    ASSERT_TRUE(event11.has_frame_end());
+    const auto& actualSurfaceFrameEnd2 = event11.frame_end();
+    validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
+}
+
+TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
+    auto tracingSession = getTracingSessionForTest();
+    auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
+
+    tracingSession->StartBlocking();
+    constexpr nsecs_t appStartTime =
+            std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count();
+    constexpr nsecs_t appEndTime =
+            std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count();
+    constexpr nsecs_t appPresentTime =
+            std::chrono::duration_cast<std::chrono::nanoseconds>(30ms).count();
+    int64_t surfaceFrameToken =
+            mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
+
+    // Flush the token so that it would expire
+    flushTokens(systemTime() + maxTokenRetentionTime);
+    auto surfaceFrame1 =
+            mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
+                                                       sPidOne, sUidOne, sLayerNameOne,
+                                                       sLayerNameOne);
+    surfaceFrame1->setActualQueueTime(appEndTime);
+    surfaceFrame1->setAcquireFenceTime(appEndTime);
+
+    constexpr nsecs_t sfStartTime =
+            std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count();
+    constexpr nsecs_t sfEndTime =
+            std::chrono::duration_cast<std::chrono::nanoseconds>(30ms).count();
+    constexpr nsecs_t sfPresentTime =
+            std::chrono::duration_cast<std::chrono::nanoseconds>(30ms).count();
+    int64_t displayFrameToken =
+            mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
+
+    // First 2 cookies will be used by the DisplayFrame
+    int64_t traceCookie = snoopCurrentTraceCookie() + 2;
+
+    auto protoActualSurfaceFrameStart =
+            createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
+                                               displayFrameToken, sPidOne, sLayerNameOne,
+                                               FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
+                                               false, FrameTimelineEvent::JANK_UNKNOWN);
+    auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
+
+    // Set up the display frame
+    mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
+    surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
+    mFrameTimeline->addSurfaceFrame(surfaceFrame1);
+    mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
+    presentFence1->signalForTest(sfPresentTime);
+
+    addEmptyDisplayFrame();
+    flushTrace();
+    tracingSession->StopBlocking();
+
+    auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
+    // Display Frame 4 packets + SurfaceFrame 2 packets
+    ASSERT_EQ(packets.size(), 6u);
+
+    // Packet - 4 : ActualSurfaceFrameStart
+    const auto& packet4 = packets[4];
+    ASSERT_TRUE(packet4.has_timestamp());
+    EXPECT_EQ(packet4.timestamp(),
+              static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
+    ASSERT_TRUE(packet4.has_frame_timeline_event());
+
+    const auto& event4 = packet4.frame_timeline_event();
+    ASSERT_TRUE(event4.has_actual_surface_frame_start());
+    const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
+    validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
+
+    // Packet - 5 : FrameEnd (ActualSurfaceFrame)
+    const auto& packet5 = packets[5];
+    ASSERT_TRUE(packet5.has_timestamp());
+    EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
+    ASSERT_TRUE(packet5.has_frame_timeline_event());
+
+    const auto& event5 = packet5.frame_timeline_event();
+    ASSERT_TRUE(event5.has_frame_end());
+    const auto& actualSurfaceFrameEnd = event5.frame_end();
     validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
 }
 
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 376995f..06f2036 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -1792,6 +1792,26 @@
     ASSERT_TRUE(frameRateOverrides.empty());
 }
 
+TEST_F(RefreshRateConfigsTest, updateDisplayModes) {
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_30);
+    refreshRateConfigs->setDisplayManagerPolicy({DisplayModeId(HWC_CONFIG_ID_30),
+                                                 /* allowGroupSwitching */ false,
+                                                 /* range */ {Fps(30.0f), Fps(30.0f)}});
+
+    refreshRateConfigs->updateDisplayModes(m60_90Device, HWC_CONFIG_ID_60);
+
+    const auto currentRefreshRate = refreshRateConfigs->getCurrentRefreshRate();
+    EXPECT_TRUE(currentRefreshRate.getFps().equalsWithMargin(Fps(60.0)));
+    EXPECT_EQ(currentRefreshRate.getModeId(), HWC_CONFIG_ID_60);
+
+    EXPECT_TRUE(
+            getMaxSupportedRefreshRate(*refreshRateConfigs).getFps().equalsWithMargin(Fps(90.0)));
+    EXPECT_TRUE(
+            getMinSupportedRefreshRate(*refreshRateConfigs).getFps().equalsWithMargin(Fps(60.0)));
+}
+
 } // namespace
 } // namespace scheduler
 } // namespace android
diff --git a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
index aa6798d..bf9ec39 100644
--- a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
@@ -157,8 +157,10 @@
         sp<Fence> fence2(new Fence());
         auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2);
         sp<GraphicBuffer> buffer2{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+        nsecs_t start = systemTime();
         layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt,
                          {/*vsyncId*/ 1, /*inputEventId*/ 0});
+        nsecs_t end = systemTime();
         acquireFence2->signalForTest(12);
 
         EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
@@ -171,6 +173,9 @@
 
         EXPECT_EQ(1, droppedSurfaceFrame->getToken());
         EXPECT_EQ(PresentState::Dropped, droppedSurfaceFrame->getPresentState());
+        EXPECT_EQ(0u, droppedSurfaceFrame->getActuals().endTime);
+        auto dropTime = droppedSurfaceFrame->getDropTime();
+        EXPECT_TRUE(dropTime > start && dropTime < end);
 
         EXPECT_EQ(1, presentedSurfaceFrame->getToken());
         EXPECT_EQ(PresentState::Presented, presentedSurfaceFrame->getPresentState());
@@ -328,6 +333,41 @@
         EXPECT_EQ(PresentState::Presented, bufferlessSurfaceFrame2->getPresentState());
         EXPECT_EQ(12, bufferlessSurfaceFrame2->getActuals().endTime);
     }
+
+    void PendingSurfaceFramesRemovedAfterClassification() {
+        sp<BufferStateLayer> layer = createBufferStateLayer();
+
+        sp<Fence> fence1(new Fence());
+        auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1);
+        sp<GraphicBuffer> buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+        layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt,
+                         {/*vsyncId*/ 1, /*inputEventId*/ 0});
+        ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
+        const auto droppedSurfaceFrame = layer->mCurrentState.bufferSurfaceFrameTX;
+
+        sp<Fence> fence2(new Fence());
+        auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2);
+        sp<GraphicBuffer> buffer2{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+        layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt,
+                         {/*vsyncId*/ 1, /*inputEventId*/ 0});
+        acquireFence2->signalForTest(12);
+
+        ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
+        auto& presentedSurfaceFrame = layer->mCurrentState.bufferSurfaceFrameTX;
+
+        commitTransaction(layer.get());
+        bool computeVisisbleRegions;
+        layer->updateTexImage(computeVisisbleRegions, 15, 0);
+
+        // Both the droppedSurfaceFrame and presentedSurfaceFrame should be in
+        // pendingJankClassifications.
+        EXPECT_EQ(2u, layer->mPendingJankClassifications.size());
+        presentedSurfaceFrame->onPresent(20, JankType::None, Fps::fromPeriodNsecs(11),
+                                         /*displayDeadlineDelta*/ 0, /*displayPresentDelta*/ 0);
+        layer->releasePendingBuffer(25);
+
+        EXPECT_EQ(0u, layer->mPendingJankClassifications.size());
+    }
 };
 
 TEST_F(TransactionSurfaceFrameTest, PresentedBufferlessSurfaceFrame) {
@@ -364,4 +404,7 @@
     MergePendingStates_BufferlessSurfaceFramesWithOverlappingToken();
 }
 
+TEST_F(TransactionSurfaceFrameTest, PendingSurfaceFramesRemovedAfterClassification) {
+    PendingSurfaceFramesRemovedAfterClassification();
+}
 } // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/vsync/Android.bp b/services/surfaceflinger/tests/vsync/Android.bp
index 6a89945..bae9796 100644
--- a/services/surfaceflinger/tests/vsync/Android.bp
+++ b/services/surfaceflinger/tests/vsync/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_binary {
     name: "test-vsync-events",
     defaults: ["surfaceflinger_defaults"],
diff --git a/services/surfaceflinger/tests/waitforvsync/Android.bp b/services/surfaceflinger/tests/waitforvsync/Android.bp
index cb6d0fd..ffed4d7 100644
--- a/services/surfaceflinger/tests/waitforvsync/Android.bp
+++ b/services/surfaceflinger/tests/waitforvsync/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_binary {
     name: "test-waitforvsync",
     cflags: [
diff --git a/services/utils/Android.bp b/services/utils/Android.bp
index f3d2bc9..81e1232 100644
--- a/services/utils/Android.bp
+++ b/services/utils/Android.bp
@@ -15,6 +15,15 @@
 //
 // Static library used in testing and executables
 //
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_static {
     name: "libserviceutils",
 
diff --git a/services/utils/tests/Android.bp b/services/utils/tests/Android.bp
index f21254c..54cf5b7 100644
--- a/services/utils/tests/Android.bp
+++ b/services/utils/tests/Android.bp
@@ -14,6 +14,15 @@
 
 // Build unit tests.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_test {
     name: "prioritydumper_test",
     test_suites: ["device-tests"],
diff --git a/services/vr/Android.bp b/services/vr/Android.bp
index 80df479..980dcf4 100644
--- a/services/vr/Android.bp
+++ b/services/vr/Android.bp
@@ -1,3 +1,13 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 subdirs = [
   "*",
 ]
diff --git a/services/vr/bufferhubd/Android.bp b/services/vr/bufferhubd/Android.bp
index 7097e7a..8523bb2 100644
--- a/services/vr/bufferhubd/Android.bp
+++ b/services/vr/bufferhubd/Android.bp
@@ -12,6 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 sharedLibraries = [
     "libbase",
     "libcutils",
diff --git a/services/vr/hardware_composer/Android.bp b/services/vr/hardware_composer/Android.bp
index 3728731..866007e 100644
--- a/services/vr/hardware_composer/Android.bp
+++ b/services/vr/hardware_composer/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libvr_hwc-hal",
 
diff --git a/services/vr/hardware_composer/aidl/Android.bp b/services/vr/hardware_composer/aidl/Android.bp
index a1d5392..98afdec 100644
--- a/services/vr/hardware_composer/aidl/Android.bp
+++ b/services/vr/hardware_composer/aidl/Android.bp
@@ -1,3 +1,14 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-Unicode-DFS
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_static {
     name: "libvr_hwc-binder",
     srcs: [
diff --git a/services/vr/performanced/Android.bp b/services/vr/performanced/Android.bp
index 0ef8cc4..5eca88b 100644
--- a/services/vr/performanced/Android.bp
+++ b/services/vr/performanced/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-MIT
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_defaults {
     name: "performanced_defaults",
     static_libs: [
diff --git a/services/vr/virtual_touchpad/Android.bp b/services/vr/virtual_touchpad/Android.bp
index 9cf4905..f2ec5a4 100644
--- a/services/vr/virtual_touchpad/Android.bp
+++ b/services/vr/virtual_touchpad/Android.bp
@@ -2,6 +2,15 @@
 
 // Touchpad implementation.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 src = [
     "EvdevInjector.cpp",
     "VirtualTouchpadEvdev.cpp",
diff --git a/vulkan/Android.bp b/vulkan/Android.bp
index 4934970..33599ea 100644
--- a/vulkan/Android.bp
+++ b/vulkan/Android.bp
@@ -14,6 +14,16 @@
 
 // This module makes the Vulkan libhardware HAL headers available, for
 // the loader and for HAL/driver implementations.
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-MIT
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_headers {
     name: "hwvulkan_headers",
     vendor_available: true,
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index 1d29bab..67cd875 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -13,6 +13,15 @@
 // limitations under the License.
 
 // Headers module is in external/vulkan-headers/Android.bp.
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 ndk_library {
     name: "libvulkan",
     symbol_file: "libvulkan.map.txt",
diff --git a/vulkan/nulldrv/Android.bp b/vulkan/nulldrv/Android.bp
index ba02504..0daad9c 100644
--- a/vulkan/nulldrv/Android.bp
+++ b/vulkan/nulldrv/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     // Real drivers would set this to vulkan.$(TARGET_BOARD_PLATFORM)
     name: "vulkan.default",
diff --git a/vulkan/vkjson/Android.bp b/vulkan/vkjson/Android.bp
index 8528898..fa0258b 100644
--- a/vulkan/vkjson/Android.bp
+++ b/vulkan/vkjson/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
 cc_library_shared {
     name: "libvkjson",
     srcs: [