Merge "Remove gpumemtracer bloat"
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 7aac7da..b21010d 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -494,7 +494,7 @@
     sp<BpBinder> bpBinder = binder->remoteBinder();
     if (bpBinder == nullptr) return -1;
 
-    return ProcessState::self()->getStrongRefCountForNodeByHandle(bpBinder->handle());
+    return ProcessState::self()->getStrongRefCountForNode(bpBinder);
 }
 
 void ServiceManager::handleClientCallbacks() {
diff --git a/include/audiomanager/AudioManager.h b/include/audiomanager/AudioManager.h
index 4aa2f60..639df7a 100644
--- a/include/audiomanager/AudioManager.h
+++ b/include/audiomanager/AudioManager.h
@@ -37,7 +37,6 @@
     PLAYER_STATE_STARTED  = 2,
     PLAYER_STATE_PAUSED   = 3,
     PLAYER_STATE_STOPPED  = 4,
-    PLAYER_UPDATE_DEVICE_ID = 5,
 } player_state_t;
 
 // must be kept in sync with definitions in AudioManager.java
diff --git a/include/audiomanager/IAudioManager.h b/include/audiomanager/IAudioManager.h
index 7d1f38f..2f5ccb8 100644
--- a/include/audiomanager/IAudioManager.h
+++ b/include/audiomanager/IAudioManager.h
@@ -49,8 +49,7 @@
                 audio_content_type_t content, const sp<IBinder>& player) = 0;
     /*oneway*/ virtual status_t playerAttributes(audio_unique_id_t piid, audio_usage_t usage,
                 audio_content_type_t content)= 0;
-    /*oneway*/ virtual status_t playerEvent(audio_unique_id_t piid, player_state_t event,
-                audio_port_handle_t deviceId) = 0;
+    /*oneway*/ virtual status_t playerEvent(audio_unique_id_t piid, player_state_t event) = 0;
     /*oneway*/ virtual status_t releasePlayer(audio_unique_id_t piid) = 0;
     virtual audio_unique_id_t trackRecorder(const sp<IBinder>& recorder) = 0;
     /*oneway*/ virtual status_t recorderEvent(audio_unique_id_t riid, recorder_state_t event) = 0;
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 91e465f..b90cc27 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -206,7 +206,7 @@
             if (proxy == nullptr) {
                 ALOGE("null proxy");
             }
-            const int32_t handle = proxy ? proxy->handle() : 0;
+            const int32_t handle = proxy ? proxy->getPrivateAccessorForHandle().handle() : 0;
             obj.hdr.type = BINDER_TYPE_HANDLE;
             obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
             obj.handle = handle;
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 9aedf28..6f26450 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -204,11 +204,11 @@
 // that the handle points to. Can only be used by the servicemanager.
 //
 // Returns -1 in case of failure, otherwise the strong reference count.
-ssize_t ProcessState::getStrongRefCountForNodeByHandle(int32_t handle) {
+ssize_t ProcessState::getStrongRefCountForNode(const sp<BpBinder>& binder) {
     binder_node_info_for_ref info;
     memset(&info, 0, sizeof(binder_node_info_for_ref));
 
-    info.handle = handle;
+    info.handle = binder->getPrivateAccessorForHandle().handle();
 
     status_t result = ioctl(mDriverFD, BINDER_GET_NODE_INFO_FOR_REF, &info);
 
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index 2735315..22300ac 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -29,6 +29,7 @@
 namespace internal {
 class Stability;
 }
+class ProcessState;
 
 using binder_proxy_limit_callback = void(*)(int);
 
@@ -37,8 +38,6 @@
 public:
     static BpBinder*    create(int32_t handle);
 
-    int32_t             handle() const;
-
     virtual const String16&    getInterfaceDescriptor() const;
     virtual bool        isBinderAlive() const;
     virtual status_t    pingBinder();
@@ -109,7 +108,23 @@
         KeyedVector<const void*, entry_t> mObjects;
     };
 
+    class PrivateAccessorForHandle {
+    private:
+        friend BpBinder;
+        friend ::android::Parcel;
+        friend ::android::ProcessState;
+        explicit PrivateAccessorForHandle(const BpBinder* binder) : mBinder(binder) {}
+        int32_t handle() const { return mBinder->handle(); }
+        const BpBinder* mBinder;
+    };
+    const PrivateAccessorForHandle getPrivateAccessorForHandle() const {
+        return PrivateAccessorForHandle(this);
+    }
+
 private:
+    friend PrivateAccessorForHandle;
+
+    int32_t             handle() const;
                         BpBinder(int32_t handle,int32_t trackedUid);
     virtual             ~BpBinder();
     virtual void        onFirstRef();
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 9f5260a..b49951b 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -504,9 +504,6 @@
                                             const binder_size_t* objects, size_t objectsCount,
                                             release_func relFunc);
 
