Merge "[SurfaceFlinger] Remove unused functions." into qt-dev
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
index 180fd97..53ca7ea 100644
--- a/libs/dumputils/dump_utils.cpp
+++ b/libs/dumputils/dump_utils.cpp
@@ -37,6 +37,7 @@
         "/system/bin/surfaceflinger",
         "/system/bin/vehicle_network_service",
         "/vendor/bin/hw/android.hardware.media.omx@1.0-service", // media.codec
+        "/apex/com.android.media.swcodec/bin/mediaswcodec", // media.swcodec
         NULL,
 };
 
@@ -50,6 +51,7 @@
         "android.hardware.graphics.allocator@2.0::IAllocator",
         "android.hardware.graphics.composer@2.1::IComposer",
         "android.hardware.health@2.0::IHealth",
+        "android.hardware.media.c2@1.0::IComponentStore",
         "android.hardware.media.omx@1.0::IOmx",
         "android.hardware.media.omx@1.0::IOmxStore",
         "android.hardware.power.stats@1.0::IPowerStats",
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index 55efcbf..23bfc02 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -84,6 +84,9 @@
     
     explicit SurfaceControl(const sp<SurfaceControl>& other);
 
+    SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
+                   const sp<IGraphicBufferProducer>& gbp, bool owned);
+
 private:
     // can't be copied
     SurfaceControl& operator = (SurfaceControl& rhs);
@@ -92,12 +95,6 @@
     friend class SurfaceComposerClient;
     friend class Surface;
 
-    SurfaceControl(
-            const sp<SurfaceComposerClient>& client,
-            const sp<IBinder>& handle,
-            const sp<IGraphicBufferProducer>& gbp,
-            bool owned);
-
     ~SurfaceControl();
 
     sp<Surface> generateSurfaceLocked() const;
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index c1805be..10dd8cb 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -39,10 +39,7 @@
 #include "egldefs.h"
 #include <EGL/eglext_angle.h>
 
