Merge "SF Buffer Stuffing" into sc-dev
diff --git a/include/android/imagedecoder.h b/include/android/imagedecoder.h
index 8d1bf99..c3d3a4b 100644
--- a/include/android/imagedecoder.h
+++ b/include/android/imagedecoder.h
@@ -739,6 +739,9 @@
  * skipping frames in an image with such frames may not produce the correct
  * results.
  *
+ * Only supported by {@link ANDROID_BITMAP_FORMAT_RGBA_8888} and
+ * {@link ANDROID_BITMAP_FORMAT_RGBA_F16}.
+ *
  * @param decoder an {@link AImageDecoder} object.
  * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
  *         indicating the reason for the failure.
@@ -747,6 +750,8 @@
  * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The AImageDecoder
  *   represents an image that is not animated (see
  *   {@link AImageDecoder_isAnimated}) or the AImageDecoder is null.
+ * - {@link ANDROID_IMAGE_DECODER_INVALID_STATE): The requested
+ *   {@link AndroidBitmapFormat} does not support animation.
  * - {@link ANDROID_IMAGE_DECODER_INCOMPLETE}: The input appears
  *   to be truncated. The client must call {@link AImageDecoder_rewind}
  *   before calling {@link AImageDecoder_decodeImage} again.
diff --git a/include/android/surface_control.h b/include/android/surface_control.h
index b7eafcd..f6c2e55 100644
--- a/include/android/surface_control.h
+++ b/include/android/surface_control.h
@@ -534,11 +534,12 @@
  *
  * \param compatibility The frame rate compatibility of this surface. The compatibility value may
  * influence the system's choice of display frame rate. To specify a compatibility use the
- * ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* enum.
+ * ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* enum. This parameter is ignored when frameRate is 0.
  *
- * \param changeFrameRateStrategy Whether display refresh rate transitions should be seamless.
- * A seamless transition is one that doesn't have any visual interruptions, such as a black
- * screen for a second or two. See the ANATIVEWINDOW_CHANGE_FRAME_RATE_* values.
+ * \param changeFrameRateStrategy Whether display refresh rate transitions caused by this
+ * surface should be seamless. A seamless transition is one that doesn't have any visual
+ * interruptions, such as a black screen for a second or two. See the
+ * ANATIVEWINDOW_CHANGE_FRAME_RATE_* values. This parameter is ignored when frameRate is 0.
  *
  * Available since API level 31.
  */
diff --git a/libs/binder/PermissionCache.cpp b/libs/binder/PermissionCache.cpp
index 6eae5ef..670fd55 100644
--- a/libs/binder/PermissionCache.cpp
+++ b/libs/binder/PermissionCache.cpp
@@ -109,5 +109,10 @@
     return granted;
 }
 
+void PermissionCache::purgeCache() {
+    PermissionCache& pc(PermissionCache::getInstance());
+    pc.purge();
+}
+
 // ---------------------------------------------------------------------------
 } // namespace android
diff --git a/libs/binder/RpcConnection.cpp b/libs/binder/RpcConnection.cpp
index 1388a80..f2302f7 100644
--- a/libs/binder/RpcConnection.cpp
+++ b/libs/binder/RpcConnection.cpp
@@ -130,24 +130,21 @@
 
 #endif // __BIONIC__
 
-class SocketAddressImpl : public RpcConnection::SocketAddress {
+class InetSocketAddress : public RpcConnection::SocketAddress {
 public:
-    SocketAddressImpl(const sockaddr* addr, size_t size, const String8& desc)
-          : mAddr(addr), mSize(size), mDesc(desc) {}
+    InetSocketAddress(const sockaddr* sockAddr, size_t size, const char* addr, unsigned int port)
+          : mSockAddr(sockAddr), mSize(size), mAddr(addr), mPort(port) {}
     [[nodiscard]] std::string toString() const override {
-        return std::string(mDesc.c_str(), mDesc.size());
+        return String8::format("%s:%u", mAddr, mPort).c_str();
     }
-    [[nodiscard]] const sockaddr* addr() const override { return mAddr; }
+    [[nodiscard]] const sockaddr* addr() const override { return mSockAddr; }
     [[nodiscard]] size_t addrSize() const override { return mSize; }
-    void set(const sockaddr* addr, size_t size) {
-        mAddr = addr;
-        mSize = size;
-    }
 
 private:
-    const sockaddr* mAddr = nullptr;
-    size_t mSize = 0;
-    String8 mDesc;
+    const sockaddr* mSockAddr;
+    size_t mSize;
+    const char* mAddr;
+    unsigned int mPort;
 };
 
 AddrInfo GetAddrInfo(const char* addr, unsigned int port) {
@@ -170,14 +167,15 @@
 }
 
 bool RpcConnection::setupInetServer(unsigned int port) {
-    auto aiStart = GetAddrInfo("127.0.0.1", port);
+    const char* kAddr = "127.0.0.1";
+
+    auto aiStart = GetAddrInfo(kAddr, port);
     if (aiStart == nullptr) return false;
-    SocketAddressImpl socketAddress(nullptr, 0, String8::format("127.0.0.1:%u", port));
     for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
-        socketAddress.set(ai->ai_addr, ai->ai_addrlen);
+        InetSocketAddress socketAddress(ai->ai_addr, ai->ai_addrlen, kAddr, port);
         if (setupSocketServer(socketAddress)) return true;
     }
-    ALOGE("None of the socket address resolved for 127.0.0.1:%u can be set up as inet server.",
+    ALOGE("None of the socket address resolved for %s:%u can be set up as inet server.", kAddr,
           port);
     return false;
 }
@@ -185,9 +183,8 @@
 bool RpcConnection::addInetClient(const char* addr, unsigned int port) {
     auto aiStart = GetAddrInfo(addr, port);
     if (aiStart == nullptr) return false;
-    SocketAddressImpl socketAddress(nullptr, 0, String8::format("%s:%u", addr, port));
     for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
-        socketAddress.set(ai->ai_addr, ai->ai_addrlen);
+        InetSocketAddress socketAddress(ai->ai_addr, ai->ai_addrlen, addr, port);
         if (addSocketClient(socketAddress)) return true;
     }
     ALOGE("None of the socket address resolved for %s:%u can be added as inet client.", addr, port);
diff --git a/libs/binder/include/binder/PermissionCache.h b/libs/binder/include/binder/PermissionCache.h
index 835a3a8..21aa705 100644
--- a/libs/binder/include/binder/PermissionCache.h
+++ b/libs/binder/include/binder/PermissionCache.h
@@ -73,6 +73,8 @@
 
     static bool checkPermission(const String16& permission,
             pid_t pid, uid_t uid);
+
+    static void purgeCache();
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index eb103d3..b03e24c 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -55,7 +55,9 @@
     defaults: ["libbinder_ndk_host_user"],
     host_supported: true,
 
-    llndk_stubs: "libbinder_ndk.llndk",
+    llndk: {
+        symbol_file: "libbinder_ndk.map.txt",
+    },
 
     export_include_dirs: [
         "include_cpp",
@@ -192,13 +194,3 @@
     symbol_file: "libbinder_ndk.map.txt",
     first_version: "29",
 }
-
-llndk_library {
-    name: "libbinder_ndk.llndk",
-    symbol_file: "libbinder_ndk.map.txt",
-    export_include_dirs: [
-        "include_cpp",
-        "include_ndk",
-        "include_platform",
-    ],
-}
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index f303b7c..c0f7c99 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -35,6 +35,7 @@
     name: "binderDriverInterfaceTest_IPC_32",
     defaults: ["binder_test_defaults"],
     srcs: ["binderDriverInterfaceTest.cpp"],
+    header_libs: ["libbinder_headers"],
     compile_multilib: "32",
     multilib: { lib32: { suffix: "" } },
     cflags: ["-DBINDER_IPC_32BIT=1"],
@@ -49,7 +50,7 @@
             cflags: ["-DBINDER_IPC_32BIT=1"],
         },
     },