-                        Parcel(const Parcel& o);
-    Parcel&             operator=(const Parcel& o);
-    
     status_t            finishWrite(size_t len);
     void                releaseObjects();
     void                acquireObjects();
diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h
index 46457cd..bab6469 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -70,7 +70,7 @@
                                 // 2. Temporary strong references held by the kernel during a
                                 //    transaction on the node.
                                 // It does NOT include local strong references to the node
-            ssize_t             getStrongRefCountForNodeByHandle(int32_t handle);
+            ssize_t             getStrongRefCountForNode(const sp<BpBinder>& binder);
 
             enum class CallRestriction {
                 // all calls okay
diff --git a/libs/binder/tests/fuzzers/BpBinderFuzzFunctions.h b/libs/binder/tests/fuzzers/BpBinderFuzzFunctions.h
index c685b41..6ca0e2f 100644
--- a/libs/binder/tests/fuzzers/BpBinderFuzzFunctions.h
+++ b/libs/binder/tests/fuzzers/BpBinderFuzzFunctions.h
@@ -48,9 +48,7 @@
 static const std::vector<std::function<void(FuzzedDataProvider*, const sp<BpBinder>&,
                                             const sp<IBinder::DeathRecipient>&)>>
         gBPBinderOperations =
-                {[](FuzzedDataProvider*, const sp<BpBinder>& bpbinder,
-                    const sp<IBinder::DeathRecipient>&) -> void { bpbinder->handle(); },
-                 [](FuzzedDataProvider* fdp, const sp<BpBinder>& bpbinder,
+                {[](FuzzedDataProvider* fdp, const sp<BpBinder>& bpbinder,
                     const sp<IBinder::DeathRecipient>& s_recipient) -> void {
                      // Clean up possible leftover memory.
                      wp<IBinder::DeathRecipient> outRecipient(nullptr);
diff --git a/libs/input/tests/InputDevice_test.cpp b/libs/input/tests/InputDevice_test.cpp
index e2cf245..f8f2f4e 100644
--- a/libs/input/tests/InputDevice_test.cpp
+++ b/libs/input/tests/InputDevice_test.cpp
@@ -43,7 +43,7 @@
                                                                   KEY_LAYOUT);
         ASSERT_FALSE(path.empty());
         base::Result<std::shared_ptr<KeyLayoutMap>> ret = KeyLayoutMap::load(path);
-        ASSERT_TRUE(ret) << "Cannot load KeyLayout at " << path;
+        ASSERT_TRUE(ret.ok()) << "Cannot load KeyLayout at " << path;
         mKeyMap.keyLayoutMap = std::move(*ret);
         mKeyMap.keyLayoutFile = path;
     }
@@ -58,7 +58,7 @@
         ASSERT_FALSE(path.empty()) << "KeyCharacterMap for " << name << " not found";
         base::Result<std::shared_ptr<KeyCharacterMap>> ret =
                 KeyCharacterMap::load(path, KeyCharacterMap::Format::BASE);
-        ASSERT_TRUE(ret) << "Cannot load KeyCharacterMap at " << path;
+        ASSERT_TRUE(ret.ok()) << "Cannot load KeyCharacterMap at " << path;
         mKeyMap.keyCharacterMap = *ret;
         mKeyMap.keyCharacterMapFile = path;
     }
@@ -82,4 +82,4 @@
     ASSERT_EQ(*map, *mKeyMap.keyCharacterMap);
 }
 
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 279e648..c88e298 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -222,6 +222,29 @@
     return err;
 }
 