-// ----------------------------------------------------------------------------
 namespace android {
-// ----------------------------------------------------------------------------
-
 
 /*
  * EGL userspace drivers must be provided either:
@@ -122,8 +119,6 @@
     return android_load_sphal_library(path, mode);
 }
 
-// ----------------------------------------------------------------------------
-
 Loader::driver_t::driver_t(void* gles)
 {
     dso[0] = gles;
@@ -159,8 +154,6 @@
     return 0;
 }
 
-// ----------------------------------------------------------------------------
-
 Loader::Loader()
     : getProcAddress(nullptr)
 {
@@ -220,9 +213,6 @@
     ATRACE_CALL();
     const nsecs_t openTime = systemTime();
 
-    void* dso;
-    driver_t* hnd = nullptr;
-
     setEmulatorGlesValue();
 
     // Check if we should use ANGLE early, so loading each driver doesn't require repeated queries.
@@ -232,19 +222,19 @@
         cnx->shouldUseAngle = false;
     }
 
-    dso = load_driver("GLES", cnx, EGL | GLESv1_CM | GLESv2);
-    if (dso) {
-        hnd = new driver_t(dso);
-    } else {
-        android::GraphicsEnv::getInstance().clearDriverLoadingInfo(
-                android::GraphicsEnv::Api::API_GL);
-        // Always load EGL first
-        dso = load_driver("EGL", cnx, EGL);
-        if (dso) {
-            hnd = new driver_t(dso);
-            hnd->set( load_driver("GLESv1_CM", cnx, GLESv1_CM), GLESv1_CM );
-            hnd->set( load_driver("GLESv2",    cnx, GLESv2),    GLESv2 );
-        }
+    // Firstly, try to load ANGLE driver.
+    driver_t* hnd = attempt_to_load_angle(cnx);
+    if (!hnd) {
+        // Secondly, try to load from driver apk.
+        hnd = attempt_to_load_updated_driver(cnx);
+    }
+    if (!hnd) {
+        // Thirdly, try to load emulation driver.
+        hnd = attempt_to_load_emulation_driver(cnx);
+    }
+    if (!hnd) {
+        // Finally, load system driver.
+        hnd = attempt_to_load_system_driver(cnx);
     }
 
     if (!hnd) {
@@ -360,7 +350,7 @@
     }
 }
 
-static void* attempt_to_load_emulation_driver(const char* kind) {
+static void* load_emulation_driver(const char* kind) {
     const int emulationStatus = checkGlesEmulationStatus();
 
     // Invalid emulation status, abort.
@@ -547,11 +537,6 @@
 }
 
 static void* load_angle(const char* kind, android_namespace_t* ns, egl_connection_t* cnx) {
-    // Only attempt to load ANGLE libs
-    if (strcmp(kind, "EGL") != 0 && strcmp(kind, "GLESv2") != 0 && strcmp(kind, "GLESv1_CM") != 0) {
-        return nullptr;
-    }
-
     void* so = nullptr;
 
     if ((cnx->shouldUseAngle) || android::GraphicsEnv::getInstance().shouldUseAngle()) {
@@ -626,46 +611,119 @@
     return nullptr;
 }
 
-void *Loader::load_driver(const char* kind,
-        egl_connection_t* cnx, uint32_t mask)
-{
+Loader::driver_t* Loader::attempt_to_load_angle(egl_connection_t* cnx) {
     ATRACE_CALL();
-
-    void* dso = nullptr;
     android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
-    if (ns) {
-        android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::ANGLE);
-        dso = load_angle(kind, ns, cnx);
-        if (dso) {
-            initialize_api(dso, cnx, mask);
-            return dso;
-        }
+    if (!ns) {
+        return nullptr;
     }
+
+    android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::ANGLE);
+    driver_t* hnd = nullptr;
+
+    // ANGLE doesn't ship with GLES library, and thus we skip GLES driver.
+    void* dso = load_angle("EGL", ns, cnx);
+    if (dso) {
+        initialize_api(dso, cnx, EGL);
+        hnd = new driver_t(dso);
+
+        dso = load_angle("GLESv1_CM", ns, cnx);
+        initialize_api(dso, cnx, GLESv1_CM);
+        hnd->set(dso, GLESv1_CM);
+
+        dso = load_angle("GLESv2", ns, cnx);
+        initialize_api(dso, cnx, GLESv2);
+        hnd->set(dso, GLESv2);
+    }
+    return hnd;
+}
+
+Loader::driver_t* Loader::attempt_to_load_updated_driver(egl_connection_t* cnx) {
+    ATRACE_CALL();
 #ifndef __ANDROID_VNDK__
-    ns = android::GraphicsEnv::getInstance().getDriverNamespace();
-    if (ns) {
-        android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL_UPDATED);
-        dso = load_updated_driver(kind, ns);
-        if (dso) {
-            initialize_api(dso, cnx, mask);
-            return dso;
-        }
-    }
-#endif
-    android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL);
-    dso = attempt_to_load_emulation_driver(kind);
-    if (dso) {
-        initialize_api(dso, cnx, mask);
-        return dso;
+    android_namespace_t* ns = android::GraphicsEnv::getInstance().getDriverNamespace();
+    if (!ns) {
+        return nullptr;
     }
 
-    dso = load_system_driver(kind);
+    android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL_UPDATED);
+    driver_t* hnd = nullptr;
+    void* dso = load_updated_driver("GLES", ns);
     if (dso) {
-        initialize_api(dso, cnx, mask);
-        return dso;
+        initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2);
+        hnd = new driver_t(dso);
+        return hnd;
     }
 
+    dso = load_updated_driver("EGL", ns);
+    if (dso) {
+        initialize_api(dso, cnx, EGL);
+        hnd = new driver_t(dso);
+
+        dso = load_updated_driver("GLESv1_CM", ns);
+        initialize_api(dso, cnx, GLESv1_CM);
+        hnd->set(dso, GLESv1_CM);
+
+        dso = load_updated_driver("GLESv2", ns);
+        initialize_api(dso, cnx, GLESv2);
+        hnd->set(dso, GLESv2);
+    }
+    return hnd;
+#else
     return nullptr;
+#endif
+}
+
+Loader::driver_t* Loader::attempt_to_load_emulation_driver(egl_connection_t* cnx) {
+    ATRACE_CALL();
+    android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL);
+    driver_t* hnd = nullptr;
+    void* dso = load_emulation_driver("GLES");
+    if (dso) {
+        initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2);
+        hnd = new driver_t(dso);
+        return hnd;
+    }
+    dso = load_emulation_driver("EGL");
+    if (dso) {
+        initialize_api(dso, cnx, EGL);
+        hnd = new driver_t(dso);
+
+        dso = load_emulation_driver("GLESv1_CM");
+        initialize_api(dso, cnx, GLESv1_CM);
+        hnd->set(dso, GLESv1_CM);
+
+        dso = load_emulation_driver("GLESv2");
+        initialize_api(dso, cnx, GLESv2);
+        hnd->set(dso, GLESv2);
+    }
+    return hnd;
+}
+
+Loader::driver_t* Loader::attempt_to_load_system_driver(egl_connection_t* cnx) {
+    ATRACE_CALL();
+    android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL);
+    driver_t* hnd = nullptr;
+    void* dso = load_system_driver("GLES");
+    if (dso) {
+        initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2);
+        hnd = new driver_t(dso);
+        return hnd;
+    }
+    dso = load_system_driver("EGL");
+    if (dso) {
+        initialize_api(dso, cnx, EGL);
+        hnd = new driver_t(dso);
+
+        dso = load_system_driver("GLESv1_CM");
+        initialize_api(dso, cnx, GLESv1_CM);
+        hnd->set(dso, GLESv1_CM);
+
+        dso = load_system_driver("GLESv2");
+        initialize_api(dso, cnx, GLESv2);
+        hnd->set(dso, GLESv2);
+    }
+    return hnd;
 }
 
 void Loader::initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask) {
@@ -710,6 +768,4 @@
     }
 }
 
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
+} // namespace android
diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h
index 083c84e..c0f1b75 100644
--- a/opengl/libs/EGL/Loader.h
+++ b/opengl/libs/EGL/Loader.h
@@ -55,7 +55,10 @@
 
 private:
     Loader();
-    void *load_driver(const char* kind, egl_connection_t* cnx, uint32_t mask);
+    driver_t* attempt_to_load_angle(egl_connection_t* cnx);
+    driver_t* attempt_to_load_updated_driver(egl_connection_t* cnx);
+    driver_t* attempt_to_load_emulation_driver(egl_connection_t* cnx);
+    driver_t* attempt_to_load_system_driver(egl_connection_t* cnx);
     void initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask);
 
     static __attribute__((noinline))
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 2549d9b..b874411 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -3214,17 +3214,29 @@
 
             std::vector<sp<InputWindowHandle>> newHandles;
             for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
-                if (!handle->updateInfo() || (getInputChannelLocked(handle->getToken()) == nullptr
-                        && handle->getInfo()->portalToDisplayId == ADISPLAY_ID_NONE)) {
-                    ALOGE("Window handle %s has no registered input channel",
-                            handle->getName().c_str());
+                if (!handle->updateInfo()) {
+                    // handle no longer valid
+                    continue;
+                }
+                const InputWindowInfo* info = handle->getInfo();
+
+                if ((getInputChannelLocked(handle->getToken()) == nullptr &&
+                     info->portalToDisplayId == ADISPLAY_ID_NONE)) {
+                    const bool noInputChannel =
+                            info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
+                    const bool canReceiveInput =
+                            !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
+                            !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
+                    if (canReceiveInput && !noInputChannel) {
+                        ALOGE("Window handle %s has no registered input channel",
+                              handle->getName().c_str());
+                    }
                     continue;
                 }
 
-                if (handle->getInfo()->displayId != displayId) {
+                if (info->displayId != displayId) {
                     ALOGE("Window %s updated by wrong display %d, should belong to display %d",
-                        handle->getName().c_str(), displayId,
-                        handle->getInfo()->displayId);
+                          handle->getName().c_str(), displayId, info->displayId);
                     continue;
                 }
 
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 6ef4518..dabc683 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -425,7 +425,7 @@
 }
 
 Region BufferStateLayer::getDrawingSurfaceDamage() const {
-    return getDrawingState().surfaceDamageRegion;
+    return Region::INVALID_REGION;
 }
 
 const HdrMetadata& BufferStateLayer::getDrawingHdrMetadata() const {
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index e54b460..482c723 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -76,18 +76,9 @@
                                uint32_t flags, const sp<IBinder>& parentHandle,
                                LayerMetadata metadata, sp<IBinder>* handle,
                                sp<IGraphicBufferProducer>* gbp) {
-    sp<Layer> parent = nullptr;
-    if (parentHandle != nullptr) {
-        auto layerHandle = reinterpret_cast<Layer::Handle*>(parentHandle.get());
-        parent = layerHandle->owner.promote();
-        if (parent == nullptr) {
-            return NAME_NOT_FOUND;
-        }
-    }
-
     // We rely on createLayer to check permissions.
     return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
-                                 &parent);
+                                 parentHandle);
 }
 
 status_t Client::createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h,
@@ -104,9 +95,8 @@
         return BAD_VALUE;
     }
 
-    sp<IBinder> parentHandle = layer->getHandle();
-
-    return createSurface(name, w, h, format, flags, parentHandle, std::move(metadata), handle, gbp);
+    return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
+                                 nullptr, layer);
 }
 
 status_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 8249b03..46ca0b6 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -130,7 +130,6 @@
     }
 
     mFrameTracker.logAndResetStats(mName);
-
     mFlinger->onLayerDestroyed();
 }
 
@@ -205,6 +204,11 @@
 
 sp<IBinder> Layer::getHandle() {
     Mutex::Autolock _l(mLock);
+    if (mGetHandleCalled) {
+        ALOGE("Get handle called twice" );
+        return nullptr;
+    }
+    mGetHandleCalled = true;
     return new Handle(mFlinger, this);
 }
 
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index a8b72a0..3712b2a 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -791,6 +791,8 @@
         wp<Layer> owner;
     };
 
+    // Creates a new handle each time, so we only expect
+    // this to be called once.
     sp<IBinder> getHandle();
     const String8& getName() const;
     virtual void notifyAvailableFrames() {}
@@ -924,6 +926,8 @@
     FloatRect mScreenBounds;
 
     void setZOrderRelativeOf(const wp<Layer>& relativeOf);
+
+    bool mGetHandleCalled = false;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index e70bfe4..fcde8da 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -31,9 +31,9 @@
     const status_t ret =
             mFlinger.createLayer(String8("RefreshRateOverlay"), mClient, 0, 0,
                                  PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceColor,
-                                 LayerMetadata(), &mIBinder, &mGbp, &mLayer);
+                                 LayerMetadata(), &mIBinder, &mGbp, nullptr);
     if (ret) {
-        ALOGE("failed to color layer");
+        ALOGE("failed to create color layer");
         return false;
     }
 
@@ -47,7 +47,7 @@
 void RefreshRateOverlay::changeRefreshRate(RefreshRateType type) {
     const half3& color = (type == RefreshRateType::PERFORMANCE) ? GREEN : RED;
     mLayer->setColor(color);
-    mFlinger.setTransactionFlags(eTransactionMask);
+    mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
 }
 
 }; // namespace android
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 1b154a4..88d2638 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -318,12 +318,24 @@
 
 void Scheduler::updateFpsBasedOnContent() {
     uint32_t refreshRate = std::round(mLayerHistory.getDesiredRefreshRate());
-    ATRACE_INT("ContentFPS", refreshRate);
-    if (refreshRate > 0) {
-        contentChangeRefreshRate(ContentFeatureState::CONTENT_DETECTION_ON, refreshRate);
-    } else {
-        contentChangeRefreshRate(ContentFeatureState::CONTENT_DETECTION_OFF, 0);
+    RefreshRateType newRefreshRateType;
+    {
+        std::lock_guard<std::mutex> lock(mFeatureStateLock);
+        if (mContentRefreshRate == refreshRate) {
+            return;
+        }
+        mContentRefreshRate = refreshRate;
+        ATRACE_INT("ContentFPS", mContentRefreshRate);
+
+        mCurrentContentFeatureState = refreshRate > 0 ? ContentFeatureState::CONTENT_DETECTION_ON
+                                                      : ContentFeatureState::CONTENT_DETECTION_OFF;
+        newRefreshRateType = calculateRefreshRateType();
+        if (mRefreshRateType == newRefreshRateType) {
+            return;
+        }
+        mRefreshRateType = newRefreshRateType;
     }
+    changeRefreshRate(newRefreshRateType, ConfigEvent::Changed);
 }
 
 void Scheduler::setChangeRefreshRateCallback(
@@ -365,24 +377,19 @@
     return stream.str();
 }
 
-void Scheduler::contentChangeRefreshRate(ContentFeatureState contentFeatureState,
-                                         uint32_t refreshRate) {
-    RefreshRateType newRefreshRateType;
-    {
-        std::lock_guard<std::mutex> lock(mFeatureStateLock);
-        mCurrentContentFeatureState = contentFeatureState;
-        mContentRefreshRate = refreshRate;
-        newRefreshRateType = calculateRefreshRateType();
-    }
-    changeRefreshRate(newRefreshRateType, ConfigEvent::Changed);
-}
-
 void Scheduler::timerChangeRefreshRate(IdleTimerState idleTimerState) {
     RefreshRateType newRefreshRateType;
     {
         std::lock_guard<std::mutex> lock(mFeatureStateLock);
+        if (mCurrentIdleTimerState == idleTimerState) {
+            return;
+        }
         mCurrentIdleTimerState = idleTimerState;
         newRefreshRateType = calculateRefreshRateType();
+        if (mRefreshRateType == newRefreshRateType) {
+            return;
+        }
+        mRefreshRateType = newRefreshRateType;
     }
     changeRefreshRate(newRefreshRateType, ConfigEvent::None);
 }
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 134dc0b..34327b5 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -193,8 +193,6 @@
     void expiredTimerCallback();
     // Sets vsync period.
     void setVsyncPeriod(const nsecs_t period);
-    // Media feature's function to change the refresh rate.
-    void contentChangeRefreshRate(ContentFeatureState contentFeatureState, uint32_t refreshRate);
     // Idle timer feature's function to change the refresh rate.
     void timerChangeRefreshRate(IdleTimerState idleTimerState);
     // Calculate the new refresh rate type
@@ -254,7 +252,8 @@
     ContentFeatureState mCurrentContentFeatureState GUARDED_BY(mFeatureStateLock) =
             ContentFeatureState::CONTENT_DETECTION_OFF;
     IdleTimerState mCurrentIdleTimerState GUARDED_BY(mFeatureStateLock) = IdleTimerState::RESET;
-    uint32_t mContentRefreshRate;
+    uint32_t mContentRefreshRate GUARDED_BY(mFeatureStateLock);
+    RefreshRateType mRefreshRateType GUARDED_BY(mFeatureStateLock);
 
     const scheduler::RefreshRateConfigs& mRefreshRateConfigs;
 };
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 3744f8b..1d54cb2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1005,6 +1005,7 @@
         // display is not valid or we are already in the requested mode
         // on both cases there is nothing left to do
         std::lock_guard<std::mutex> lock(mActiveConfigLock);
+        mDesiredActiveConfig.event = Scheduler::ConfigEvent::None;
         mDesiredActiveConfigChanged = false;
         ATRACE_INT("DesiredActiveConfigChanged", mDesiredActiveConfigChanged);
         return false;
@@ -1017,6 +1018,8 @@
         std::lock_guard<std::mutex> lock(mActiveConfigLock);
         mDesiredActiveConfig.event = Scheduler::ConfigEvent::None;
         mDesiredActiveConfig.configId = display->getActiveConfig();
+        mDesiredActiveConfigChanged = false;
+        ATRACE_INT("DesiredActiveConfigChanged", mDesiredActiveConfigChanged);
         return false;
     }
     mUpcomingActiveConfig = desiredActiveConfig;
@@ -3398,21 +3401,31 @@
     engine.fillRegionWithColor(region, 0, 0, 0, 0);
 }
 
-status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
-        const sp<IBinder>& handle,
-        const sp<IGraphicBufferProducer>& gbc,
-        const sp<Layer>& lbc,
-        const sp<Layer>& parent,
-        bool addToCurrentState)
-{
+status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
+                                        const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc,
+                                        const sp<IBinder>& parentHandle,
+                                        const sp<Layer>& parentLayer, bool addToCurrentState) {
     // add this layer to the current state list
     {
         Mutex::Autolock _l(mStateLock);
+        sp<Layer> parent;
+        if (parentHandle != nullptr) {
+            parent = fromHandle(parentHandle);
+            if (parent == nullptr) {
+                return NAME_NOT_FOUND;
+            }
+        } else {
+            parent = parentLayer;
+        }
+
         if (mNumLayers >= MAX_LAYERS) {
             ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers,
                   MAX_LAYERS);
             return NO_MEMORY;
         }
+
+        mLayersByLocalBinderToken.emplace(handle->localBinder(), lbc);
+
         if (parent == nullptr && addToCurrentState) {
             mCurrentState.layersSortedByZ.add(lbc);
         } else if (parent == nullptr) {
@@ -4018,13 +4031,19 @@
 status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,
                                      uint32_t h, PixelFormat format, uint32_t flags,
                                      LayerMetadata metadata, sp<IBinder>* handle,
-                                     sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent) {
+                                     sp<IGraphicBufferProducer>* gbp,
+                                     const sp<IBinder>& parentHandle,
+                                     const sp<Layer>& parentLayer) {
     if (int32_t(w|h) < 0) {
         ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
                 int(w), int(h));
         return BAD_VALUE;
     }
 
+    ALOG_ASSERT(parentLayer == nullptr || parentHandle == nullptr,
+            "Expected only one of parentLayer or parentHandle to be non-null. "
+            "Programmer error?");
+
     status_t result = NO_ERROR;
 
     sp<Layer> layer;
@@ -4088,8 +4107,8 @@
     }
 
     bool addToCurrentState = callingThreadHasUnscopedSurfaceFlingerAccess();
-    result = addClientLayer(client, *handle, *gbp, layer, *parent,
-            addToCurrentState);
+    result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer,
+                            addToCurrentState);
     if (result != NO_ERROR) {
         return result;
     }
@@ -4206,6 +4225,16 @@
         mCurrentState.layersSortedByZ.remove(layer);
     }
     markLayerPendingRemovalLocked(layer);
+
+    auto it = mLayersByLocalBinderToken.begin();
+    while (it != mLayersByLocalBinderToken.end()) {
+        if (it->second == layer) {
+            it = mLayersByLocalBinderToken.erase(it);
+        } else {
+            it++;
+        }
+    }
+
     layer.clear();
 }
 
@@ -5486,34 +5515,50 @@
         const bool mChildrenOnly;
     };
 
-    auto layerHandle = reinterpret_cast<Layer::Handle*>(layerHandleBinder.get());
-    auto parent = layerHandle->owner.promote();
-
-    if (parent == nullptr || parent->isRemovedFromCurrentState()) {
-        ALOGE("captureLayers called with a removed parent");
-        return NAME_NOT_FOUND;
-    }
-
-    const int uid = IPCThreadState::self()->getCallingUid();
-    const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM;
-    if (!forSystem && parent->getCurrentState().flags & layer_state_t::eLayerSecure) {
-        ALOGW("Attempting to capture secure layer: PERMISSION_DENIED");
-        return PERMISSION_DENIED;
-    }
-
+    int reqWidth = 0;
+    int reqHeight = 0;
+    sp<Layer> parent;
     Rect crop(sourceCrop);
-    if (sourceCrop.width() <= 0) {
-        crop.left = 0;
-        crop.right = parent->getBufferSize(parent->getCurrentState()).getWidth();
-    }
+    std::unordered_set<sp<Layer>, ISurfaceComposer::SpHash<Layer>> excludeLayers;
 
-    if (sourceCrop.height() <= 0) {
-        crop.top = 0;
-        crop.bottom = parent->getBufferSize(parent->getCurrentState()).getHeight();
-    }
+    {
+        Mutex::Autolock _l(mStateLock);
 
-    int32_t reqWidth = crop.width() * frameScale;
-    int32_t reqHeight = crop.height() * frameScale;
+        parent = fromHandle(layerHandleBinder);
+        if (parent == nullptr || parent->isRemovedFromCurrentState()) {
+            ALOGE("captureLayers called with an invalid or removed parent");
+            return NAME_NOT_FOUND;
+        }
+
+        const int uid = IPCThreadState::self()->getCallingUid();
+        const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM;
+        if (!forSystem && parent->getCurrentState().flags & layer_state_t::eLayerSecure) {
+            ALOGW("Attempting to capture secure layer: PERMISSION_DENIED");
+            return PERMISSION_DENIED;
+        }
+
+        if (sourceCrop.width() <= 0) {
+            crop.left = 0;
+            crop.right = parent->getBufferSize(parent->getCurrentState()).getWidth();
+        }
+
+        if (sourceCrop.height() <= 0) {
+            crop.top = 0;
+            crop.bottom = parent->getBufferSize(parent->getCurrentState()).getHeight();
+        }
+        reqWidth = crop.width() * frameScale;
+        reqHeight = crop.height() * frameScale;
+
+        for (const auto& handle : excludeHandles) {
+            sp<Layer> excludeLayer = fromHandle(handle);
+            if (excludeLayer != nullptr) {
+                excludeLayers.emplace(excludeLayer);
+            } else {
+                ALOGW("Invalid layer handle passed as excludeLayer to captureLayers");
+                return NAME_NOT_FOUND;
+            }
+        }
+    } // mStateLock
 
     // really small crop or frameScale
     if (reqWidth <= 0) {
@@ -5523,18 +5568,6 @@
         reqHeight = 1;
     }
 
-    std::unordered_set<sp<Layer>, ISurfaceComposer::SpHash<Layer>> excludeLayers;
-    for (const auto& handle : excludeHandles) {
-        BBinder* local = handle->localBinder();
-        if (local != nullptr) {
-            auto layerHandle = reinterpret_cast<Layer::Handle*>(local);
-            excludeLayers.emplace(layerHandle->owner.promote());
-        } else {
-            ALOGW("Invalid layer handle passed as excludeLayer to captureLayers");
-            return NAME_NOT_FOUND;
-        }
-    }
-
     LayerRenderArea renderArea(this, parent, crop, reqWidth, reqHeight, reqDataspace, childrenOnly);
     auto traverseLayers = [parent, childrenOnly,
                            &excludeLayers](const LayerVector::Visitor& visitor) {
@@ -5889,6 +5922,18 @@
     mFlinger->setInputWindowsFinished();
 }
 
+sp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) {
+    BBinder *b = handle->localBinder();
+    if (b == nullptr) {
+        return nullptr;
+    }
+    auto it = mLayersByLocalBinderToken.find(b);
+    if (it != mLayersByLocalBinderToken.end()) {
+        return it->second.promote();
+    }
+    return nullptr;
+}
+
 } // namespace android
 
 #if defined(__gl_h_)
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 13b2182..72e2ff9 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -314,6 +314,8 @@
         return mTransactionCompletedThread;
     }
 
+    sp<Layer> fromHandle(const sp<IBinder>& handle) REQUIRES(mStateLock);
+
 private:
     friend class BufferLayer;
     friend class BufferQueueLayer;
@@ -576,7 +578,8 @@
      */
     status_t createLayer(const String8& name, const sp<Client>& client, uint32_t w, uint32_t h,
                          PixelFormat format, uint32_t flags, LayerMetadata metadata,
-                         sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent);
+                         sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp,
+                         const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer = nullptr);
 
     status_t createBufferQueueLayer(const sp<Client>& client, const String8& name, uint32_t w,
                                     uint32_t h, uint32_t flags, LayerMetadata metadata,
@@ -604,12 +607,10 @@
     void markLayerPendingRemovalLocked(const sp<Layer>& layer);
 
     // add a layer to SurfaceFlinger
-    status_t addClientLayer(const sp<Client>& client,
-            const sp<IBinder>& handle,
-            const sp<IGraphicBufferProducer>& gbc,
-            const sp<Layer>& lbc,
-            const sp<Layer>& parent,
-            bool addToCurrentState);
+    status_t addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
+                            const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc,
+                            const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer,
+                            bool addToCurrentState);
 
     // Traverse through all the layers and compute and cache its bounds.
     void computeLayerBounds();