-
+    header_libs: ["libbinder_headers"],
     srcs: ["binderDriverInterfaceTest.cpp"],
     test_suites: ["device-tests", "vts"],
 }
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index 8675439..9286009 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -60,7 +60,13 @@
 
 cc_library {
     name: "libnativewindow",
-    llndk_stubs: "libnativewindow.llndk",
+    llndk: {
+        symbol_file: "libnativewindow.map.txt",
+        unversioned: true,
+        override_export_include_dirs: [
+            "include"
+        ],
+    },
     export_include_dirs: [
         "include",
         "include-private",
@@ -115,11 +121,4 @@
     },
 }
 
-llndk_library {
-    name: "libnativewindow.llndk",
-    symbol_file: "libnativewindow.map.txt",
-    unversioned: true,
-    export_include_dirs: ["include"],
-}
-
 subdirs = ["tests"]
diff --git a/libs/nativewindow/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h
index 61b3f94..3865ba5 100644
--- a/libs/nativewindow/include/android/native_window.h
+++ b/libs/nativewindow/include/android/native_window.h
@@ -302,6 +302,8 @@
  *
  * Available since API level 31.
  *
+ * \param window pointer to an ANativeWindow object.
+ *
  * \param frameRate The intended frame rate of this window, in frames per
  * second. 0 is a special value that indicates the app will accept the system's
  * choice for the display frame rate, which is the default behavior if this
@@ -309,15 +311,16 @@
  * valid refresh rate for this device's display - e.g., it's fine to pass 30fps
  * to a device that can only run the display at 60fps.
  *
- * \param window pointer to an ANativeWindow object.
- *
  * \param compatibility The frame rate compatibility of this window. The
  * compatibility value may influence the system's choice of display refresh
  * rate. See the ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* values for more info.
+ * This parameter is ignored when frameRate is 0.
  *
- * \param changeFrameRateStrategy Whether display refresh rate transitions should be seamless.
+ * \param changeFrameRateStrategy Whether display refresh rate transitions caused by this
+ * window should be seamless.
  * A seamless transition is one that doesn't have any visual interruptions, such as a black
  * screen for a second or two. See the ANATIVEWINDOW_CHANGE_FRAME_RATE_* values.
+ * This parameter is ignored when frameRate is 0.
  *
  * \return 0 for success, -EINVAL if the window, frame rate, or compatibility
  * value are invalid.
diff --git a/libs/permission/Android.bp b/libs/permission/Android.bp
index 1ae0a00..a5712b3 100644
--- a/libs/permission/Android.bp
+++ b/libs/permission/Android.bp
@@ -7,42 +7,17 @@
     default_applicable_licenses: ["frameworks_native_license"],
 }
 
-aidl_interface {
-    name: "framework-permission-aidl",
-    unstable: true,
-    local_include_dir: "aidl",
-    backend: {
-        ndk: {
-            enabled: false
-        }
-    },
-    srcs: [
-        "aidl/android/content/AttributionSourceState.aidl",
-        "aidl/android/permission/IPermissionChecker.aidl",
-    ],
-}
-
 cc_library_shared {
     name: "libpermission",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
     srcs: [
         "AppOpsManager.cpp",
         "IAppOpsCallback.cpp",
         "IAppOpsService.cpp",
-        "android/permission/PermissionChecker.cpp",
     ],
     export_include_dirs: ["include"],
     shared_libs: [
-        "libutils",
         "libbinder",
-        "libcutils",
         "liblog",
-    ],
-    static_libs: [
-        "framework-permission-aidl-cpp",
+        "libutils",
     ],
 }
