diff --git a/interfaces/kits/cj/BUILD.gn b/interfaces/kits/cj/BUILD.gn index bc6da4e48d6b45eb49e79ca0dbfd29c4f8476e9e..943858b06eb6bcb4269e7f90260f58d4fe61c794 100644 --- a/interfaces/kits/cj/BUILD.gn +++ b/interfaces/kits/cj/BUILD.gn @@ -16,6 +16,7 @@ import("//build/ohos.gni") group("ffi_packages") { deps = [ "display_runtime:cj_display_ffi", + "screenshot:cj_screenshot_ffi", "window_runtime:cj_window_ffi", ] } diff --git a/interfaces/kits/cj/screenshot/BUILD.gn b/interfaces/kits/cj/screenshot/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..6e3fcfc00f10a1eb78a19d9636eb8dcdd272c1ef --- /dev/null +++ b/interfaces/kits/cj/screenshot/BUILD.gn @@ -0,0 +1,55 @@ +# Copyright (c) 2025 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 permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("../../../../windowmanager_aafwk.gni") + +## Build cj_screenshot_ffi.so {{{ +ohos_shared_library("cj_screenshot_ffi") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + configs = [ "../../../../resources/config/build:coverage_flags" ] + + if (!build_ohos_sdk) { + sources = [ + "cj_screenshot_module.cpp", + "screenshot_ffi.cpp", + ] + deps = [ + "../../../../dm:libdm", + "../../../../utils:libwmutil", + "../../../../utils:libwmutil_base", + ] + external_deps = [ + "hilog:libhilog", + "image_framework:cj_image_ffi", + "image_framework:image", + "image_framework:image_native", + "napi:ace_napi", + "napi:cj_bind_ffi", + "napi:cj_bind_native", + ] + } else { + defines += [ "PREVIEWER" ] + sources = [ "display_runtime_mock.cpp" ] + external_deps = [ "napi:cj_bind_ffi" ] + } + innerapi_tags = [ "platformsdk" ] + part_name = "window_manager" + subsystem_name = "window" +} +## Build cj_screenshot_ffi.so }}} diff --git a/interfaces/kits/cj/screenshot/cj_screenshot_module.cpp b/interfaces/kits/cj/screenshot/cj_screenshot_module.cpp new file mode 100644 index 0000000000000000000000000000000000000000..92ca5714a0c5ccfda93482a7c608d14f46007fa0 --- /dev/null +++ b/interfaces/kits/cj/screenshot/cj_screenshot_module.cpp @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2025 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 permissions and + * limitations under the License. + */ + +#include "cj_screenshot_module.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "display_manager.h" +#include "pixel_map.h" +#include "pixel_map_impl.h" +#include "window_manager_hilog.h" +#include "dm_common.h" + +using namespace OHOS::FFI; +using namespace OHOS::Media; + +namespace OHOS { +namespace Rosen { +struct Option { + Media::Rect rect; + Media::Size size; + int rotation = 0; + DisplayId displayId = 0; + bool isNeedNotify = true; + bool isNeedPointer = true; +}; + +struct Param { + DmErrorCode wret; + Option option; + std::string errMessage; + bool useInputOption; + bool validInputParam; + std::shared_ptr image; + Media::Rect imageRect; + bool isPick; +}; + +static CRect CreateRectObject(const Media::Rect& imageRect) +{ + CRect rect; + rect.left = imageRect.left; + rect.top = imageRect.top; + rect.width = imageRect.width; + rect.height = imageRect.height; + return rect; +} + +static std::unique_ptr CreatePickerObject(const std::unique_ptr& param) +{ + if (param == nullptr) { + TLOGE(WmsLogTag::WMS_SCB, "param nullptr."); + return nullptr; + } + auto pickInfo = std::make_unique(); + pickInfo->pickRect = CreateRectObject(param->imageRect); + + auto nativeImage = FFIData::Create(move(param->image)); + if (nativeImage == nullptr) { + TLOGE(WmsLogTag::WMS_SCB, "create image failed"); + return pickInfo; + } + TLOGI(WmsLogTag::WMS_SCB, "pick end"); + pickInfo->pixelMap = nativeImage->GetID(); + return pickInfo; +} + +static RetStruct Resolve(std::unique_ptr& param, RetStruct ret) +{ + bool isThrowError = true; + switch (param->wret) { + case DmErrorCode::DM_ERROR_NO_PERMISSION: + TLOGE(WmsLogTag::WMS_SCB, "[CJScreenshotModule] Get default DmErrorCode is DM_ERROR_NO_PERMISSION"); + ret.code = static_cast(DmErrorCode::DM_ERROR_NO_PERMISSION); + break; + case DmErrorCode::DM_ERROR_INVALID_PARAM: + TLOGE(WmsLogTag::WMS_SCB, "[CJScreenshotModule] Get default DmErrorCode is DM_ERROR_INVALID_PARAM"); + ret.code = static_cast(DmErrorCode::DM_ERROR_INVALID_PARAM); + break; + case DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT: + TLOGE(WmsLogTag::WMS_SCB, "[CJScreenshotModule] Get default DmErrorCode is DM_ERROR_DEVICE_NOT_SUPPORT"); + ret.code = static_cast(DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT); + break; + case DmErrorCode::DM_ERROR_SYSTEM_INNORMAL: + ret.code = static_cast(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL); + break; + default: + isThrowError = false; + ret.code = static_cast(DmErrorCode::DM_OK); + break; + } + TLOGI(WmsLogTag::WMS_SCB, "screen shot ret=%{public}d.", param->wret); + if (isThrowError) { + return ret; + } + if (param->wret != DmErrorCode::DM_OK) { + ret.code = static_cast(param->wret); + TLOGE(WmsLogTag::WMS_SCB, "ret is not DmErrorCode DM_OK, errorCode:%{public}d", param->wret); + return ret; + } + if (param->isPick) { + TLOGI(WmsLogTag::WMS_SCB, "Resolve Screenshot by picker"); + std::unique_ptr pickInfoPtr(CreatePickerObject(param)); + ret.data = static_cast(pickInfoPtr.get()); + return ret; + } + TLOGI(WmsLogTag::WMS_SCB, "Screenshot image Width %{public}d, Height %{public}d", + param->image->GetWidth(), param->image->GetHeight()); + auto nativeImage = FFIData::Create(move(param->image)); + if (nativeImage == nullptr) { + TLOGE(WmsLogTag::WMS_SCB, "create image failed"); + return ret; + } + int64_t* pixelId = new int64_t(nativeImage->GetID()); + ret.data = pixelId; + return ret; +} + +static void GetScreenshot(std::unique_ptr& param) +{ + if (!param->validInputParam) { + TLOGE(WmsLogTag::WMS_SCB, "Invalid Input Param!"); + param->image = nullptr; + param->wret = DmErrorCode::DM_ERROR_INVALID_PARAM; + param->errMessage = "Get Screenshot Failed: Invalid input param"; + return; + } + CaptureOption option = { param->option.displayId, param->option.isNeedNotify, param->option.isNeedPointer }; + if (!param->isPick && (!option.isNeedNotify_ || !option.isNeedPointer_)) { + if (param->useInputOption) { + param->image = DisplayManager::GetInstance().GetScreenshotWithOption(option, + param->option.rect, param->option.size, param->option.rotation, ¶m->wret); + } else { + param->image = DisplayManager::GetInstance().GetScreenshotWithOption(option, ¶m->wret); + } + } else { + if (param->useInputOption) { + TLOGI(WmsLogTag::WMS_SCB, "Get Screenshot by input option"); + SnapShotConfig snapConfig; + snapConfig.displayId_ = param->option.displayId; + snapConfig.imageRect_ = param->option.rect; + snapConfig.imageSize_ = param->option.size; + snapConfig.rotation_ = param->option.rotation; + param->image = DisplayManager::GetInstance().GetScreenshotwithConfig(snapConfig, ¶m->wret, true); + } else if (param->isPick) { + TLOGI(WmsLogTag::WMS_SCB, "Get Screenshot by picker"); + param->image = DisplayManager::GetInstance().GetSnapshotByPicker(param->imageRect, ¶m->wret); + } else { + TLOGI(WmsLogTag::WMS_SCB, "Get Screenshot by default option"); + param->image = DisplayManager::GetInstance().GetScreenshot(param->option.displayId, ¶m->wret, true); + } + } + if (param->image == nullptr && param->wret == DmErrorCode::DM_OK) { + TLOGE(WmsLogTag::WMS_SCB, "Get Screenshot failed!"); + param->wret = DmErrorCode::DM_ERROR_INVALID_SCREEN; + param->errMessage = "Get Screenshot failed: Screenshot image is nullptr"; + } +} + +static void GetScreenCapture(std::unique_ptr& param) +{ + CaptureOption captureOption; + captureOption.displayId_ = param->option.displayId; + captureOption.isNeedNotify_ = param->option.isNeedNotify; + captureOption.isNeedPointer_ = param->option.isNeedPointer; + TLOGI(WmsLogTag::WMS_SCB, "capture option isNeedNotify=%{public}d isNeedPointer=%{public}d", + captureOption.isNeedNotify_, captureOption.isNeedPointer_); + param->image = DisplayManager::GetInstance().GetScreenCapture(captureOption, ¶m->wret); + if (param->image == nullptr && param->wret == DmErrorCode::DM_OK) { + TLOGE(WmsLogTag::WMS_SCB, "screen capture failed!"); + param->wret = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL; + param->errMessage = "ScreenCapture failed: image is null."; + } +} + +RetStruct CJScreenshotModule::PickFunc() +{ + TLOGI(WmsLogTag::WMS_SCB, "%{public}s called", __PRETTY_FUNCTION__); + + RetStruct ret = { .code = static_cast(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL), .len = 0, .data = nullptr }; + auto param = std::make_unique(); + if (param == nullptr) { + TLOGE(WmsLogTag::WMS_SCB, "Create param failed."); + return ret; + } + param->validInputParam = true; + param->isPick = true; + GetScreenshot(param); + Resolve(param, ret); + return ret; +} + +RetStruct CJScreenshotModule::CaptureFunc(uint32_t displayId) +{ + TLOGI(WmsLogTag::WMS_SCB, "%{public}s called", __PRETTY_FUNCTION__); + + RetStruct ret = { .code = static_cast(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL), .len = 0, .data = nullptr }; + auto param = std::make_unique(); + if (param == nullptr) { + TLOGE(WmsLogTag::WMS_SCB, "Create param failed."); + return ret; + } + param->option.displayId = displayId; + GetScreenCapture(param); + Resolve(param, ret); + return ret; +} +} // namespace Rosen +} // namespace OHOS diff --git a/interfaces/kits/cj/screenshot/cj_screenshot_module.h b/interfaces/kits/cj/screenshot/cj_screenshot_module.h new file mode 100644 index 0000000000000000000000000000000000000000..168ae89c2fcafecef6e68cb59bbe34ab6dcebb8d --- /dev/null +++ b/interfaces/kits/cj/screenshot/cj_screenshot_module.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 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 permissions and + * limitations under the License. + */ + +#ifndef CJ_SCREENSHOT_MODULE_H +#define CJ_SCREENSHOT_MODULE_H + +#include + +#include "screenshot_utils.h" +#include "ffi_remote_data.h" + +namespace OHOS { +namespace Rosen { + +class CJScreenshotModule { +public: + static RetStruct PickFunc(); + static RetStruct CaptureFunc(uint32_t displayId); +}; + +} // namespace Rosen +} // namespace OHOS + +#endif // CJ_SCREENSHOT_MODULE_H diff --git a/interfaces/kits/cj/screenshot/screenshot_ffi.cpp b/interfaces/kits/cj/screenshot/screenshot_ffi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0313bc3b849206200e8fa306863412ff1dbc3071 --- /dev/null +++ b/interfaces/kits/cj/screenshot/screenshot_ffi.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 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 permissions and + * limitations under the License. + */ + +#include "screenshot_ffi.h" + +#include "cj_screenshot_module.h" +#include "ffi_remote_data.h" +#include "window_manager_hilog.h" + +using namespace OHOS::FFI; + +namespace OHOS { +namespace Rosen { +extern "C" { +RetStruct FfiOHOSScreenshotPick() +{ + TLOGI(WmsLogTag::WMS_SCB, "FfiOHOSScreenshotPick start"); + return CJScreenshotModule::PickFunc(); +} + +RetStruct FfiOHOSScreenshotCapture(uint32_t displayId) +{ + TLOGI(WmsLogTag::WMS_SCB, "FfiOHOSScreenshotCapture start"); + return CJScreenshotModule::CaptureFunc(displayId); +} +} +} // namespace Rosen +} // namespace OHOS diff --git a/interfaces/kits/cj/screenshot/screenshot_ffi.h b/interfaces/kits/cj/screenshot/screenshot_ffi.h new file mode 100644 index 0000000000000000000000000000000000000000..f8ede1e73b89d4247ec52ec9038434db34eeabbc --- /dev/null +++ b/interfaces/kits/cj/screenshot/screenshot_ffi.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 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 permissions and + * limitations under the License. + */ + +#ifndef OHOS_SCREENSHOT_FFI_H +#define OHOS_SCREENSHOT_FFI_H + +#include "cj_common_ffi.h" +#include "screenshot_utils.h" + +extern "C" { +FFI_EXPORT RetStruct FfiOHOSScreenshotPick(); +FFI_EXPORT RetStruct FfiOHOSScreenshotCapture(uint32_t displayId); +} + +#endif // SCREENSHOT_FFI_H diff --git a/interfaces/kits/cj/screenshot/screenshot_mock.cpp b/interfaces/kits/cj/screenshot/screenshot_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ea0ef3a07f30efeea3c3a42f0c8e4c1085d9f3fb --- /dev/null +++ b/interfaces/kits/cj/screenshot/screenshot_mock.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 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 permissions and + * limitations under the License. + */ + +extern "C" { +FFI_EXPORT int FfiOHOSScreenshotPick = 0; +FFI_EXPORT int FfiOHOSScreenshotCapture = 0; +} diff --git a/interfaces/kits/cj/screenshot/screenshot_utils.h b/interfaces/kits/cj/screenshot/screenshot_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..3baa39d152b520b8503865e8e99c0b80a96019da --- /dev/null +++ b/interfaces/kits/cj/screenshot/screenshot_utils.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025 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 permissions and + * limitations under the License. + */ + +#ifndef OHOS_SCREENSHOT_UTILS_H +#define OHOS_SCREENSHOT_UTILS_H + +#include +#include +#include + +extern "C" { +typedef struct { + int32_t code; + int64_t len; + void* data; +} RetStruct; + +typedef struct { + int32_t left; + int32_t top; + uint32_t width; + uint32_t height; +} CRect; + +typedef struct { + CRect pickRect; + int64_t pixelMap; +} CPickInfo; +} + +#endif // OHOS_SCREENSHOT_UTILS_H