Remove the redundant getProcessFreezeInfo() am: 4e678b9830

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/15842844

Change-Id: Id852ed41260cc0cabbe6efe03baec4b1ae8ee5d5
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index d54de49..7f0cac5 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -343,80 +343,6 @@
     return nullptr;
 }
 
-bool GraphicsEnv::checkAngleRules(void* so) {
-    auto manufacturer = base::GetProperty("ro.product.manufacturer", "UNSET");
-    auto model = base::GetProperty("ro.product.model", "UNSET");
-
-    auto ANGLEGetFeatureSupportUtilAPIVersion =
-            (fpANGLEGetFeatureSupportUtilAPIVersion)dlsym(so,
-                                                          "ANGLEGetFeatureSupportUtilAPIVersion");
-
-    if (!ANGLEGetFeatureSupportUtilAPIVersion) {
-        ALOGW("Cannot find ANGLEGetFeatureSupportUtilAPIVersion function");
-        return false;
-    }
-
-    // Negotiate the interface version by requesting most recent known to the platform
-    unsigned int versionToUse = CURRENT_ANGLE_API_VERSION;
-    if (!(ANGLEGetFeatureSupportUtilAPIVersion)(&versionToUse)) {
-        ALOGW("Cannot use ANGLE feature-support library, it is older than supported by EGL, "
-              "requested version %u",
-              versionToUse);
-        return false;
-    }
-
-    // Add and remove versions below as needed
-    bool useAngle = false;
-    switch (versionToUse) {
-        case 2: {
-            ALOGV("Using version %d of ANGLE feature-support library", versionToUse);
-            void* rulesHandle = nullptr;
-            int rulesVersion = 0;
-            void* systemInfoHandle = nullptr;
-
-            // Get the symbols for the feature-support-utility library:
-#define GET_SYMBOL(symbol)                                                 \
-    fp##symbol symbol = (fp##symbol)dlsym(so, #symbol);                    \
-    if (!symbol) {                                                         \
-        ALOGW("Cannot find " #symbol " in ANGLE feature-support library"); \
-        break;                                                             \
-    }
-            GET_SYMBOL(ANGLEAndroidParseRulesString);
-            GET_SYMBOL(ANGLEGetSystemInfo);
-            GET_SYMBOL(ANGLEAddDeviceInfoToSystemInfo);
-            GET_SYMBOL(ANGLEShouldBeUsedForApplication);
-            GET_SYMBOL(ANGLEFreeRulesHandle);
-            GET_SYMBOL(ANGLEFreeSystemInfoHandle);
-
-            // Parse the rules, obtain the SystemInfo, and evaluate the
-            // application against the rules:
-            if (!(ANGLEAndroidParseRulesString)(mRulesBuffer.data(), &rulesHandle, &rulesVersion)) {
-                ALOGW("ANGLE feature-support library cannot parse rules file");
-                break;
-            }
-            if (!(ANGLEGetSystemInfo)(&systemInfoHandle)) {
-                ALOGW("ANGLE feature-support library cannot obtain SystemInfo");
-                break;
-            }
-            if (!(ANGLEAddDeviceInfoToSystemInfo)(manufacturer.c_str(), model.c_str(),
-                                                  systemInfoHandle)) {
-                ALOGW("ANGLE feature-support library cannot add device info to SystemInfo");
-                break;
-            }
-            useAngle = (ANGLEShouldBeUsedForApplication)(rulesHandle, rulesVersion,
-                                                         systemInfoHandle, mAngleAppName.c_str());
-            (ANGLEFreeRulesHandle)(rulesHandle);
-            (ANGLEFreeSystemInfoHandle)(systemInfoHandle);
-        } break;
-
-        default:
-            ALOGW("Version %u of ANGLE feature-support library is NOT supported.", versionToUse);
-    }
-
-    ALOGV("Close temporarily-loaded ANGLE opt-in/out logic");
-    return useAngle;
-}
-
 bool GraphicsEnv::shouldUseAngle(std::string appName) {
     if (appName != mAngleAppName) {
         // Make sure we are checking the app we were init'ed for
@@ -444,31 +370,20 @@
     const char* ANGLE_PREFER_ANGLE = "angle";
     const char* ANGLE_PREFER_NATIVE = "native";
 
+    mUseAngle = NO;
     if (mAngleDeveloperOptIn == ANGLE_PREFER_ANGLE) {
         ALOGV("User set \"Developer Options\" to force the use of ANGLE");
         mUseAngle = YES;
     } else if (mAngleDeveloperOptIn == ANGLE_PREFER_NATIVE) {
         ALOGV("User set \"Developer Options\" to force the use of Native");
-        mUseAngle = NO;
     } else {
-        // The "Developer Options" value wasn't set to force the use of ANGLE.  Need to temporarily
-        // load ANGLE and call the updatable opt-in/out logic:
-        void* featureSo = loadLibrary("feature_support");
-        if (featureSo) {
-            ALOGV("loaded ANGLE's opt-in/out logic from namespace");
-            mUseAngle = checkAngleRules(featureSo) ? YES : NO;
-            dlclose(featureSo);
-            featureSo = nullptr;
-        } else {
-            ALOGV("Could not load the ANGLE opt-in/out logic, cannot use ANGLE.");
-        }
+        ALOGV("User set invalid \"Developer Options\": '%s'", mAngleDeveloperOptIn.c_str());
     }
 }
 
 void GraphicsEnv::setAngleInfo(const std::string path, const std::string appName,
                                const std::string developerOptIn,
-                               const std::vector<std::string> eglFeatures, const int rulesFd,
-                               const long rulesOffset, const long rulesLength) {
+                               const std::vector<std::string> eglFeatures) {
     if (mUseAngle != UNKNOWN) {
         // We've already figured out an answer for this app, so just return.
         ALOGV("Already evaluated the rules file for '%s': use ANGLE = %s", appName.c_str(),
@@ -485,22 +400,6 @@
     ALOGV("setting ANGLE application opt-in to '%s'", developerOptIn.c_str());
     mAngleDeveloperOptIn = developerOptIn;
 
-    lseek(rulesFd, rulesOffset, SEEK_SET);
-    mRulesBuffer = std::vector<char>(rulesLength + 1);
-    ssize_t numBytesRead = read(rulesFd, mRulesBuffer.data(), rulesLength);
-    if (numBytesRead < 0) {
-        ALOGE("Cannot read rules file: numBytesRead = %zd", numBytesRead);
-        numBytesRead = 0;
-    } else if (numBytesRead == 0) {
-        ALOGW("Empty rules file");
-    }
-    if (numBytesRead != rulesLength) {
-        ALOGW("Did not read all of the necessary bytes from the rules file."
-              "expected: %ld, got: %zd",
-              rulesLength, numBytesRead);
-    }
-    mRulesBuffer[numBytesRead] = '\0';
-
     // Update the current status of whether we should use ANGLE or not
     updateUseAngle();
 }
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index 900fc49..56d1139 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -97,8 +97,7 @@
     // in the search path must have a '!' after the zip filename, e.g.
     //     /system/app/ANGLEPrebuilt/ANGLEPrebuilt.apk!/lib/arm64-v8a
     void setAngleInfo(const std::string path, const std::string appName, std::string devOptIn,
-                      const std::vector<std::string> eglFeatures, const int rulesFd,
-                      const long rulesOffset, const long rulesLength);
+                      const std::vector<std::string> eglFeatures);
     // Get the ANGLE driver namespace.
     android_namespace_t* getAngleNamespace();
     // Get the app name for ANGLE debug message.
@@ -129,8 +128,6 @@
 
     // Load requested ANGLE library.
     void* loadLibrary(std::string name);
-    // Check ANGLE support with the rules.
-    bool checkAngleRules(void* so);
     // Update whether ANGLE should be used.
     void updateUseAngle();
     // Link updatable driver namespace with llndk and vndk-sp libs.
@@ -159,8 +156,6 @@
     std::string mAngleDeveloperOptIn;
     // ANGLE EGL features;
     std::vector<std::string> mAngleEglFeatures;
-    // ANGLE rules.
-    std::vector<char> mRulesBuffer;
     // Use ANGLE flag.
     UseAngle mUseAngle = UNKNOWN;
     // Vulkan debug layers libs.
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index f7ec8ef..94e1ae1 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -118,12 +118,12 @@
 }
 
 void BLASTBufferItemConsumer::setBlastBufferQueue(BLASTBufferQueue* blastbufferqueue) {
-    Mutex::Autolock lock(mMutex);
+    std::scoped_lock lock(mBufferQueueMutex);
     mBLASTBufferQueue = blastbufferqueue;
 }
 
 void BLASTBufferItemConsumer::onSidebandStreamChanged() {
-    Mutex::Autolock lock(mMutex);
+    std::scoped_lock lock(mBufferQueueMutex);
     if (mBLASTBufferQueue != nullptr) {
         sp<NativeHandle> stream = getSidebandStream();
         mBLASTBufferQueue->setSidebandStream(stream);
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index ea9b1c6..6c5b2aa 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -62,11 +62,12 @@
     uint64_t mCurrentFrameNumber = 0;
 
     Mutex mMutex;
+    std::mutex mBufferQueueMutex;
     ConsumerFrameEventHistory mFrameEventHistory GUARDED_BY(mMutex);
     std::queue<uint64_t> mDisconnectEvents GUARDED_BY(mMutex);
     bool mCurrentlyConnected GUARDED_BY(mMutex);
     bool mPreviouslyConnected GUARDED_BY(mMutex);
-    BLASTBufferQueue* mBLASTBufferQueue GUARDED_BY(mMutex);
+    BLASTBufferQueue* mBLASTBufferQueue GUARDED_BY(mBufferQueueMutex);
 };
 
 class BLASTBufferQueue
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 3c59f11..94023e6 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -424,14 +424,28 @@
     return fenceFd;
 }
 
-bool SkiaGLRenderEngine::waitFence(base::unique_fd fenceFd) {
+void SkiaGLRenderEngine::waitFence(base::borrowed_fd fenceFd) {
+    if (fenceFd.get() >= 0 && !waitGpuFence(fenceFd)) {
+        ATRACE_NAME("SkiaGLRenderEngine::waitFence");
+        sync_wait(fenceFd.get(), -1);
+    }
+}
+
+bool SkiaGLRenderEngine::waitGpuFence(base::borrowed_fd fenceFd) {
     if (!gl::GLExtensions::getInstance().hasNativeFenceSync() ||
         !gl::GLExtensions::getInstance().hasWaitSync()) {
         return false;
     }
 
+    // Duplicate the fence for passing to eglCreateSyncKHR.
+    base::unique_fd fenceDup(dup(fenceFd.get()));
+    if (fenceDup.get() < 0) {
+        ALOGE("failed to create duplicate fence fd: %d", fenceDup.get());
+        return false;
+    }
+
     // release the fd and transfer the ownership to EGLSync
-    EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd.release(), EGL_NONE};
+    EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceDup.release(), EGL_NONE};
     EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
     if (sync == EGL_NO_SYNC_KHR) {
         ALOGE("failed to create EGL native fence sync: %#x", eglGetError());
@@ -726,14 +740,6 @@
         return NO_ERROR;
     }
 
-    if (bufferFence.get() >= 0) {
-        // Duplicate the fence for passing to waitFence.
-        base::unique_fd bufferFenceDup(dup(bufferFence.get()));
-        if (bufferFenceDup < 0 || !waitFence(std::move(bufferFenceDup))) {
-            ATRACE_NAME("Waiting before draw");
-            sync_wait(bufferFence.get(), -1);
-        }
-    }
     if (buffer == nullptr) {
         ALOGE("No output buffer provided. Aborting GPU composition.");
         return BAD_VALUE;
@@ -758,6 +764,9 @@
                                                                true, mTextureCleanupMgr);
     }
 
+    // wait on the buffer to be ready to use prior to using it
+    waitFence(bufferFence);
+
     const ui::Dataspace dstDataspace =
             mUseColorManagement ? display.outputDataspace : ui::Dataspace::V0_SRGB_LINEAR;
     sk_sp<SkSurface> dstSurface = surfaceTextureRef->getOrCreateSurface(dstDataspace, grContext);
@@ -1014,6 +1023,12 @@
                                                       false, mTextureCleanupMgr);
             }
 