diff --git a/libs/permission/aidl/android/content/AttributionSourceState.aidl b/libs/permission/aidl/android/content/AttributionSourceState.aidl
deleted file mode 100644
index b6e54bf..0000000
--- a/libs/permission/aidl/android/content/AttributionSourceState.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.
- */
-
-package android.content;
-
-/**
- * Payload for the {@link AttributionSource} class needed to interoperate
- * with different languages.
- *
- * {@hide}
- */
-parcelable AttributionSourceState {
-    /** The UID that is accessing the permission protected data. */
-    int uid;
-    /** The package that is accessing the permission protected data. */
-    @nullable @utf8InCpp String packageName;
-    /** The attribution tag of the app accessing the permission protected data. */
-    @nullable @utf8InCpp String attributionTag;
-    /** Unique token for that source. */
-    @nullable IBinder token;
-    /** Permissions that should be considered revoked regardless if granted. */
-    @nullable @utf8InCpp String[] renouncedPermissions;
-    /** The next app to receive the permission protected data. */
-    // TODO: We use an array as a workaround - the C++ backend doesn't
-    // support referring to the parcelable as it expects ctor/dtor
-    @nullable AttributionSourceState[] next;
-}
diff --git a/libs/permission/aidl/android/permission/IPermissionChecker.aidl b/libs/permission/aidl/android/permission/IPermissionChecker.aidl
deleted file mode 100644
index 1f0e32d..0000000
--- a/libs/permission/aidl/android/permission/IPermissionChecker.aidl
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.
- */
-
-package android.permission;
-
-import android.content.AttributionSourceState;
-
-/**
- * Interface to communicate directly with the permission checker service.
- */
-interface IPermissionChecker {
-    const int PERMISSION_GRANTED = 0;
-    const int PERMISSION_SOFT_DENIED = 1;
-    const int PERMISSION_HARD_DENIED = 2;
-
-    int checkPermission(String permission, in AttributionSourceState attributionSource,
-            @nullable String message, boolean forDataDelivery, boolean startDataDelivery,
-            boolean fromDatasource);
-
-    void finishDataDelivery(String op, in AttributionSourceState attributionSource);
-
-    int checkOp(int op, in AttributionSourceState attributionSource,
-            String message, boolean forDataDelivery, boolean startDataDelivery);
-}
diff --git a/libs/permission/android/permission/PermissionChecker.cpp b/libs/permission/android/permission/PermissionChecker.cpp
deleted file mode 100644
index a8083ee..0000000
--- a/libs/permission/android/permission/PermissionChecker.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.
- */
-
-#include <mutex>
-#include <include/android/permission/PermissionChecker.h>
-#include <binder/Binder.h>
-#include <binder/IServiceManager.h>
-
-#include <utils/SystemClock.h>
-
-#include <sys/types.h>
-#include <private/android_filesystem_config.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "PermissionChecker"
-
-namespace android {
-
-using android::content::AttributionSourceState;
-
-PermissionChecker::PermissionChecker()
-{
-}
-
-sp<IPermissionChecker> PermissionChecker::getService()
-{
-    static String16 permission_checker("permission_checker");
-
-    std::lock_guard<Mutex> scoped_lock(mLock);
-    int64_t startTime = 0;
-    sp<IPermissionChecker> service = mService;
-    while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) {
-        sp<IBinder> binder = defaultServiceManager()->checkService(permission_checker);
-        if (binder == nullptr) {
-            // Wait for the permission checker service to come back...
-            if (startTime == 0) {
-                startTime = uptimeMillis();
-                ALOGW("Waiting for permission checker service");
-            } else if ((uptimeMillis() - startTime) > 10000) {
-                ALOGE("Waiting too long for permission checker service, giving up");
-                service = nullptr;
-                break;
-            }
-            sleep(1);
-        } else {
-            mService = interface_cast<IPermissionChecker>(binder);
-        }
-    }
-    return mService;
-}
-
-PermissionChecker::PermissionResult
-    PermissionChecker::checkPermissionForDataDeliveryFromDatasource(
-        const String16& permission, AttributionSourceState& attributionSource,
-        const String16& message)
-{
-    return static_cast<PermissionResult>(checkPermission(permission, attributionSource, message,
-            /*forDataDelivery*/ true, /*startDataDelivery*/ false,/*fromDatasource*/ true));
-}
-
-PermissionChecker::PermissionResult
-    PermissionChecker::checkPermissionForStartDataDeliveryFromDatasource(
-        const String16& permission, AttributionSourceState& attributionSource,
-        const String16& message)
-{
-    return static_cast<PermissionResult>(checkPermission(permission, attributionSource, message,
-            /*forDataDelivery*/ true, /*startDataDelivery*/ true, /*fromDatasource*/ true));
-}
-
-void PermissionChecker::finishDataDelivery(const String16& op,
-        AttributionSourceState& attributionSource)
-{
-    sp<IPermissionChecker> service = getService();
-    if (service != nullptr) {
-        binder::Status status = service->finishDataDelivery(op, attributionSource);
-        if (!status.isOk()) {
-            ALOGE("finishDataDelivery failed: %s", status.exceptionMessage().c_str());
-        }
-    }
-}
-
-int32_t PermissionChecker::checkPermission(const String16& permission,
-        AttributionSourceState& attributionSource, const String16& message,
-        bool forDataDelivery, bool startDataDelivery, bool fromDatasource)
-{
-    sp<IPermissionChecker> service = getService();
-    if (service != nullptr) {
-        int32_t result;
-        binder::Status status = service->checkPermission(permission, attributionSource, message,
-                forDataDelivery, startDataDelivery, fromDatasource, &result);
-        if (status.isOk()) {
-            return result;
-        }
-        ALOGE("checkPermission failed: %s", status.exceptionMessage().c_str());
-    }
-    return PERMISSION_DENIED;
-}
-
-} // namespace android
diff --git a/libs/permission/include/android/permission/PermissionChecker.h b/libs/permission/include/android/permission/PermissionChecker.h
deleted file mode 100644
index 20ab51f..0000000
--- a/libs/permission/include/android/permission/PermissionChecker.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <android/content/AttributionSourceState.h>
-#include <android/permission/IPermissionChecker.h>
-
-#include <utils/threads.h>
-
-#include <optional>
-
-#ifdef __ANDROID_VNDK__
-#error "This header is not visible to vendors"
-#endif
-
-// ---------------------------------------------------------------------------
-namespace android {
-
-using android::content::AttributionSourceState;
-using android::permission::IPermissionChecker;
-
-class PermissionChecker
-{
-public:
-
-    enum PermissionResult {
-
-        /**
-         * The permission is granted.
-         */
-        PERMISSION_GRANTED = IPermissionChecker::PERMISSION_GRANTED,
-
-        /**
-         * The permission is denied. Applicable only to runtime and app op permissions.
-         *
-         * Returned when:
-         *   - the runtime permission is granted, but the corresponding app op is denied
-         *       for runtime permissions.
-         *   - the app ops is ignored for app op permissions.
-         *
-         */
-        PERMISSION_SOFT_DENIED = IPermissionChecker::PERMISSION_SOFT_DENIED,
-
-        /**
-         * The permission is denied.
-         *
-         * Returned when:
-         *  - the permission is denied for non app op permissions.
-         *  - the app op is denied or app op is AppOpsManager#MODE_DEFAULT and permission is denied.
-         */
-        PERMISSION_HARD_DENIED = IPermissionChecker::PERMISSION_HARD_DENIED
-    };
-
-    PermissionChecker();
-
-    /**
-     * Checks whether a given data access chain described by the given attribution source
-     * has a given permission and whether the app op that corresponds to this permission
-     * is allowed. Call this method if you are the datasource which would not blame you for
-     * access to the data since you are the data. Note that the attribution source chain
-     *
-     * NOTE: The attribution source should be for yourself with its next attribution
-     * source being the app that would receive the data from you.
-     *
-     * NOTE: Use this method only for permission checks at the point where you will deliver
-     * the permission protected data to clients.
-     *
-     * @param permission The permission to check.
-     * @param attributionSource The attribution chain to check.
-     * @param message A message describing the reason the permission was checked.
-     * @return The permission check result which is either PERMISSION_GRANTED,
-     *     or PERMISSION_SOFT_DENIED or PERMISSION_HARD_DENIED.
-     */
-    PermissionChecker::PermissionResult checkPermissionForDataDeliveryFromDatasource(
-            const String16& permission, AttributionSourceState& attributionSource,
-            const String16& message);
-
-   /**
-     * Checks whether a given data access chain described by the given attribution source
-     * has a given permission and whether the app op that corresponds to this permission
-     * is allowed. The app ops are also marked as started. This is useful for long running
-     * permissions like camera and microphone.
-     *
-     * NOTE: The attribution source should be for yourself with its next attribution
-     * source being the app that would receive the data from you.
-     *
-     * NOTE: Use this method only for permission checks at the point where you will deliver
-     * the permission protected data to clients.
-     *
-     * @param permission The permission to check.
-     * @param attributionSource The attribution chain to check.
-     * @param message A message describing the reason the permission was checked.
-     * @return The permission check result which is either PERMISSION_GRANTED,
-     *     or PERMISSION_SOFT_DENIED or PERMISSION_HARD_DENIED.
-     */
-    PermissionResult checkPermissionForStartDataDeliveryFromDatasource(
-            const String16& permission, AttributionSourceState& attributionSource,
-            const String16& message);
-
-    /**
-     * Finishes an ongoing op for data access chain described by the given
-     * attribution source.
-     *
-     * @param op The op to finish.
-     * @param attributionSource The attribution chain for which to finish data delivery.
-     */
-    void finishDataDelivery(const String16& op, AttributionSourceState& attributionSource);
-
-private:
-    Mutex mLock;
-    sp<IPermissionChecker> mService;
-    sp<IPermissionChecker> getService();
-
-    int32_t checkPermission(const String16& permission, AttributionSourceState& attributionSource,
-            const String16& message, bool forDataDelivery, bool startDataDelivery,
-            bool fromDatasource);
-};
-
-
-} // namespace android
-
-// ---------------------------------------------------------------------------
diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp
index 1c2b2fc..a0da888 100644
--- a/libs/renderengine/skia/Cache.cpp
+++ b/libs/renderengine/skia/Cache.cpp
@@ -37,12 +37,17 @@
                                      0.f,  0.7f, 0.f, 0.f,
                                      0.f,   0.f, 1.f, 0.f,
                                    67.3f, 52.2f, 0.f, 1.f);
