diff --git a/dmserver/include/abstract_display_controller.h b/dmserver/include/abstract_display_controller.h index 811abce4..17252cf5 100644 --- a/dmserver/include/abstract_display_controller.h +++ b/dmserver/include/abstract_display_controller.h @@ -26,6 +26,7 @@ #include "screen.h" #include "abstract_display.h" #include "transaction/rs_interfaces.h" +#include "future.h" namespace OHOS::Rosen { class AbstractDisplayController : public RefBase { @@ -55,22 +56,28 @@ private: sptr abstractScreenCallback_; OHOS::Rosen::RSInterfaces *rsInterface_; - class ScreenshotCallback : public SurfaceCaptureCallback { + class ScreenshotCallback : public SurfaceCaptureCallback, public Future> { public: ScreenshotCallback() = default; ~ScreenshotCallback() {}; void OnSurfaceCapture(std::shared_ptr pixelmap) override { - if (flag_ == false) { + FutureCall(pixelmap); + } + + protected: + void Call(std::shared_ptr pixelmap) override + { + if (!flag_) { flag_ = true; pixelMap_ = pixelmap; } } - bool IsPixelMapOk() + bool IsReady() override { return flag_; } - std::shared_ptr GetPixelMap() + std::shared_ptr FetchResult() override { return pixelMap_; } diff --git a/dmserver/src/abstract_display_controller.cpp b/dmserver/src/abstract_display_controller.cpp index 6bd95128..be4e6380 100644 --- a/dmserver/src/abstract_display_controller.cpp +++ b/dmserver/src/abstract_display_controller.cpp @@ -90,18 +90,7 @@ std::shared_ptr AbstractDisplayController::GetScreenSnapshot(Di std::shared_ptr callback = std::make_shared(); rsInterface_->TakeSurfaceCapture(displayNode, callback); - - int counter = 0; - while (!callback->IsPixelMapOk()) { - usleep(10000); // 10000us equals to 10ms - counter++; - if (counter >= 200) { // wait for 200 * 10ms = 2s - WLOGFE("Failed to get pixelmap, timeout"); - return nullptr; - } - } - std::shared_ptr screenshot = callback->GetPixelMap(); - + std::shared_ptr screenshot = callback->GetResult(2000); // wait for 2000ms if (screenshot == nullptr) { WLOGFE("Failed to get pixelmap from RS, return nullptr!"); } diff --git a/dmserver/src/abstract_screen_controller.cpp b/dmserver/src/abstract_screen_controller.cpp index c21a1d9f..c482bccd 100644 --- a/dmserver/src/abstract_screen_controller.cpp +++ b/dmserver/src/abstract_screen_controller.cpp @@ -51,8 +51,11 @@ void AbstractScreenController::Init() std::vector AbstractScreenController::GetAllScreenIds() { - std::vector tmp; - return tmp; + std::vector res; + for (auto iter = dmsScreenMap_.begin(); iter != dmsScreenMap_.end(); iter++) { + res.push_back(iter->first); + } + return res; } sptr AbstractScreenController::GetAbstractScreen(ScreenId dmsScreenId) @@ -136,13 +139,12 @@ void AbstractScreenController::OnRsScreenChange(ScreenId rsScreenId, ScreenEvent void AbstractScreenController::ProcessScreenDisconnected(ScreenId rsScreenId) { WLOGI("disconnect screen, screenId=%{public}" PRIu64"", rsScreenId); - ScreenId dmsScreenId = INVALID_SCREEN_ID; auto iter = rs2DmsScreenIdMap_.find(rsScreenId); if (iter == rs2DmsScreenIdMap_.end()) { WLOGE("disconnect screen, screenId=%{public}" PRIu64" is not in rs2DmsScreenIdMap_", rsScreenId); return; } - dmsScreenId = iter->second; + ScreenId dmsScreenId = iter->second; auto dmsScreenMapIter = dmsScreenMap_.find(dmsScreenId); if (dmsScreenMapIter != dmsScreenMap_.end()) { if (abstractScreenCallback_ != nullptr && CheckScreenInScreenGroup(dmsScreenMapIter->second)) { diff --git a/utils/include/future.h b/utils/include/future.h new file mode 100644 index 00000000..62b006e3 --- /dev/null +++ b/utils/include/future.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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 p ermissions and + * limitations under the License. + */ + +#ifndef OHOS_WM_INCLUDE_FUTURE_H +#define OHOS_WM_INCLUDE_FUTURE_H + +#include "hilog/log.h" + +namespace OHOS::Rosen { +template +class Future { + constexpr static HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "Future"}; +public: + T GetResult(long timeOut) + { + std::unique_lock lock(mutex_); + if (!conditionVariable_.wait_for(lock, std::chrono::milliseconds(timeOut), [this] { return IsReady(); })) { + OHOS::HiviewDFX::HiLog::Error(LABEL, "wait for %{public}ld, timeout.", timeOut); + } + return FetchResult(); + } + +protected: + virtual bool IsReady() = 0; + + virtual T FetchResult() = 0; + + virtual void Call(T) = 0; + + void FutureCall(T t) + { + std::unique_lock lock(mutex_); + Call(t); + conditionVariable_.notify_one(); + } + +private: + std::condition_variable conditionVariable_; + std::mutex mutex_; +}; +} // namespace OHOS::Rosen +#endif // OHOS_WM_INCLUDE_FUTURE_H