+std::optional<RenderEngine::ContextPriority> GLESRenderEngine::createContextPriority(
+        const RenderEngineCreationArgs& args) {
+    if (!GLExtensions::getInstance().hasContextPriority()) {
+        return std::nullopt;
+    }
+
+    switch (args.contextPriority) {
+        case RenderEngine::ContextPriority::REALTIME:
+            if (gl::GLExtensions::getInstance().hasRealtimePriority()) {
+                return RenderEngine::ContextPriority::REALTIME;
+            } else {
+                ALOGI("Realtime priority unsupported, degrading gracefully to high priority");
+                return RenderEngine::ContextPriority::HIGH;
+            }
+        case RenderEngine::ContextPriority::HIGH:
+        case RenderEngine::ContextPriority::MEDIUM:
+        case RenderEngine::ContextPriority::LOW:
+            return args.contextPriority;
+        default:
+            return std::nullopt;
+    }
+}
+
 std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(const RenderEngineCreationArgs& args) {
     // initialize EGL for the default display
     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
@@ -235,6 +258,7 @@
         LOG_ALWAYS_FATAL("eglQueryString(EGL_VERSION) failed");
     }
 
+    // Use the Android impl to grab EGL_NV_context_priority_realtime
     const auto eglExtensions = eglQueryString(display, EGL_EXTENSIONS);
     if (!eglExtensions) {
         checkGlError(__FUNCTION__, __LINE__);
@@ -251,17 +275,16 @@
         config = chooseEglConfig(display, args.pixelFormat, /*logConfig*/ true);
     }
 
-    bool useContextPriority =
-            extensions.hasContextPriority() && args.contextPriority == ContextPriority::HIGH;
+    const std::optional<RenderEngine::ContextPriority> priority = createContextPriority(args);
     EGLContext protectedContext = EGL_NO_CONTEXT;
     if (args.enableProtectedContext && extensions.hasProtectedContent()) {
-        protectedContext = createEglContext(display, config, nullptr, useContextPriority,
-                                            Protection::PROTECTED);
+        protectedContext =
+                createEglContext(display, config, nullptr, priority, Protection::PROTECTED);
         ALOGE_IF(protectedContext == EGL_NO_CONTEXT, "Can't create protected context");
     }
 
-    EGLContext ctxt = createEglContext(display, config, protectedContext, useContextPriority,
-                                       Protection::UNPROTECTED);
+    EGLContext ctxt =
+            createEglContext(display, config, protectedContext, priority, Protection::UNPROTECTED);
 
     // if can't create a GL context, we can only abort.
     LOG_ALWAYS_FATAL_IF(ctxt == EGL_NO_CONTEXT, "EGLContext creation failed");
@@ -311,7 +334,6 @@
     ALOGI("extensions: %s", extensions.getExtensions());
     ALOGI("GL_MAX_TEXTURE_SIZE = %zu", engine->getMaxTextureSize());
     ALOGI("GL_MAX_VIEWPORT_DIMS = %zu", engine->getMaxViewportDims());
-
     return engine;
 }
 
@@ -802,6 +824,12 @@
     ALOGV("Failed to find image for buffer: %" PRIu64, bufferId);
 }
 