+const auto kScaleYOnly = mat4(1.f,   0.f, 0.f, 0.f,
+                              0.f,  0.7f, 0.f, 0.f,
+                              0.f,   0.f, 1.f, 0.f,
+                              0.f,   0.f, 0.f, 1.f);
 // clang-format on
 // When choosing dataspaces below, whether the match the destination or not determined whether
 // a color correction effect is added to the shader. There may be other additional shader details
 // for particular color spaces.
 // TODO(b/184842383) figure out which color related shaders are necessary
 constexpr auto kDestDataSpace = ui::Dataspace::SRGB;
+constexpr auto kOtherDataSpace = ui::Dataspace::DISPLAY_P3;
 } // namespace
 
 static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
@@ -182,6 +187,37 @@
     }
 }
 
+static void drawTextureScaleLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
+                                   const std::shared_ptr<ExternalTexture>& dstTexture,
+                                   const std::shared_ptr<ExternalTexture>& srcTexture) {
+    const Rect& displayRect = display.physicalDisplay;
+    FloatRect rect(0, 0, displayRect.width(), displayRect.height());
+    LayerSettings layer{
+            .geometry =
+                    Geometry{
+                            .boundaries = rect,
+                            .roundedCornersCrop = rect,
+                            .positionTransform = kScaleAndTranslate,
+                            .roundedCornersRadius = 300,
+                    },
+            .source = PixelSource{.buffer =
+                                          Buffer{
+                                                  .buffer = srcTexture,
+                                                  .maxMasteringLuminance = 1000.f,
+                                                  .maxContentLuminance = 1000.f,
+                                                  .textureTransform = kScaleYOnly,
+                                          }},
+            .sourceDataspace = kOtherDataSpace,
+    };
+
+    auto layers = std::vector<const LayerSettings*>{&layer};
+    for (float alpha : {0.5f, 1.f}) {
+        layer.alpha = alpha,
+        renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
+                                 base::unique_fd(), nullptr);
+    }
+}
+
 //
 // The collection of shaders cached here were found by using perfetto to record shader compiles
 // during actions that involve RenderEngine, logging the layer settings, and the shader code
