Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55222d47 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SF: Fix thread safety in ISurfaceComposer APIs" into rvc-dev

parents 0716947d 470df5f0
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -795,8 +795,7 @@ public:
    }

    virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
                                                      uint8_t componentMask,
                                                      uint64_t maxFrames) const {
                                                      uint8_t componentMask, uint64_t maxFrames) {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        data.writeStrongBinder(display);
@@ -1038,7 +1037,7 @@ public:
        return NO_ERROR;
    }

    virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) const {
    virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) {
        Parcel data, reply;
        status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        if (error != NO_ERROR) {
+2 −3
Original line number Diff line number Diff line
@@ -383,7 +383,7 @@ public:
     */
    virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
                                                      uint8_t componentMask,
                                                      uint64_t maxFrames) const = 0;
                                                      uint64_t maxFrames) = 0;

    /* Returns statistics on the color profile of the last frame displayed for a given display
     *
@@ -468,8 +468,7 @@ public:
     *      BAD_VALUE         if the brightness is invalid, or
     *      INVALID_OPERATION if brightness operations are not supported.
     */
    virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken,
                                          float brightness) const = 0;
    virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) = 0;

    /*
     * Sends a power hint to the composer. This function is asynchronous.
+2 −2
Original line number Diff line number Diff line
@@ -804,7 +804,7 @@ public:
    }
    status_t setDisplayContentSamplingEnabled(const sp<IBinder>& /*display*/, bool /*enable*/,
                                              uint8_t /*componentMask*/,
                                              uint64_t /*maxFrames*/) const override {
                                              uint64_t /*maxFrames*/) override {
        return NO_ERROR;
    }
    status_t getDisplayedContentSample(const sp<IBinder>& /*display*/, uint64_t /*maxFrames*/,
@@ -822,7 +822,7 @@ public:
        return NO_ERROR;
    }
    status_t setDisplayBrightness(const sp<IBinder>& /*displayToken*/,
                                  float /*brightness*/) const override {
                                  float /*brightness*/) override {
        return NO_ERROR;
    }

+117 −118
Original line number Diff line number Diff line
@@ -466,17 +466,17 @@ sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
}