+int GLESRenderEngine::getContextPriority() {
+    int value;
+    eglQueryContext(mEGLDisplay, mEGLContext, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &value);
+    return value;
+}
+
 FloatRect GLESRenderEngine::setupLayerCropping(const LayerSettings& layer, Mesh& mesh) {
     // Translate win by the rounded corners rect coordinates, to have all values in
     // layer coordinate space.
@@ -1617,7 +1645,8 @@
 }
 
 EGLContext GLESRenderEngine::createEglContext(EGLDisplay display, EGLConfig config,
-                                              EGLContext shareContext, bool useContextPriority,
+                                              EGLContext shareContext,
+                                              std::optional<ContextPriority> contextPriority,
                                               Protection protection) {
     EGLint renderableType = 0;
     if (config == EGL_NO_CONFIG) {
@@ -1640,9 +1669,23 @@
     contextAttributes.reserve(7);
     contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
     contextAttributes.push_back(contextClientVersion);
-    if (useContextPriority) {
+    if (contextPriority) {
         contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG);
-        contextAttributes.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG);
+        switch (*contextPriority) {
+            case ContextPriority::REALTIME:
+                contextAttributes.push_back(EGL_CONTEXT_PRIORITY_REALTIME_NV);
+                break;
+            case ContextPriority::MEDIUM:
+                contextAttributes.push_back(EGL_CONTEXT_PRIORITY_MEDIUM_IMG);
+                break;
+            case ContextPriority::LOW:
+                contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LOW_IMG);
+                break;
+            case ContextPriority::HIGH:
+            default:
+                contextAttributes.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG);
+                break;
+        }
     }
     if (protection == Protection::PROTECTED) {
         contextAttributes.push_back(EGL_PROTECTED_CONTENT_EXT);
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index 92e1529..64d6c6b 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -71,6 +71,7 @@
                         const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
                         base::unique_fd&& bufferFence, base::unique_fd* drawFence) override;
     bool cleanupPostRender(CleanupMode mode) override;
+    int getContextPriority() override;
 
     EGLDisplay getEGLDisplay() const { return mEGLDisplay; }
     // Creates an output image for rendering to
@@ -116,8 +117,11 @@
     static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig);
     static GlesVersion parseGlesVersion(const char* str);
     static EGLContext createEglContext(EGLDisplay display, EGLConfig config,
-                                       EGLContext shareContext, bool useContextPriority,
+                                       EGLContext shareContext,
+                                       std::optional<ContextPriority> contextPriority,
                                        Protection protection);
+    static std::optional<RenderEngine::ContextPriority> createContextPriority(
+            const RenderEngineCreationArgs& args);
     static EGLSurface createStubEglPbufferSurface(EGLDisplay display, EGLConfig config,
                                                   int hwcFormat, Protection protection);
     std::unique_ptr<Framebuffer> createFramebuffer();
diff --git a/libs/renderengine/gl/GLExtensions.cpp b/libs/renderengine/gl/GLExtensions.cpp
index 2924b0e..3dd534e 100644
--- a/libs/renderengine/gl/GLExtensions.cpp
+++ b/libs/renderengine/gl/GLExtensions.cpp
@@ -120,6 +120,10 @@
     if (extensionSet.hasExtension("EGL_KHR_surfaceless_context")) {
         mHasSurfacelessContext = true;
     }
+
+    if (extensionSet.hasExtension("EGL_NV_context_priority_realtime")) {
+        mHasRealtimePriority = true;
+    }
 }
 
 char const* GLExtensions::getEGLVersion() const {
diff --git a/libs/renderengine/gl/GLExtensions.h b/libs/renderengine/gl/GLExtensions.h
index ef00009..e415ff3 100644
--- a/libs/renderengine/gl/GLExtensions.h
+++ b/libs/renderengine/gl/GLExtensions.h
@@ -41,6 +41,7 @@
     bool hasContextPriority() const { return mHasContextPriority; }
     bool hasSurfacelessContext() const { return mHasSurfacelessContext; }
     bool hasProtectedTexture() const { return mHasProtectedTexture; }
+    bool hasRealtimePriority() const { return mHasRealtimePriority; }
 
     void initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer, GLubyte const* version,
                            GLubyte const* extensions);
@@ -67,6 +68,7 @@
     bool mHasContextPriority = false;
     bool mHasSurfacelessContext = false;
     bool mHasProtectedTexture = false;
+    bool mHasRealtimePriority = false;
 
     String8 mVendor;
     String8 mRenderer;
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index ef12fd2..9157066 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -75,6 +75,7 @@
         LOW = 1,
         MEDIUM = 2,
         HIGH = 3,