@@ -250,6 +286,9 @@
     // between 6 and 8 will occur in real uses.
     drawImageLayers(renderengine, display, dstTexture, externalTexture);
 
+    // Draw layers for b/185569240.
+    drawTextureScaleLayers(renderengine, display, dstTexture, externalTexture);
+
     const nsecs_t timeAfter = systemTime();
     const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6;
     const int shadersCompiled = renderengine->reportShadersCompiled();
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 7861d62..4146764 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -137,7 +137,12 @@
 cc_library_shared {
     name: "libEGL",
     defaults: ["egl_libs_defaults"],
-    llndk_stubs: "libEGL.llndk",
+    llndk: {
+        symbol_file: "libEGL.map.txt",
+        export_llndk_headers: ["gl_llndk_headers"],
+        // Don't export EGL/include from the LLNDK variant.
+        override_export_include_dirs: [],
+    },
     srcs: [
         "EGL/egl_tls.cpp",
         "EGL/egl_cache.cpp",
@@ -203,7 +208,12 @@
 cc_library_shared {
     name: "libGLESv1_CM",
     defaults: ["gles_libs_defaults"],
-    llndk_stubs: "libGLESv1_CM.llndk",
+    llndk: {
+        symbol_file: "libGLESv1_CM.map.txt",
+        export_llndk_headers: ["gl_llndk_headers"],
+        // Don't export EGL/include from the LLNDK variant.
+        override_export_include_dirs: [],
+    },
     srcs: ["GLES_CM/gl.cpp"],
     cflags: ["-DLOG_TAG=\"libGLESv1\""],
     version_script: "libGLESv1_CM.map.txt",
@@ -215,7 +225,12 @@
 cc_library_shared {
     name: "libGLESv2",
     defaults: ["gles_libs_defaults"],
-    llndk_stubs: "libGLESv2.llndk",
+    llndk: {
+        symbol_file: "libGLESv2.map.txt",
+        export_llndk_headers: ["gl_llndk_headers"],
+        // Don't export EGL/include from the LLNDK variant.
+        override_export_include_dirs: [],
+    },
     srcs: ["GLES2/gl2.cpp"],
     cflags: ["-DLOG_TAG=\"libGLESv2\""],
 
@@ -230,31 +245,12 @@
 cc_library_shared {
     name: "libGLESv3",
     defaults: ["gles_libs_defaults"],
-    llndk_stubs: "libGLESv3.llndk",
+    llndk: {
+        symbol_file: "libGLESv3.map.txt",
+        export_llndk_headers: ["gl_llndk_headers"],
+        // Don't export EGL/include from the LLNDK variant.
+        override_export_include_dirs: [],
+    },
     srcs: ["GLES2/gl2.cpp"],
     cflags: ["-DLOG_TAG=\"libGLESv3\""],
 }
-
-llndk_library {
-    name: "libEGL.llndk",
-    symbol_file: "libEGL.map.txt",
-    export_llndk_headers: ["gl_llndk_headers"],
-}
-
-llndk_library {
-    name: "libGLESv1_CM.llndk",
-    symbol_file: "libGLESv1_CM.map.txt",
-    export_llndk_headers: ["gl_llndk_headers"],
-}
-
-llndk_library {
-    name: "libGLESv2.llndk",
-    symbol_file: "libGLESv2.map.txt",
-    export_llndk_headers: ["gl_llndk_headers"],
-}
-
-llndk_library {
-    name: "libGLESv3.llndk",
-    symbol_file: "libGLESv3.map.txt",
-    export_llndk_headers: ["gl_llndk_headers"],
-}
diff --git a/services/surfaceflinger/Clock.h b/services/surfaceflinger/Clock.h
new file mode 100644
index 0000000..3f23c6d
--- /dev/null
+++ b/services/surfaceflinger/Clock.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 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.
+ */
+
+#pragma once
+
+#include <chrono>
+
+namespace android {
+
+// Abstract interface for timekeeping which can be injected for unit tests.
+class Clock {
+public:
+    Clock() = default;
+    virtual ~Clock() = default;
+
+    // Returns the current time
+    virtual std::chrono::steady_clock::time_point now() const = 0;
+};
+
+class SteadyClock : public Clock {
+public:
+    virtual ~SteadyClock() = default;
+
+    std::chrono::steady_clock::time_point now() const override {
+        return std::chrono::steady_clock::now();
+    }
+};
+
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/FpsReporter.cpp b/services/surfaceflinger/FpsReporter.cpp
index 0bc2d3e..23db805 100644
--- a/services/surfaceflinger/FpsReporter.cpp
+++ b/services/surfaceflinger/FpsReporter.cpp
@@ -26,10 +26,18 @@
 
 namespace android {
 
-FpsReporter::FpsReporter(frametimeline::FrameTimeline& frameTimeline, SurfaceFlinger& flinger)
-      : mFrameTimeline(frameTimeline), mFlinger(flinger) {}
+FpsReporter::FpsReporter(frametimeline::FrameTimeline& frameTimeline, SurfaceFlinger& flinger,
+                         std::unique_ptr<Clock> clock)
+      : mFrameTimeline(frameTimeline), mFlinger(flinger), mClock(std::move(clock)) {
+    LOG_ALWAYS_FATAL_IF(mClock == nullptr, "Passed in null clock when constructing FpsReporter!");
+}
 
-void FpsReporter::dispatchLayerFps() const {
+void FpsReporter::dispatchLayerFps() {
+    const auto now = mClock->now();
+    if (now - mLastDispatch < kMinDispatchDuration) {
+        return;
+    }
+
     std::vector<TrackedListener> localListeners;
     {
         std::scoped_lock lock(mMutex);
@@ -71,6 +79,8 @@
 
         listener.listener->onFpsReported(mFrameTimeline.computeFps(layerIds));
     }
+
+    mLastDispatch = now;
 }
 
 void FpsReporter::binderDied(const wp<IBinder>& who) {
diff --git a/services/surfaceflinger/FpsReporter.h b/services/surfaceflinger/FpsReporter.h
index 1cec295..bd7b9a5 100644
--- a/services/surfaceflinger/FpsReporter.h
+++ b/services/surfaceflinger/FpsReporter.h
@@ -22,6 +22,7 @@
 
 #include <unordered_map>
 
+#include "Clock.h"
 #include "FrameTimeline/FrameTimeline.h"
 
 namespace android {
@@ -31,12 +32,13 @@
 
 class FpsReporter : public IBinder::DeathRecipient {
 public:
-    FpsReporter(frametimeline::FrameTimeline& frameTimeline, SurfaceFlinger& flinger);
+    FpsReporter(frametimeline::FrameTimeline& frameTimeline, SurfaceFlinger& flinger,
+                std::unique_ptr<Clock> clock = std::make_unique<SteadyClock>());
 
     // Dispatches updated layer fps values for the registered listeners
     // This method promotes Layer weak pointers and performs layer stack traversals, so mStateLock
     // must be held when calling this method.
-    void dispatchLayerFps() const EXCLUDES(mMutex);
+    void dispatchLayerFps() EXCLUDES(mMutex);
 
     // Override for IBinder::DeathRecipient
     void binderDied(const wp<IBinder>&) override;
@@ -61,6 +63,10 @@
 
     frametimeline::FrameTimeline& mFrameTimeline;
     SurfaceFlinger& mFlinger;
+    static const constexpr std::chrono::steady_clock::duration kMinDispatchDuration =
+            std::chrono::milliseconds(500);
+    std::unique_ptr<Clock> mClock;
+    std::chrono::steady_clock::time_point mLastDispatch;
     std::unordered_map<wp<IBinder>, TrackedListener, WpHash> mListeners GUARDED_BY(mMutex);
 };
 
diff --git a/services/surfaceflinger/Scheduler/OneShotTimer.cpp b/services/surfaceflinger/Scheduler/OneShotTimer.cpp
index d659398..16f041a 100644
--- a/services/surfaceflinger/Scheduler/OneShotTimer.cpp
+++ b/services/surfaceflinger/Scheduler/OneShotTimer.cpp
@@ -15,7 +15,6 @@
  */
 
 #include "OneShotTimer.h"
-
 #include <utils/Log.h>
 #include <utils/Timers.h>
 #include <chrono>
@@ -40,14 +39,9 @@
 namespace android {
 namespace scheduler {
 
-std::chrono::steady_clock::time_point OneShotTimer::Clock::now() const {
-    return std::chrono::steady_clock::now();
-}
-
 OneShotTimer::OneShotTimer(std::string name, const Interval& interval,
                            const ResetCallback& resetCallback,
-                           const TimeoutCallback& timeoutCallback,
-                           std::unique_ptr<OneShotTimer::Clock> clock)
+                           const TimeoutCallback& timeoutCallback, std::unique_ptr<Clock> clock)
       : mClock(std::move(clock)),
         mName(std::move(name)),
         mInterval(interval),
diff --git a/services/surfaceflinger/Scheduler/OneShotTimer.h b/services/surfaceflinger/Scheduler/OneShotTimer.h
index 7285427..09265bb 100644
--- a/services/surfaceflinger/Scheduler/OneShotTimer.h
+++ b/services/surfaceflinger/Scheduler/OneShotTimer.h
@@ -20,6 +20,7 @@
 #include <chrono>
 #include <condition_variable>
 #include <thread>
+#include "../Clock.h"
 
 #include <android-base/thread_annotations.h>
 
@@ -36,17 +37,9 @@
     using ResetCallback = std::function<void()>;
     using TimeoutCallback = std::function<void()>;
 
-    class Clock {
-    public:
-        Clock() = default;
-        virtual ~Clock() = default;
-
-        virtual std::chrono::steady_clock::time_point now() const;
-    };
-
     OneShotTimer(std::string name, const Interval& interval, const ResetCallback& resetCallback,
                  const TimeoutCallback& timeoutCallback,
-                 std::unique_ptr<OneShotTimer::Clock> = std::make_unique<OneShotTimer::Clock>());
+                 std::unique_ptr<Clock> clock = std::make_unique<SteadyClock>());
     ~OneShotTimer();
 
     // Initializes and turns on the idle timer.
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 57bd045..fac2c65 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -583,13 +583,9 @@
 
     scheduler::LayerHistory::LayerVoteType voteType;
 
-    if (layer->getWindowType() == InputWindowInfo::Type::STATUS_BAR) {
+    if (!mOptions.useContentDetection ||
+        layer->getWindowType() == InputWindowInfo::Type::STATUS_BAR) {
         voteType = scheduler::LayerHistory::LayerVoteType::NoVote;
-    } else if (!mOptions.useContentDetection) {
-        // If the content detection feature is off, all layers are registered at Max. We still keep
-        // the layer history, since we use it for other features (like Frame Rate API), so layers
-        // still need to be registered.
-        voteType = scheduler::LayerHistory::LayerVoteType::Max;
     } else if (layer->getWindowType() == InputWindowInfo::Type::WALLPAPER) {
         // Running Wallpaper at Min is considered as part of content detection.
         voteType = scheduler::LayerHistory::LayerVoteType::Min;
@@ -597,6 +593,9 @@
         voteType = scheduler::LayerHistory::LayerVoteType::Heuristic;
     }
 
+    // If the content detection feature is off, we still keep the layer history,
+    // since we use it for other features (like Frame Rate API), so layers
+    // still need to be registered.
     mLayerHistory->registerLayer(layer, voteType);
 }
 
diff --git a/services/surfaceflinger/tests/unittests/FpsReporterTest.cpp b/services/surfaceflinger/tests/unittests/FpsReporterTest.cpp
index a2291b2..dec0ff5 100644
--- a/services/surfaceflinger/tests/unittests/FpsReporterTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FpsReporterTest.cpp
@@ -28,6 +28,7 @@
 #include "FpsReporter.h"
 #include "Layer.h"
 #include "TestableSurfaceFlinger.h"
+#include "fake/FakeClock.h"
 #include "mock/DisplayHardware/MockComposer.h"
 #include "mock/MockEventThread.h"
 #include "mock/MockFrameTimeline.h"
@@ -91,7 +92,9 @@
     sp<Layer> mUnrelated;
 
     sp<TestableFpsListener> mFpsListener;
-    sp<FpsReporter> mFpsReporter = new FpsReporter(mFrameTimeline, *(mFlinger.flinger()));
+    fake::FakeClock* mClock = new fake::FakeClock();
+    sp<FpsReporter> mFpsReporter =
+            new FpsReporter(mFrameTimeline, *(mFlinger.flinger()), std::unique_ptr<Clock>(mClock));
 };
 
 FpsReporterTest::FpsReporterTest() {
@@ -178,6 +181,7 @@
             .WillOnce(Return(expectedFps));
 
     mFpsReporter->addListener(mFpsListener, kTaskId);
+    mClock->advanceTime(600ms);
     mFpsReporter->dispatchLayerFps();
     EXPECT_EQ(expectedFps, mFpsListener->lastReportedFps);
     mFpsReporter->removeListener(mFpsListener);
@@ -187,5 +191,34 @@
     mFpsReporter->dispatchLayerFps();
 }
 
+TEST_F(FpsReporterTest, rateLimits) {
+    const constexpr int32_t kTaskId = 12;
+    LayerMetadata targetMetadata;
+    targetMetadata.setInt32(METADATA_TASK_ID, kTaskId);
+    mTarget = createBufferStateLayer(targetMetadata);
+    mFlinger.mutableCurrentState().layersSortedByZ.add(mTarget);
+
+    float firstFps = 44.0;
+    float secondFps = 53.0;
+
+    EXPECT_CALL(mFrameTimeline, computeFps(UnorderedElementsAre(mTarget->getSequence())))
+            .WillOnce(Return(firstFps))
+            .WillOnce(Return(secondFps));
+
+    mFpsReporter->addListener(mFpsListener, kTaskId);
+    mClock->advanceTime(600ms);
+    mFpsReporter->dispatchLayerFps();
+    EXPECT_EQ(firstFps, mFpsListener->lastReportedFps);
+    mClock->advanceTime(200ms);
+    mFpsReporter->dispatchLayerFps();
+    EXPECT_EQ(firstFps, mFpsListener->lastReportedFps);
+    mClock->advanceTime(200ms);
+    mFpsReporter->dispatchLayerFps();
+    EXPECT_EQ(firstFps, mFpsListener->lastReportedFps);
+    mClock->advanceTime(200ms);
+    mFpsReporter->dispatchLayerFps();
+    EXPECT_EQ(secondFps, mFpsListener->lastReportedFps);
+}
+
 } // namespace
 } // namespace android
diff --git a/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp b/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp
index a1f0588..6916764 100644
--- a/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp
@@ -23,23 +23,13 @@
 
 #include "AsyncCallRecorder.h"
 #include "Scheduler/OneShotTimer.h"
+#include "fake/FakeClock.h"
 
 using namespace std::chrono_literals;
 
 namespace android {
 namespace scheduler {
 
-class FakeClock : public OneShotTimer::Clock {
-public:
-    virtual ~FakeClock() = default;
-    std::chrono::steady_clock::time_point now() const override { return mNow; }
-
-    void advanceTime(std::chrono::nanoseconds delta) { mNow += delta; }
-
-private:
-    std::chrono::steady_clock::time_point mNow;
-};
-
 class OneShotTimerTest : public testing::Test {
 protected:
     OneShotTimerTest() = default;
@@ -58,17 +48,17 @@
 
 namespace {
 TEST_F(OneShotTimerTest, createAndDestroyTest) {
-    FakeClock* clock = new FakeClock();
+    fake::FakeClock* clock = new fake::FakeClock();
     mIdleTimer = std::make_unique<scheduler::OneShotTimer>(
-            "TestTimer", 3ms, [] {}, [] {}, std::unique_ptr<FakeClock>(clock));
+            "TestTimer", 3ms, [] {}, [] {}, std::unique_ptr<fake::FakeClock>(clock));
 }
 
 TEST_F(OneShotTimerTest, startStopTest) {
-    FakeClock* clock = new FakeClock();
+    fake::FakeClock* clock = new fake::FakeClock();
     mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
                                                            mResetTimerCallback.getInvocable(),
                                                            mExpiredTimerCallback.getInvocable(),
-                                                           std::unique_ptr<FakeClock>(clock));
+                                                           std::unique_ptr<fake::FakeClock>(clock));
     mIdleTimer->start();
     EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
     EXPECT_FALSE(mExpiredTimerCallback.waitForUnexpectedCall().has_value());
@@ -83,11 +73,11 @@
 }
 
 TEST_F(OneShotTimerTest, resetTest) {
-    FakeClock* clock = new FakeClock();
+    fake::FakeClock* clock = new fake::FakeClock();
     mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
                                                            mResetTimerCallback.getInvocable(),
                                                            mExpiredTimerCallback.getInvocable(),
-                                                           std::unique_ptr<FakeClock>(clock));
+                                                           std::unique_ptr<fake::FakeClock>(clock));
 
     mIdleTimer->start();
     EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
@@ -105,11 +95,11 @@
 }
 
 TEST_F(OneShotTimerTest, resetBackToBackTest) {
-    FakeClock* clock = new FakeClock();
+    fake::FakeClock* clock = new fake::FakeClock();
     mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
                                                            mResetTimerCallback.getInvocable(),
                                                            mExpiredTimerCallback.getInvocable(),
-                                                           std::unique_ptr<FakeClock>(clock));
+                                                           std::unique_ptr<fake::FakeClock>(clock));
     mIdleTimer->start();
     EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
 
@@ -139,11 +129,11 @@
 }
 
 TEST_F(OneShotTimerTest, startNotCalledTest) {
-    FakeClock* clock = new FakeClock();
+    fake::FakeClock* clock = new fake::FakeClock();
     mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
                                                            mResetTimerCallback.getInvocable(),
                                                            mExpiredTimerCallback.getInvocable(),
-                                                           std::unique_ptr<FakeClock>(clock));
+                                                           std::unique_ptr<fake::FakeClock>(clock));
     // The start hasn't happened, so the callback does not happen.
     EXPECT_FALSE(mExpiredTimerCallback.waitForUnexpectedCall().has_value());
     EXPECT_FALSE(mResetTimerCallback.waitForUnexpectedCall().has_value());
@@ -155,11 +145,11 @@
 }
 
 TEST_F(OneShotTimerTest, idleTimerIdlesTest) {
-    FakeClock* clock = new FakeClock();
+    fake::FakeClock* clock = new fake::FakeClock();
     mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
                                                            mResetTimerCallback.getInvocable(),
                                                            mExpiredTimerCallback.getInvocable(),
-                                                           std::unique_ptr<FakeClock>(clock));
+                                                           std::unique_ptr<fake::FakeClock>(clock));
     mIdleTimer->start();
     EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
     clock->advanceTime(2ms);