+            // if the layer's buffer has a fence, then we must must respect the fence prior to using
+            // the buffer.
+            if (layer->source.buffer.fence != nullptr) {
+                waitFence(layer->source.buffer.fence->get());
+            }
+
             // isOpaque means we need to ignore the alpha in the image,
             // replacing it with the alpha specified by the LayerSettings. See
             // https://developer.android.com/reference/android/view/SurfaceControl.Builder#setOpaque(boolean)
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index a852bbc..238ad8f 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -99,7 +99,10 @@
     inline GrDirectContext* getActiveGrContext() const;
 
     base::unique_fd flush();
-    bool waitFence(base::unique_fd fenceFd);
+    // waitFence attempts to wait in the GPU, and if unable to waits on the CPU instead.
+    void waitFence(base::borrowed_fd fenceFd);
+    bool waitGpuFence(base::borrowed_fd fenceFd);
+
     void initCanvas(SkCanvas* canvas, const DisplaySettings& display);
     void drawShadow(SkCanvas* canvas, const SkRRect& casterRRect,
                     const ShadowSettings& shadowSettings);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 75dd51c..d8cead5 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -820,11 +820,7 @@
 }
 
 bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ) {
-    sp<Handle> handle = static_cast<Handle*>(relativeToHandle.get());
-    if (handle == nullptr) {
-        return false;
-    }
-    sp<Layer> relative = handle->owner.promote();
+    sp<Layer> relative = fromHandle(relativeToHandle).promote();
     if (relative == nullptr) {
         return false;
     }
@@ -1610,8 +1606,7 @@
 bool Layer::reparent(const sp<IBinder>& newParentHandle) {
     sp<Layer> newParent;
     if (newParentHandle != nullptr) {
-        auto handle = static_cast<Handle*>(newParentHandle.get());
-        newParent = handle->owner.promote();
+        newParent = fromHandle(newParentHandle).promote();
         if (newParent == nullptr) {
             ALOGE("Unable to promote Layer handle");
             return false;
@@ -1986,24 +1981,10 @@
     mDrawingParent = mCurrentParent;
 }
 
-static wp<Layer> extractLayerFromBinder(const wp<IBinder>& weakBinderHandle) {
-    if (weakBinderHandle == nullptr) {
-        return nullptr;
-    }
-    sp<IBinder> binderHandle = weakBinderHandle.promote();
-    if (binderHandle == nullptr) {
-        return nullptr;
-    }
-    sp<Layer::Handle> handle = static_cast<Layer::Handle*>(binderHandle.get());
-    if (handle == nullptr) {
-        return nullptr;
-    }
-    return handle->owner;
-}
 
 void Layer::setInputInfo(const InputWindowInfo& info) {
     mDrawingState.inputInfo = info;
-    mDrawingState.touchableRegionCrop = extractLayerFromBinder(info.touchableRegionCropHandle);
+    mDrawingState.touchableRegionCrop = fromHandle(info.touchableRegionCropHandle.promote());
     mDrawingState.modified = true;
     mFlinger->mInputInfoChanged = true;
     setTransactionFlags(eTransactionNeeded);
@@ -2562,6 +2543,23 @@
     mFlinger->mNumClones++;
 }
 
+const String16 Layer::Handle::kDescriptor = String16("android.Layer.Handle");
+
+wp<Layer> Layer::fromHandle(const sp<IBinder>& handleBinder) {
+    if (handleBinder == nullptr) {
+        return nullptr;
+    }
+
+    BBinder* b = handleBinder->localBinder();
+    if (b == nullptr || b->getInterfaceDescriptor() != Handle::kDescriptor) {
+        return nullptr;
+    }
+
+    // We can safely cast this binder since its local and we verified its interface descriptor.
+    sp<Handle> handle = static_cast<Handle*>(handleBinder.get());
+    return handle->owner;
+}
+
 // ---------------------------------------------------------------------------
 
 std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 59f5b0d..8905548 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -289,16 +289,17 @@
     class LayerCleaner {
         sp<SurfaceFlinger> mFlinger;
         sp<Layer> mLayer;
+        BBinder* mHandle;
 
     protected:
         ~LayerCleaner() {
             // destroy client resources
-            mFlinger->onHandleDestroyed(mLayer);
+            mFlinger->onHandleDestroyed(mHandle, mLayer);
         }
 
     public:
-        LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
-              : mFlinger(flinger), mLayer(layer) {}
+        LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer, BBinder* handle)
+              : mFlinger(flinger), mLayer(layer), mHandle(handle) {}
     };
 
     /*
@@ -312,11 +313,15 @@
     class Handle : public BBinder, public LayerCleaner {
     public:
         Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
-              : LayerCleaner(flinger, layer), owner(layer) {}
+              : LayerCleaner(flinger, layer, this), owner(layer) {}
+        const String16& getInterfaceDescriptor() const override { return kDescriptor; }
 
+        static const String16 kDescriptor;
         wp<Layer> owner;
     };
 
+    static wp<Layer> fromHandle(const sp<IBinder>& handle);
+
     explicit Layer(const LayerCreationArgs& args);
     virtual ~Layer();
 
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 0334d70..73b7b63 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -911,7 +911,10 @@
 int RefreshRateConfigs::getFrameRateDivider(Fps displayFrameRate, Fps layerFrameRate) {
     // This calculation needs to be in sync with the java code
     // in DisplayManagerService.getDisplayInfoForFrameRateOverride
-    constexpr float kThreshold = 0.1f;
+
+    // The threshold must be smaller than 0.001 in order to differentiate
+    // between the fractional pairs (e.g. 59.94 and 60).
+    constexpr float kThreshold = 0.0009f;
     const auto numPeriods = displayFrameRate.getValue() / layerFrameRate.getValue();
     const auto numPeriodsRounded = std::round(numPeriods);
     if (std::abs(numPeriods - numPeriodsRounded) > kThreshold) {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index e0b3640..64ad178 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -386,6 +386,13 @@
     }
 
     const auto modeId = *mFeatures.modeId;
+    // If the modeId is not the current mode, this means that a
+    // mode change is in progress. In that case we shouldn't dispatch an event
+    // as it will be dispatched when the current mode changes.
+    if (mRefreshRateConfigs.getCurrentRefreshRate().getModeId() != modeId) {
+        return;
+    }
+
     const auto vsyncPeriod = mRefreshRateConfigs.getRefreshRateFromModeId(modeId).getVsyncPeriod();
 
     // If there is no change from cached mode, there is no need to dispatch an event
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 230810c..fe43a20 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3611,7 +3611,7 @@
 
         sp<Layer> layer = nullptr;
         if (s.surface) {
-            layer = fromHandleLocked(s.surface).promote();
+            layer = fromHandle(s.surface).promote();
         } else if (s.hasBufferChanges()) {
             ALOGW("Transaction with buffer, but no Layer?");
             continue;
@@ -3778,7 +3778,7 @@
                 setClientStateLocked(frameTimelineInfo, state, desiredPresentTime, isAutoTimestamp,
                                      postTime, permissions, listenerCallbacksWithSurfaces);
         if ((flags & eAnimation) && state.state.surface) {
-            if (const auto layer = fromHandleLocked(state.state.surface).promote(); layer) {
+            if (const auto layer = fromHandle(state.state.surface).promote(); layer) {
                 mScheduler->recordLayerHistory(layer.get(),
                                                isAutoTimestamp ? 0 : desiredPresentTime,
                                                LayerHistory::LayerUpdateType::AnimationTX);
@@ -3933,13 +3933,11 @@
         if (what & layer_state_t::eLayerCreated) {
             layer = handleLayerCreatedLocked(s.surface);
             if (layer) {
-                // put the created layer into mLayersByLocalBinderToken.
-                mLayersByLocalBinderToken.emplace(s.surface->localBinder(), layer);
                 flags |= eTransactionNeeded | eTraversalNeeded;
                 mLayersAdded = true;
             }
         } else {
-            layer = fromHandleLocked(s.surface).promote();
+            layer = fromHandle(s.surface).promote();
         }
     } else {
         // The client may provide us a null handle. Treat it as if the layer was removed.
@@ -4267,7 +4265,7 @@
 
     {
         Mutex::Autolock _l(mStateLock);
-        mirrorFrom = fromHandleLocked(mirrorFromHandle).promote();
+        mirrorFrom = fromHandle(mirrorFromHandle).promote();
         if (!mirrorFrom) {
             return NAME_NOT_FOUND;
         }
@@ -4465,7 +4463,7 @@
     setTransactionFlags(eTransactionNeeded);
 }
 
-void SurfaceFlinger::onHandleDestroyed(sp<Layer>& layer) {
+void SurfaceFlinger::onHandleDestroyed(BBinder* handle, sp<Layer>& layer) {
     Mutex::Autolock lock(mStateLock);
     // If a layer has a parent, we allow it to out-live it's handle
     // with the idea that the parent holds a reference and will eventually
@@ -4476,17 +4474,7 @@
         mCurrentState.layersSortedByZ.remove(layer);
     }
     markLayerPendingRemovalLocked(layer);
-
-    auto it = mLayersByLocalBinderToken.begin();
-    while (it != mLayersByLocalBinderToken.end()) {
-        if (it->second == layer) {
-            mBufferCountTracker.remove(it->first->localBinder());
-            it = mLayersByLocalBinderToken.erase(it);
-        } else {
-            it++;
-        }
-    }
-
+    mBufferCountTracker.remove(handle);
     layer.clear();
 }
 
@@ -6089,7 +6077,7 @@
     {
         Mutex::Autolock lock(mStateLock);
 
-        parent = fromHandleLocked(args.layerHandle).promote();
+        parent = fromHandle(args.layerHandle).promote();
         if (parent == nullptr || parent->isRemovedFromCurrentState()) {
             ALOGE("captureLayers called with an invalid or removed parent");
             return NAME_NOT_FOUND;
@@ -6120,7 +6108,7 @@
         reqSize = ui::Size(crop.width() * args.frameScaleX, crop.height() * args.frameScaleY);
 
         for (const auto& handle : args.excludeHandles) {
-            sp<Layer> excludeLayer = fromHandleLocked(handle).promote();
+            sp<Layer> excludeLayer = fromHandle(handle).promote();
             if (excludeLayer != nullptr) {
                 excludeLayers.emplace(excludeLayer);
             } else {
@@ -6616,24 +6604,8 @@
     }
 }
 
-wp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) {
-    Mutex::Autolock _l(mStateLock);
-    return fromHandleLocked(handle);
-}
-
-wp<Layer> SurfaceFlinger::fromHandleLocked(const sp<IBinder>& handle) const {
-    BBinder* b = nullptr;
-    if (handle) {
-        b = handle->localBinder();
-    }
-    if (b == nullptr) {
-        return nullptr;
-    }
-    auto it = mLayersByLocalBinderToken.find(b);
-    if (it != mLayersByLocalBinderToken.end()) {
-        return it->second;
-    }
-    return nullptr;
+wp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) const {
+    return Layer::fromHandle(handle);
 }
 
 void SurfaceFlinger::onLayerFirstRef(Layer* layer) {
@@ -6938,7 +6910,7 @@
     sp<Layer> parent;
     bool allowAddRoot = state->addToRoot;
     if (state->initialParent != nullptr) {
-        parent = fromHandleLocked(state->initialParent.promote()).promote();
+        parent = fromHandle(state->initialParent.promote()).promote();
         if (parent == nullptr) {
             ALOGE("Invalid parent %p", state->initialParent.unsafe_get());
             allowAddRoot = false;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 380f444..c3d837e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -327,8 +327,7 @@
     // Returns nullptr if the handle does not point to an existing layer.
     // Otherwise, returns a weak reference so that callers off the main-thread
     // won't accidentally hold onto the last strong reference.
-    wp<Layer> fromHandle(const sp<IBinder>& handle);
-    wp<Layer> fromHandleLocked(const sp<IBinder>& handle) const REQUIRES(mStateLock);
+    wp<Layer> fromHandle(const sp<IBinder>& handle) const;
 
     // If set, disables reusing client composition buffers. This can be set by
     // debug.sf.disable_client_composition_cache
@@ -898,7 +897,7 @@
     // called when all clients have released all their references to
     // this layer meaning it is entirely safe to destroy all
     // resources associated to this layer.
-    void onHandleDestroyed(sp<Layer>& layer);
+    void onHandleDestroyed(BBinder* handle, sp<Layer>& layer);
     void markLayerPendingRemovalLocked(const sp<Layer>& layer);
 
     // add a layer to SurfaceFlinger
@@ -1290,8 +1289,6 @@
         std::optional<DisplayIdGenerator<HalVirtualDisplayId>> hal;
     } mVirtualDisplayIdGenerators;
 
-    std::unordered_map<BBinder*, wp<Layer>> mLayersByLocalBinderToken GUARDED_BY(mStateLock);
-
     // don't use a lock for these, we don't care
     int mDebugRegion = 0;
     bool mDebugDisableHWC = false;
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 23ab7c8..837b2e8 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -183,12 +183,9 @@
     return NO_ERROR;
 }
 
-const sp<const Layer> SurfaceInterceptor::getLayer(const wp<const IBinder>& weakHandle) const {
-    const sp<const IBinder>& handle(weakHandle.promote());
-    const auto layerHandle(static_cast<const Layer::Handle*>(handle.get()));
-    const sp<const Layer> layer(layerHandle->owner.promote());
-    // layer could be a nullptr at this point
-    return layer;
+const sp<const Layer> SurfaceInterceptor::getLayer(const wp<IBinder>& weakHandle) const {
+    sp<IBinder> handle = weakHandle.promote();
+    return Layer::fromHandle(handle).promote();
 }
 
 int32_t SurfaceInterceptor::getLayerId(const sp<const Layer>& layer) const {
@@ -203,12 +200,11 @@
     return strongLayer == nullptr ? -1 : getLayerId(strongLayer);
 }
 
-int32_t SurfaceInterceptor::getLayerIdFromHandle(const sp<const IBinder>& handle) const {
+int32_t SurfaceInterceptor::getLayerIdFromHandle(const sp<IBinder>& handle) const {
     if (handle == nullptr) {
         return -1;
     }
-    const auto layerHandle(static_cast<const Layer::Handle*>(handle.get()));
-    const sp<const Layer> layer(layerHandle->owner.promote());
+    const sp<const Layer> layer = Layer::fromHandle(handle).promote();
     return layer == nullptr ? -1 : getLayerId(layer);
 }
 
diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h
index 673f9e7..c955596 100644
--- a/services/surfaceflinger/SurfaceInterceptor.h
+++ b/services/surfaceflinger/SurfaceInterceptor.h
@@ -133,10 +133,10 @@
     void addInitialDisplayStateLocked(Increment* increment, const DisplayDeviceState& display);
 
     status_t writeProtoFileLocked();
-    const sp<const Layer> getLayer(const wp<const IBinder>& weakHandle) const;
+    const sp<const Layer> getLayer(const wp<IBinder>& weakHandle) const;
     int32_t getLayerId(const sp<const Layer>& layer) const;
     int32_t getLayerIdFromWeakRef(const wp<const Layer>& layer) const;
-    int32_t getLayerIdFromHandle(const sp<const IBinder>& weakHandle) const;
+    int32_t getLayerIdFromHandle(const sp<IBinder>& weakHandle) const;
 
     Increment* createTraceIncrementLocked();
     void addSurfaceCreationLocked(Increment* increment, const sp<const Layer>& layer);
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 3423bd5..3b2bd81 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -2123,7 +2123,11 @@
     refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90);
     displayRefreshRate = refreshRateConfigs->getCurrentRefreshRate().getFps();
     EXPECT_EQ(4, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, Fps(22.5f)));
-    EXPECT_EQ(4, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, Fps(22.6f)));
+
+    EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivider(Fps(24.f), Fps(25.f)));
+    EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivider(Fps(24.f), Fps(23.976f)));
+    EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivider(Fps(30.f), Fps(29.97f)));
+    EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivider(Fps(60.f), Fps(59.94f)));
 }
 
 TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_noLayers) {
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 2715587..3ed3eba 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -1231,6 +1231,12 @@
         return VK_ERROR_SURFACE_LOST_KHR;
     }
 
+    // In shared mode the num_images must be one regardless of how many
+    // buffers were allocated for the buffer queue.
+    if (swapchain_image_usage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID) {
+        num_images = 1;
+    }
+
     int32_t legacy_usage = 0;
     if (dispatch.GetSwapchainGrallocUsage2ANDROID) {
         uint64_t consumer_usage, producer_usage;