+        REALTIME = 4,
     };
 
     enum class RenderEngineType {
@@ -181,6 +182,10 @@
                                 const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
                                 base::unique_fd&& bufferFence, base::unique_fd* drawFence) = 0;
     virtual void cleanFramebufferCache() = 0;
+    // Returns the priority this context was actually created with. Note: this may not be
+    // the same as specified at context creation time, due to implementation limits on the
+    // number of contexts that can be created at a specific priority level in the system.
+    virtual int getContextPriority() = 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 95ee925..2c34da4 100644
--- a/libs/renderengine/include/renderengine/mock/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -53,6 +53,7 @@
                           const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
                           base::unique_fd*));
     MOCK_METHOD0(cleanFramebufferCache, void());
+    MOCK_METHOD0(getContextPriority, int());
 };
 
 } // namespace mock
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 1f98a46..3d6b7af 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -169,17 +169,16 @@
         config = chooseEglConfig(display, args.pixelFormat, /*logConfig*/ true);
     }
 
-    bool useContextPriority =
-            extensions.hasContextPriority() && args.contextPriority == ContextPriority::HIGH;
     EGLContext protectedContext = EGL_NO_CONTEXT;
+    const std::optional<RenderEngine::ContextPriority> priority = createContextPriority(args);
     if (args.enableProtectedContext && extensions.hasProtectedContent()) {
-        protectedContext = createEglContext(display, config, nullptr, useContextPriority,
-                                            Protection::PROTECTED);
+        protectedContext =
+                createEglContext(display, config, nullptr, priority, Protection::PROTECTED);
         ALOGE_IF(protectedContext == EGL_NO_CONTEXT, "Can't create protected context");
     }
 
-    EGLContext ctxt = createEglContext(display, config, protectedContext, useContextPriority,
-                                       Protection::UNPROTECTED);
+    EGLContext ctxt =
+            createEglContext(display, config, protectedContext, priority, Protection::UNPROTECTED);
 
     // if can't create a GL context, we can only abort.
     LOG_ALWAYS_FATAL_IF(ctxt == EGL_NO_CONTEXT, "EGLContext creation failed");
@@ -832,7 +831,8 @@
 }
 
 EGLContext SkiaGLRenderEngine::createEglContext(EGLDisplay display, EGLConfig config,
-                                                EGLContext shareContext, bool useContextPriority,
+                                                EGLContext shareContext,
+                                                std::optional<ContextPriority> contextPriority,
                                                 Protection protection) {
     EGLint renderableType = 0;
     if (config == EGL_NO_CONFIG_KHR) {
@@ -855,9 +855,23 @@
     contextAttributes.reserve(7);
     contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
     contextAttributes.push_back(contextClientVersion);
-    if (useContextPriority) {
+    if (contextPriority) {
         contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG);
-        contextAttributes.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG);
+        switch (*contextPriority) {
+            case ContextPriority::REALTIME:
+                contextAttributes.push_back(EGL_CONTEXT_PRIORITY_REALTIME_NV);
+                break;
+            case ContextPriority::MEDIUM:
+                contextAttributes.push_back(EGL_CONTEXT_PRIORITY_MEDIUM_IMG);
+                break;
+            case ContextPriority::LOW:
+                contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LOW_IMG);
+                break;
+            case ContextPriority::HIGH:
+            default:
+                contextAttributes.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG);
+                break;
+        }
     }
     if (protection == Protection::PROTECTED) {
         contextAttributes.push_back(EGL_PROTECTED_CONTENT_EXT);
@@ -882,6 +896,29 @@
     return context;
 }
 