@@ -180,11 +170,11 @@
 }
 
 TEST_F(OneShotTimerTest, timeoutCallbackExecutionTest) {
-    FakeClock* clock = new FakeClock();
+    fake::FakeClock* clock = new fake::FakeClock();
     mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
                                                            mResetTimerCallback.getInvocable(),
                                                            mExpiredTimerCallback.getInvocable(),
-                                                           std::unique_ptr<FakeClock>(clock));
+                                                           std::unique_ptr<fake::FakeClock>(clock));
     mIdleTimer->start();
     EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
 
@@ -197,11 +187,11 @@
 }
 
 TEST_F(OneShotTimerTest, noCallbacksAfterStopAndResetTest) {
-    FakeClock* clock = new FakeClock();
+    fake::FakeClock* clock = new fake::FakeClock();
     mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
                                                            mResetTimerCallback.getInvocable(),
                                                            mExpiredTimerCallback.getInvocable(),
-                                                           std::unique_ptr<FakeClock>(clock));
+                                                           std::unique_ptr<fake::FakeClock>(clock));
     mIdleTimer->start();
     EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
     clock->advanceTime(2ms);
@@ -215,11 +205,11 @@
 }
 
 TEST_F(OneShotTimerTest, noCallbacksAfterStopTest) {
-    FakeClock* clock = new FakeClock();
+    fake::FakeClock* clock = new fake::FakeClock();
     mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
                                                            mResetTimerCallback.getInvocable(),
                                                            mExpiredTimerCallback.getInvocable(),
-                                                           std::unique_ptr<FakeClock>(clock));
+                                                           std::unique_ptr<fake::FakeClock>(clock));
     mIdleTimer->start();
     EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
     EXPECT_FALSE(mExpiredTimerCallback.waitForUnexpectedCall().has_value());