@@ -982,6 +983,9 @@
     std::map<wp<IBinder>, sp<DisplayDevice>> mDisplays;
     std::unordered_map<DisplayId, sp<IBinder>> mPhysicalDisplayTokens;
 
+    // protected by mStateLock
+    std::unordered_map<BBinder*, wp<Layer>> mLayersByLocalBinderToken;
+
     // don't use a lock for these, we don't care
     int mDebugRegion = 0;
     bool mDebugDisableHWC = false;
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index 003ae7f..53a3611 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -19,6 +19,7 @@
     srcs: [
         "BufferGenerator.cpp",
         "Credentials_test.cpp",
+        "InvalidHandles_test.cpp",
         "Stress_test.cpp",
         "SurfaceInterceptor_test.cpp",
         "Transaction_test.cpp",
diff --git a/services/surfaceflinger/tests/InvalidHandles_test.cpp b/services/surfaceflinger/tests/InvalidHandles_test.cpp
new file mode 100644
index 0000000..42d1f5a
--- /dev/null
+++ b/services/surfaceflinger/tests/InvalidHandles_test.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 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 <binder/Binder.h>
+
+#include <gtest/gtest.h>
+
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
+#include <private/gui/ComposerService.h>
+#include <ui/Rect.h>
+
+namespace android {
+namespace {
+
+class NotALayer : public BBinder {};
+
+/**
+ * For all of these tests we make a SurfaceControl with an invalid layer handle
+ * and verify we aren't able to trick SurfaceFlinger.
+ */
+class InvalidHandleTest : public ::testing::Test {
+protected:
+    sp<SurfaceComposerClient> mScc;
+    sp<SurfaceControl> mNotSc;
+    void SetUp() override {
+        mScc = new SurfaceComposerClient;
+        ASSERT_EQ(NO_ERROR, mScc->initCheck());
+        mNotSc = makeNotSurfaceControl();
+    }
+
+    sp<SurfaceControl> makeNotSurfaceControl() {
+        return new SurfaceControl(mScc, new NotALayer(), nullptr, true);
+    }
+};
+
+TEST_F(InvalidHandleTest, createSurfaceInvalidHandle) {
+    auto notSc = makeNotSurfaceControl();
+    ASSERT_EQ(nullptr,
+              mScc->createSurface(String8("lolcats"), 19, 47, PIXEL_FORMAT_RGBA_8888, 0,
+                                  notSc.get())
+                      .get());
+}
+
+TEST_F(InvalidHandleTest, captureLayersInvalidHandle) {
+    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+    sp<GraphicBuffer> outBuffer;
+
+    ASSERT_EQ(NAME_NOT_FOUND,
+              sf->captureLayers(mNotSc->getHandle(), &outBuffer, Rect::EMPTY_RECT, 1.0f));
+}
+
+} // namespace
+} // namespace android