+std::optional<RenderEngine::ContextPriority> SkiaGLRenderEngine::createContextPriority(
+        const RenderEngineCreationArgs& args) {
+    if (!gl::GLExtensions::getInstance().hasContextPriority()) {
+        return std::nullopt;
+    }
+
+    switch (args.contextPriority) {
+        case RenderEngine::ContextPriority::REALTIME:
+            if (gl::GLExtensions::getInstance().hasRealtimePriority()) {
+                return RenderEngine::ContextPriority::REALTIME;
+            } else {
+                ALOGI("Realtime priority unsupported, degrading gracefully to high priority");
+                return RenderEngine::ContextPriority::HIGH;
+            }
+        case RenderEngine::ContextPriority::HIGH:
+        case RenderEngine::ContextPriority::MEDIUM:
+        case RenderEngine::ContextPriority::LOW:
+            return args.contextPriority;
+        default:
+            return std::nullopt;
+    }
+}
+
 EGLSurface SkiaGLRenderEngine::createPlaceholderEglPbufferSurface(EGLDisplay display,
                                                                   EGLConfig config, int hwcFormat,
                                                                   Protection protection) {
@@ -906,6 +943,12 @@
 
 void SkiaGLRenderEngine::cleanFramebufferCache() {}
 
+int SkiaGLRenderEngine::getContextPriority() {
+    int value;
+    eglQueryContext(mEGLDisplay, mEGLContext, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &value);
+    return value;
+}
+
 } // namespace skia
 } // namespace renderengine
 } // namespace android
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index b53250e..3d8c693 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -56,6 +56,7 @@
                         const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
                         base::unique_fd&& bufferFence, base::unique_fd* drawFence) override;
     void cleanFramebufferCache() override;
+    int getContextPriority() override;
     bool isProtected() const override { return mInProtectedContext; }
     bool supportsProtectedContent() const override;
     bool useProtectedContext(bool useProtectedContext) override;
@@ -68,8 +69,11 @@
 private:
     static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig);
     static EGLContext createEglContext(EGLDisplay display, EGLConfig config,
-                                       EGLContext shareContext, bool useContextPriority,
+                                       EGLContext shareContext,
+                                       std::optional<ContextPriority> contextPriority,
                                        Protection protection);
+    static std::optional<RenderEngine::ContextPriority> createContextPriority(
+            const RenderEngineCreationArgs& args);
     static EGLSurface createPlaceholderEglPbufferSurface(EGLDisplay display, EGLConfig config,
                                                          int hwcFormat, Protection protection);
     inline SkRect getSkRect(const FloatRect& layer);
diff --git a/libs/renderengine/skia/SkiaRenderEngine.h b/libs/renderengine/skia/SkiaRenderEngine.h
index 2352c7e..12b8586 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.h
+++ b/libs/renderengine/skia/SkiaRenderEngine.h
@@ -56,6 +56,7 @@
         return 0;
     };
     virtual bool cleanupPostRender(CleanupMode) override { return true; };
+    virtual int getContextPriority() override { return 0; }
 };
 
 } // namespace skia
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp
index 5453302..08f2949 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.cpp
+++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp
@@ -304,6 +304,21 @@
     resultFuture.wait();
 }
 
+int RenderEngineThreaded::getContextPriority() {
+    std::promise<int> resultPromise;
+    std::future<int> resultFuture = resultPromise.get_future();
+    {
+        std::lock_guard lock(mThreadMutex);
+        mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) {
+            ATRACE_NAME("REThreaded::getContextPriority");
+            int priority = instance.getContextPriority();
+            resultPromise.set_value(priority);
+        });
+    }
+    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 cdfbd04..8b1e2de 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.h
+++ b/libs/renderengine/threaded/RenderEngineThreaded.h
@@ -63,6 +63,7 @@
                         base::unique_fd&& bufferFence, base::unique_fd* drawFence) override;
 
     void cleanFramebufferCache() override;
+    int getContextPriority() override;
 
 private:
     void threadMain(CreateInstanceFactory factory);
diff --git a/opengl/Android.bp b/opengl/Android.bp
index 393ced7..48abdce 100644
--- a/opengl/Android.bp
+++ b/opengl/Android.bp
@@ -52,36 +52,17 @@
     license: "include/KHR/NOTICE",
 }
 