diff --git a/services/surfaceflinger/tests/unittests/fake/FakeClock.h b/services/surfaceflinger/tests/unittests/fake/FakeClock.h
new file mode 100644
index 0000000..6d9c764
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/fake/FakeClock.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 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.
+ */
+
+#pragma once
+
+#include "../../Clock.h"
+
+namespace android::fake {
+
+class FakeClock : public Clock {
+public:
+    virtual ~FakeClock() = default;
+    std::chrono::steady_clock::time_point now() const override { return mNow; }
+
+    void advanceTime(std::chrono::nanoseconds delta) { mNow += delta; }
+
+private:
+    std::chrono::steady_clock::time_point mNow;
+};
+
+} // namespace android::fake
\ No newline at end of file
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index 67cd875..d4cb928 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -29,17 +29,14 @@
     unversioned_until: "current",
 }
 
-llndk_library {
-    name: "libvulkan.llndk",
-    symbol_file: "libvulkan.map.txt",
-    export_llndk_headers: [
-        "vulkan_headers_llndk",
-    ],
-}
-
 cc_library_shared {
     name: "libvulkan",
-    llndk_stubs: "libvulkan.llndk",
+    llndk: {
+        symbol_file: "libvulkan.map.txt",
+        export_llndk_headers: [
+            "vulkan_headers_llndk",
+        ],
+    },
     clang: true,
     sanitize: {
         misc_undefined: ["integer"],