void SurfaceFlinger::destroyDisplay(const sp<IBinder>& displayToken) {
    Mutex::Autolock _l(mStateLock);
    Mutex::Autolock lock(mStateLock);

    ssize_t index = mCurrentState.displays.indexOfKey(displayToken);
    const ssize_t index = mCurrentState.displays.indexOfKey(displayToken);
    if (index < 0) {
        ALOGE("destroyDisplay: Invalid display token %p", displayToken.get());
        ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
        return;
    }

    const DisplayDeviceState& state = mCurrentState.displays.valueAt(index);
    if (!state.isVirtual()) {
        ALOGE("destroyDisplay called for non-virtual display");
    if (state.physical) {
        ALOGE("%s: Invalid operation on physical display", __FUNCTION__);
        return;
    }
    mInterceptor->saveDisplayDeletion(state.sequenceId);
@@ -908,20 +908,29 @@ status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>&, DisplayStatInfo* st
}

int SurfaceFlinger::getActiveConfig(const sp<IBinder>& displayToken) {
    const auto display = getDisplayDevice(displayToken);
    if (!display) {
        ALOGE("getActiveConfig: Invalid display token %p", displayToken.get());
        return BAD_VALUE;
    int activeConfig;
    bool isPrimary;

    {
        Mutex::Autolock lock(mStateLock);

        if (const auto display = getDisplayDeviceLocked(displayToken)) {
            activeConfig = display->getActiveConfig().value();
            isPrimary = display->isPrimary();
        } else {
            ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
            return NAME_NOT_FOUND;
        }
    }

    if (display->isPrimary()) {
    if (isPrimary) {
        std::lock_guard<std::mutex> lock(mActiveConfigLock);
        if (mDesiredActiveConfigChanged) {
            return mDesiredActiveConfig.configId.value();
        }
    }

    return display->getActiveConfig().value();
    return activeConfig;
}

void SurfaceFlinger::setDesiredActiveConfig(const ActiveConfigInfo& info) {
@@ -972,17 +981,16 @@ status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& displayToken, int mo
        return BAD_VALUE;
    }

    status_t result = NO_ERROR;
    status_t result = NAME_NOT_FOUND;

    postMessageSync(new LambdaMessage([&]() {
        const auto display = getDisplayDeviceLocked(displayToken);
        if (!display) {
            ALOGE("Attempt to set allowed display configs for invalid display token %p",
                  displayToken.get());
            result = BAD_VALUE;
        } else if (display->isVirtual()) {
            ALOGW("Attempt to set allowed display configs for virtual display");
            result = BAD_VALUE;
            result = INVALID_OPERATION;
        } else {
            HwcConfigIndexType config(mode);
            const auto& refreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(config);
@@ -1152,7 +1160,7 @@ status_t SurfaceFlinger::getDisplayNativePrimaries(const sp<IBinder>& displayTok

    // Currently we only support this API for a single internal display.
    if (getInternalDisplayToken() != displayToken) {
        return BAD_VALUE;
        return NAME_NOT_FOUND;
    }

    memcpy(&primaries, &mInternalDisplayPrimaries, sizeof(ui::DisplayPrimaries));
@@ -1160,7 +1168,9 @@ status_t SurfaceFlinger::getDisplayNativePrimaries(const sp<IBinder>& displayTok
}

ColorMode SurfaceFlinger::getActiveColorMode(const sp<IBinder>& displayToken) {
    if (const auto display = getDisplayDevice(displayToken)) {
    Mutex::Autolock lock(mStateLock);

    if (const auto display = getDisplayDeviceLocked(displayToken)) {
        return display->getCompositionDisplay()->getState().colorMode;
    }
    return static_cast<ColorMode>(BAD_VALUE);
@@ -1176,7 +1186,7 @@ status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& displayToken, Col
                  decodeColorMode(mode).c_str(), mode, displayToken.get());
            return;
        }
        const auto display = getDisplayDevice(displayToken);
        const auto display = getDisplayDeviceLocked(displayToken);
        if (!display) {
            ALOGE("Attempt to set active color mode %s (%d) for invalid display token %p",
                  decodeColorMode(mode).c_str(), mode, displayToken.get());
@@ -1196,16 +1206,14 @@ status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& displayToken, Col

status_t SurfaceFlinger::getAutoLowLatencyModeSupport(const sp<IBinder>& displayToken,
                                                      bool* outSupport) const {
    Mutex::Autolock _l(mStateLock);

    if (!displayToken) {
        ALOGE("getAutoLowLatencyModeSupport() failed. Missing display token.");
        return BAD_VALUE;
    }

    Mutex::Autolock lock(mStateLock);

    const auto displayId = getPhysicalDisplayIdLocked(displayToken);
    if (!displayId) {
        ALOGE("getAutoLowLatencyModeSupport() failed. Display id for display token %p not found.",
              displayToken.get());
        return NAME_NOT_FOUND;
    }
    *outSupport = getHwComposer().hasDisplayCapability(*displayId,
@@ -1214,64 +1222,45 @@ status_t SurfaceFlinger::getAutoLowLatencyModeSupport(const sp<IBinder>& display
}

void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) {
    postMessageAsync(new LambdaMessage([=] { setAutoLowLatencyModeInternal(displayToken, on); }));
}

void SurfaceFlinger::setAutoLowLatencyModeInternal(const sp<IBinder>& displayToken, bool on) {
    if (!displayToken) {
        ALOGE("setAutoLowLatencyMode() failed. Missing display token.");
        return;
    }
    const auto displayId = getPhysicalDisplayIdLocked(displayToken);
    if (!displayId) {
        ALOGE("setAutoLowLatencyMode() failed. Display id for display token %p not found.",
              displayToken.get());
        return;
    }

    postMessageAsync(new LambdaMessage([=] {
        if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
            getHwComposer().setAutoLowLatencyMode(*displayId, on);
        } else {
            ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
        }
    }));
}

status_t SurfaceFlinger::getGameContentTypeSupport(const sp<IBinder>& displayToken,
                                                   bool* outSupport) const {
    Mutex::Autolock _l(mStateLock);

    if (!displayToken) {
        ALOGE("getGameContentTypeSupport() failed. Missing display token.");
        return BAD_VALUE;
    }

    Mutex::Autolock lock(mStateLock);

    const auto displayId = getPhysicalDisplayIdLocked(displayToken);
    if (!displayId) {
        ALOGE("getGameContentTypeSupport() failed. Display id for display token %p not found.",
              displayToken.get());
        return NAME_NOT_FOUND;
    }

    std::vector<HWC2::ContentType> outSupportedContentTypes;
    getHwComposer().getSupportedContentTypes(*displayId, &outSupportedContentTypes);
    *outSupport = std::find(outSupportedContentTypes.begin(), outSupportedContentTypes.end(),
                            HWC2::ContentType::Game) != outSupportedContentTypes.end();
    std::vector<HWC2::ContentType> types;
    getHwComposer().getSupportedContentTypes(*displayId, &types);

    *outSupport = std::any_of(types.begin(), types.end(),
                              [](auto type) { return type == HWC2::ContentType::Game; });
    return NO_ERROR;
}

void SurfaceFlinger::setGameContentType(const sp<IBinder>& displayToken, bool on) {
    postMessageAsync(new LambdaMessage([=] { setGameContentTypeInternal(displayToken, on); }));
}

void SurfaceFlinger::setGameContentTypeInternal(const sp<IBinder>& displayToken, bool on) {
    if (!displayToken) {
        ALOGE("setGameContentType() failed. Missing display token.");
        return;
    }
    const auto displayId = getPhysicalDisplayIdLocked(displayToken);
    if (!displayId) {
        ALOGE("setGameContentType() failed. Display id for display token %p not found.",
              displayToken.get());
        return;
    }

    const HWC2::ContentType type = on ? HWC2::ContentType::Game : HWC2::ContentType::None;
    postMessageAsync(new LambdaMessage([=] {
        if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
            const auto type = on ? HWC2::ContentType::Game : HWC2::ContentType::None;
            getHwComposer().setContentType(*displayId, type);
        } else {
            ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
        }
    }));
}

status_t SurfaceFlinger::clearAnimationFrameStats() {
@@ -1288,15 +1277,15 @@ status_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {

status_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& displayToken,
                                            HdrCapabilities* outCapabilities) const {
    Mutex::Autolock _l(mStateLock);
    Mutex::Autolock lock(mStateLock);

    const auto display = getDisplayDeviceLocked(displayToken);
    if (!display) {
        ALOGE("getHdrCapabilities: Invalid display token %p", displayToken.get());
        return BAD_VALUE;
        ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
        return NAME_NOT_FOUND;
    }

    // At this point the DisplayDeivce should already be set up,
    // At this point the DisplayDevice should already be set up,
    // meaning the luminance information is already queried from
    // hardware composer and stored properly.
    const HdrCapabilities& capabilities = display->getHdrCapabilities();
@@ -1339,39 +1328,46 @@ status_t SurfaceFlinger::getDisplayedContentSamplingAttributes(const sp<IBinder>
    if (!outFormat || !outDataspace || !outComponentMask) {
        return BAD_VALUE;
    }
    const auto display = getDisplayDevice(displayToken);
    if (!display || !display->getId()) {
        ALOGE("getDisplayedContentSamplingAttributes: Bad display token: %p", display.get());
        return BAD_VALUE;

    Mutex::Autolock lock(mStateLock);

    const auto displayId = getPhysicalDisplayIdLocked(displayToken);
    if (!displayId) {
        return NAME_NOT_FOUND;
    }
    return getHwComposer().getDisplayedContentSamplingAttributes(*display->getId(), outFormat,

    return getHwComposer().getDisplayedContentSamplingAttributes(*displayId, outFormat,
                                                                 outDataspace, outComponentMask);
}

status_t SurfaceFlinger::setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken,
                                                          bool enable, uint8_t componentMask,
                                                          uint64_t maxFrames) const {
    const auto display = getDisplayDevice(displayToken);
    if (!display || !display->getId()) {
        ALOGE("setDisplayContentSamplingEnabled: Bad display token: %p", display.get());
        return BAD_VALUE;
    }
                                                          uint64_t maxFrames) {
    status_t result = NAME_NOT_FOUND;

    return getHwComposer().setDisplayContentSamplingEnabled(*display->getId(), enable,
    postMessageSync(new LambdaMessage([&] {
        if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
            result = getHwComposer().setDisplayContentSamplingEnabled(*displayId, enable,
                                                                      componentMask, maxFrames);
        } else {
            ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
        }
    }));

    return result;
}

status_t SurfaceFlinger::getDisplayedContentSample(const sp<IBinder>& displayToken,
                                                   uint64_t maxFrames, uint64_t timestamp,
                                                   DisplayedFrameStats* outStats) const {
    const auto display = getDisplayDevice(displayToken);
    if (!display || !display->getId()) {
        ALOGE("getDisplayContentSample: Bad display token: %p", displayToken.get());
        return BAD_VALUE;
    Mutex::Autolock lock(mStateLock);

    const auto displayId = getPhysicalDisplayIdLocked(displayToken);
    if (!displayId) {
        return NAME_NOT_FOUND;
    }

    return getHwComposer().getDisplayedContentSample(*display->getId(), maxFrames, timestamp,
                                                     outStats);
    return getHwComposer().getDisplayedContentSample(*displayId, maxFrames, timestamp, outStats);
}

status_t SurfaceFlinger::getProtectedContentSupport(bool* outSupported) const {
@@ -1387,19 +1383,15 @@ status_t SurfaceFlinger::isWideColorDisplay(const sp<IBinder>& displayToken,
    if (!displayToken || !outIsWideColorDisplay) {
        return BAD_VALUE;
    }
    Mutex::Autolock _l(mStateLock);

    Mutex::Autolock lock(mStateLock);
    const auto display = getDisplayDeviceLocked(displayToken);
    if (!display) {
        return BAD_VALUE;
        return NAME_NOT_FOUND;
    }

    // Use hasWideColorDisplay to override built-in display.
    const auto displayId = display->getId();
    if (displayId && displayId == getInternalDisplayIdLocked()) {
        *outIsWideColorDisplay = hasWideColorDisplay;
        return NO_ERROR;
    }
    *outIsWideColorDisplay = display->hasWideColorGamut();
    *outIsWideColorDisplay =
            display->isPrimary() ? hasWideColorDisplay : display->hasWideColorGamut();
    return NO_ERROR;
}

@@ -1474,6 +1466,9 @@ status_t SurfaceFlinger::getDisplayBrightnessSupport(const sp<IBinder>& displayT
    if (!displayToken || !outSupport) {
        return BAD_VALUE;
    }

    Mutex::Autolock lock(mStateLock);

    const auto displayId = getPhysicalDisplayIdLocked(displayToken);
    if (!displayId) {
        return NAME_NOT_FOUND;
@@ -1483,16 +1478,22 @@ status_t SurfaceFlinger::getDisplayBrightnessSupport(const sp<IBinder>& displayT
    return NO_ERROR;
}

status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken,
                                              float brightness) const {
status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) {
    if (!displayToken) {
        return BAD_VALUE;
    }
    const auto displayId = getPhysicalDisplayIdLocked(displayToken);
    if (!displayId) {
        return NAME_NOT_FOUND;

    status_t result = NAME_NOT_FOUND;

    postMessageSync(new LambdaMessage([&] {
        if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
            result = getHwComposer().setDisplayBrightness(*displayId, brightness);
        } else {
            ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
        }
    return getHwComposer().setDisplayBrightness(*displayId, brightness);
    }));

    return result;
}

status_t SurfaceFlinger::notifyPowerHint(int32_t hintId) {
@@ -4233,7 +4234,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int

void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
    postMessageSync(new LambdaMessage([&]() NO_THREAD_SAFETY_ANALYSIS {
        const auto display = getDisplayDevice(displayToken);
        const auto display = getDisplayDeviceLocked(displayToken);
        if (!display) {
            ALOGE("Attempt to set power mode %d for invalid display token %p", mode,
                  displayToken.get());
@@ -5346,10 +5347,10 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& displayToken,

    sp<DisplayDevice> display;
    {
        Mutex::Autolock _l(mStateLock);
        Mutex::Autolock lock(mStateLock);

        display = getDisplayDeviceLocked(displayToken);
        if (!display) return BAD_VALUE;
        if (!display) return NAME_NOT_FOUND;

        // set the requested width/height to the logical display viewport size
        // by default
@@ -5425,10 +5426,10 @@ status_t SurfaceFlinger::captureScreen(uint64_t displayOrLayerStack, Dataspace*
    uint32_t height;
    ui::Transform::RotationFlags captureOrientation;
    {
        Mutex::Autolock _l(mStateLock);
        Mutex::Autolock lock(mStateLock);
        display = getDisplayByIdOrLayerStack(displayOrLayerStack);
        if (!display) {
            return BAD_VALUE;
            return NAME_NOT_FOUND;
        }

        width = uint32_t(display->getViewport().width());
@@ -5563,7 +5564,7 @@ status_t SurfaceFlinger::captureLayers(
    std::unordered_set<sp<Layer>, ISurfaceComposer::SpHash<Layer>> excludeLayers;
    Rect displayViewport;
    {
        Mutex::Autolock _l(mStateLock);
        Mutex::Autolock lock(mStateLock);

        parent = fromHandle(layerHandleBinder);
        if (parent == nullptr || parent->isRemovedFromCurrentState()) {
@@ -5607,9 +5608,9 @@ status_t SurfaceFlinger::captureLayers(
            }
        }

        auto display = getDisplayByLayerStack(parent->getLayerStack());
        const auto display = getDisplayByLayerStack(parent->getLayerStack());
        if (!display) {
            return BAD_VALUE;
            return NAME_NOT_FOUND;
        }

        displayViewport = display->getViewport();
@@ -5996,17 +5997,16 @@ status_t SurfaceFlinger::setDesiredDisplayConfigSpecs(const sp<IBinder>& display
        return BAD_VALUE;
    }

    status_t result = NO_ERROR;
    status_t result = NAME_NOT_FOUND;

    postMessageSync(new LambdaMessage([&]() {
        const auto display = getDisplayDeviceLocked(displayToken);
        if (!display) {
            result = BAD_VALUE;
            ALOGE("Attempt to set desired display configs for invalid display token %p",
                  displayToken.get());
        } else if (display->isVirtual()) {
            result = BAD_VALUE;
            ALOGW("Attempt to set desired display configs for virtual display");
            result = INVALID_OPERATION;
        } else {
            result = setDesiredDisplayConfigSpecsInternal(display,
                                                          scheduler::RefreshRateConfigs::
@@ -6045,12 +6045,11 @@ status_t SurfaceFlinger::getDesiredDisplayConfigSpecs(const sp<IBinder>& display
        *outMaxRefreshRate = policy.maxRefreshRate;
        return NO_ERROR;
    } else if (display->isVirtual()) {
        return BAD_VALUE;
        return INVALID_OPERATION;
    } else {
        const auto displayId = display->getId();
        if (!displayId) {
            return BAD_VALUE;
        }
        LOG_FATAL_IF(!displayId);

        *outDefaultConfig = getHwComposer().getActiveConfigIndex(*displayId);
        auto vsyncPeriod = getHwComposer().getActiveConfig(*displayId)->getVsyncPeriod();
        *outMinRefreshRate = 1e9f / vsyncPeriod;
+5 −21
Original line number Diff line number Diff line
@@ -475,14 +475,13 @@ private:
    status_t getCompositionPreference(ui::Dataspace* outDataspace, ui::PixelFormat* outPixelFormat,
                                      ui::Dataspace* outWideColorGamutDataspace,
                                      ui::PixelFormat* outWideColorGamutPixelFormat) const override;
    status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& display,
    status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& displayToken,
                                                   ui::PixelFormat* outFormat,
                                                   ui::Dataspace* outDataspace,
                                                   uint8_t* outComponentMask) const override;
    status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
                                              uint8_t componentMask,
                                              uint64_t maxFrames) const override;
    status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames,
    status_t setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken, bool enable,
                                              uint8_t componentMask, uint64_t maxFrames) override;
    status_t getDisplayedContentSample(const sp<IBinder>& displayToken, uint64_t maxFrames,
                                       uint64_t timestamp,
                                       DisplayedFrameStats* outStats) const override;
    status_t getProtectedContentSupport(bool* outSupported) const override;
@@ -498,7 +497,7 @@ private:
                                          float* outMaxRefreshRate) override;
    status_t getDisplayBrightnessSupport(const sp<IBinder>& displayToken,
                                         bool* outSupport) const override;
    status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) const override;
    status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) override;
    status_t notifyPowerHint(int32_t hintId) override;
    status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
                                     float lightPosY, float lightPosZ, float lightRadius) override;
@@ -579,11 +578,6 @@ private:
            const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy)
            EXCLUDES(mStateLock);

    // called on the main thread in response to setAutoLowLatencyMode()
    void setAutoLowLatencyModeInternal(const sp<IBinder>& displayToken, bool on);
    // called on the main thread in response to setGameContentType()
    void setGameContentTypeInternal(const sp<IBinder>& displayToken, bool on);

    // Returns whether the transaction actually modified any state
    bool handleMessageTransaction();

@@ -738,16 +732,6 @@ private:
    // called when starting, or restarting after system_server death
    void initializeDisplays();

    sp<const DisplayDevice> getDisplayDevice(const wp<IBinder>& displayToken) const {
        Mutex::Autolock _l(mStateLock);
        return getDisplayDeviceLocked(displayToken);
    }

    sp<DisplayDevice> getDisplayDevice(const wp<IBinder>& displayToken) {
        Mutex::Autolock _l(mStateLock);
        return getDisplayDeviceLocked(displayToken);
    }

    // NOTE: can only be called from the main thread or with mStateLock held
    sp<const DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) const {
        return const_cast<SurfaceFlinger*>(this)->getDisplayDeviceLocked(displayToken);
Loading