-llndk_library {
-    name: "libEGL.llndk",
-    symbol_file: "libs/libEGL.map.txt",
-    export_include_dirs: ["include"],
-}
-
-llndk_library {
-    name: "libGLESv1_CM.llndk",
-    symbol_file: "libs/libGLESv1_CM.map.txt",
-    export_include_dirs: ["include"],
-}
-
-llndk_library {
-    name: "libGLESv2.llndk",
-    symbol_file: "libs/libGLESv2.map.txt",
-    export_include_dirs: ["include"],
-}
-
-llndk_library {
-    name: "libGLESv3.llndk",
-    symbol_file: "libs/libGLESv3.map.txt",
-    export_include_dirs: ["include"],
-}
-
 cc_library_headers {
     name: "gl_headers",
     vendor_available: true,
     export_include_dirs: ["include"],
 }
 
+llndk_headers {
+    name: "gl_llndk_headers",
+    export_include_dirs: ["include"],
+}
+
 subdirs = [
     "*",
 ]
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 77d887c..5d17561 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -225,3 +225,27 @@
     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/audiomanager/IAudioManager.cpp b/services/audiomanager/IAudioManager.cpp
index 0d17265..6235f06 100644
--- a/services/audiomanager/IAudioManager.cpp
+++ b/services/audiomanager/IAudioManager.cpp
@@ -84,13 +84,11 @@
         return remote()->transact(PLAYER_ATTRIBUTES, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
-    virtual status_t playerEvent(audio_unique_id_t piid, player_state_t event,
-            audio_port_handle_t deviceId) {
+    virtual status_t playerEvent(audio_unique_id_t piid, player_state_t event) {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioManager::getInterfaceDescriptor());
         data.writeInt32((int32_t) piid);
         data.writeInt32((int32_t) event);
-        data.writeInt32((int32_t) deviceId);
         return remote()->transact(PLAYER_EVENT, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index 3d99589..a50e5c7 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -148,7 +148,7 @@
     }
 
     base::Result<std::unique_ptr<InputChannel>> channel = mDispatcher->createInputChannel(name);
-    if (!channel) {
+    if (!channel.ok()) {
         return binder::Status::fromExceptionCode(exceptionCodeFromStatusT(channel.error().code()),
                                                  channel.error().message().c_str());
     }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index d9c8457..38ee1eb 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -710,16 +710,17 @@
     // Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
     mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create(
             renderengine::RenderEngineCreationArgs::Builder()
-                .setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
-                .setImageCacheSize(maxFrameBufferAcquiredBuffers)
-                .setUseColorManagerment(useColorManagement)
-                .setEnableProtectedContext(enable_protected_contents(false))
-                .setPrecacheToneMapperShaderOnly(false)
-                .setSupportsBackgroundBlur(mSupportsBlur)
-                .setContextPriority(useContextPriority
-                        ? renderengine::RenderEngine::ContextPriority::HIGH
-                        : renderengine::RenderEngine::ContextPriority::MEDIUM)
-                .build()));
+                    .setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
+                    .setImageCacheSize(maxFrameBufferAcquiredBuffers)
+                    .setUseColorManagerment(useColorManagement)
+                    .setEnableProtectedContext(enable_protected_contents(false))
+                    .setPrecacheToneMapperShaderOnly(false)
+                    .setSupportsBackgroundBlur(mSupportsBlur)
+                    .setContextPriority(
+                            useContextPriority
+                                    ? renderengine::RenderEngine::ContextPriority::REALTIME
+                                    : renderengine::RenderEngine::ContextPriority::MEDIUM)
+                    .build()));
     mCompositionEngine->setTimeStats(mTimeStats);
     mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
     mCompositionEngine->getHwComposer().setConfiguration(this, getBE().mComposerSequenceId);
@@ -6355,10 +6356,7 @@
 }
 
 int SurfaceFlinger::getGPUContextPriority() {
-    // TODO(b/168740533): This is a proof of concept. Once REAL time priority is available
-    // in EGL, we can return it in RenderEngine and propagate it to SurfaceFlinger. Until
-    // then return IntentFilter.SYSTEM_HIGH_PRIORITY.
-    return 1000;
+    return getRenderEngine().getContextPriority();
 }
 
 } // namespace android