From f307ac0f4237b44e9f599bdca50a249790fca205 Mon Sep 17 00:00:00 2001 From: KangPeng Date: Fri, 12 Sep 2025 16:54:50 +0800 Subject: [PATCH 1/4] msdp taihe 1.2 test Signed-off-by: KangPeng --- bundle.json | 3 +- frameworks/ets/metadataBinding/BUILD.gn | 105 +++++ ....multimodalAwareness.metadataBinding.taihe | 45 ++ .../metadataBinding/include/ani_boomerang.h | 74 +++ .../include/ani_boomerang_manager.h | 121 +++++ .../ets/metadataBinding/src/ani_boomerang.cpp | 200 ++++++++ .../src/ani_boomerang_manager.cpp | 443 ++++++++++++++++++ .../metadataBinding/src/ani_constructor.cpp | 21 + ...ltimodalAwareness.metadataBinding.impl.cpp | 55 +++ .../ets/metadataBinding/test/test_main.ets | 102 ++++ 10 files changed, 1168 insertions(+), 1 deletion(-) create mode 100644 frameworks/ets/metadataBinding/BUILD.gn create mode 100644 frameworks/ets/metadataBinding/idl/ohos.multimodalAwareness.metadataBinding.taihe create mode 100644 frameworks/ets/metadataBinding/include/ani_boomerang.h create mode 100644 frameworks/ets/metadataBinding/include/ani_boomerang_manager.h create mode 100644 frameworks/ets/metadataBinding/src/ani_boomerang.cpp create mode 100644 frameworks/ets/metadataBinding/src/ani_boomerang_manager.cpp create mode 100644 frameworks/ets/metadataBinding/src/ani_constructor.cpp create mode 100644 frameworks/ets/metadataBinding/src/ohos.multimodalAwareness.metadataBinding.impl.cpp create mode 100644 frameworks/ets/metadataBinding/test/test_main.ets diff --git a/bundle.json b/bundle.json index d39633b50..bf17818b9 100644 --- a/bundle.json +++ b/bundle.json @@ -100,7 +100,8 @@ "//base/msdp/device_status/frameworks/js/napi/boomerang:metadatabinding_napi", "//base/msdp/device_status/frameworks/js/napi/device_status:devicestatus_napi", "//base/msdp/device_status/frameworks/js/napi/underage_model:userstatus_napi", - "//base/msdp/device_status/frameworks/ets/drag:dragInteraction" + "//base/msdp/device_status/frameworks/ets/drag:dragInteraction"£¬ + "//base/msdp/device_status/frameworks/ets/metadataBinding:metadataBinding" ], "service_group":[ "//base/msdp/device_status/libs:devicestatus_algo", diff --git a/frameworks/ets/metadataBinding/BUILD.gn b/frameworks/ets/metadataBinding/BUILD.gn new file mode 100644 index 000000000..fd361485e --- /dev/null +++ b/frameworks/ets/metadataBinding/BUILD.gn @@ -0,0 +1,105 @@ +# 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/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//build/ohos/taihe_idl/taihe.gni") +import("//base/msdp/device_status/device_status.gni") +copy_taihe_idl("metadataBinding_taihe") { + sources = [ "idl/ohos.multimodalAwareness.metadataBinding.taihe" ] +} +subsystem_name = "msdp" +part_name = "device_status" +taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name/metadataBinding" +ohos_taihe("run_taihe") { + taihe_generated_file_path = "$taihe_generated_file_path" + deps = [ ":metadataBinding_taihe" ] + outputs = [ + "$taihe_generated_file_path/src/ohos.multimodalAwareness.metadataBinding.ani.cpp", + "$taihe_generated_file_path/src/ohos.multimodalAwareness.metadataBinding.abi.c", + ] +} +taihe_shared_library("MetadataBinding") { + taihe_generated_file_path = "$taihe_generated_file_path" + part_name = "$part_name" + subsystem_name = "$subsystem_name" + sources = get_target_outputs(":run_taihe") + branch_protector_ret = "pac_ret" + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + include_dirs = [ + #"../common", + "include", + "${device_status_utils_path}/include", + "${device_status_root_path}/utils/common/include", + "${device_status_interfaces_path}/innerkits/interaction/include", + "${device_status_interfaces_path}/innerkits/include/", + "${device_status_frameworks_path}/native/interaction/include" + ] + external_deps = [ + "c_utils:utils", + "graphic_2d:librender_service_client", + "graphic_2d:librender_service_base", + "hilog:libhilog", + "image_framework:image_native", + "image_framework:image_taihe", + #"${device_status_interfaces_path}/innerkits:devicestatus_client", + ] + sources += [ + "src/ani_constructor.cpp", + "src/ani_boomerang.cpp", + "src/ani_boomerang_manager.cpp", + "src/ohos.multimodalAwareness.metadataBinding.impl.cpp", + #"${device_status_interfaces_path}/../intention/boomerang/client/src/boomerang_client.cpp" + ] + deps = [ + ":run_taihe", + "${device_status_interfaces_path}/innerkits:devicestatus_client", + "${device_status_utils_path}:devicestatus_util", + ] +} + +generate_static_abc("metadataBinding_abc") { + base_url = "$taihe_generated_file_path" + files = [ "$taihe_generated_file_path/@ohos.multimodalAwareness.metadataBinding.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/metadataBinding_abc.abc" + dependencies = [ ":run_taihe" ] +} + +ohos_prebuilt_etc("metadataBinding_etc") { + source = "$target_out_dir/metadataBinding_abc.abc" + module_install_dir = "framework" + part_name = "$part_name" + subsystem_name = "$subsystem_name" + deps = [ ":metadataBinding_abc" ] +} + +generate_static_abc("metadataBinding_taihe_test") { + base_url = "${device_status_frameworks_path}/ets/metadataBinding" + files = [ "$base_url/test/test_main.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/metadataBinding_taihe_test.abc" +} + +group("metadataBinding") { + deps = [ + ":metadataBinding_etc", + ":MetadataBinding", + ":metadataBinding_taihe_test", + ] +} \ No newline at end of file diff --git a/frameworks/ets/metadataBinding/idl/ohos.multimodalAwareness.metadataBinding.taihe b/frameworks/ets/metadataBinding/idl/ohos.multimodalAwareness.metadataBinding.taihe new file mode 100644 index 000000000..fa0ba6f1e --- /dev/null +++ b/frameworks/ets/metadataBinding/idl/ohos.multimodalAwareness.metadataBinding.taihe @@ -0,0 +1,45 @@ +/* + * 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. + */ + +@!namespace("@ohos.multimodalAwareness.metadataBinding", "metadataBinding") + +@!sts_inject_into_module("import image from '@ohos.multimedia.image';") + +@!sts_inject(""" +static +{ loadLibrary("MetadataBinding.z") } +""") + +@!sts_inject(""" + function on(type: 'operationSubmitMetadata', bundleName: string, callback: (info: int) => void) { + return onMetadata(bundleName, callback, callback); + } + function off(type: 'operationSubmitMetadata', bundleName: string, callback?: (info: int) => void) { + return offMetadata(bundleName, callback); + } +""") + +function onMetadata(bundleName: String, callbck: (info: i32) => void, opq: Opaque); +function offMetadata(bundleName: String, opq: Optional); + +function submitMetadata(metadata: String): void; + +@gen_promise("notifyMetadataBindingEvent") +function notifyMetadataBindingEventPromise(bundleName: String): @sts_type("Promise") Opaque; +@gen_promise("encodeImage") +function encodeImagePromise(srcImage: @sts_type("image.PixelMap") Opaque, metadata: String): @sts_type("Promise") Opaque; +@gen_promise("decodeImage") +function decodeImagePromise(encodedImage: @sts_type("image.PixelMap") Opaque): @sts_type("Promise") Opaque; + diff --git a/frameworks/ets/metadataBinding/include/ani_boomerang.h b/frameworks/ets/metadataBinding/include/ani_boomerang.h new file mode 100644 index 000000000..32b017bb2 --- /dev/null +++ b/frameworks/ets/metadataBinding/include/ani_boomerang.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024-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. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "taihe/runtime.hpp" +#include "pixel_map_taihe_ani.h" +#include "fi_log.h" +#include "boomerang_data.h" + +namespace OHOS { +namespace Msdp { +namespace DeviceStatus { +using namespace taihe; + +typedef void (*EncodeImagePtr)(std::shared_ptr &pixelMap, const std::string &content, + std::shared_ptr &resultPixelMap); +typedef void (*DecodeImagePtr)(std::shared_ptr &pixelMap, std::string &content); + +struct AniBoomerangEventListener { + ani_ref onHandlerRef { nullptr }; +}; + +class AniBoomerangEvent { +public: + AniBoomerangEvent() = default; + ~AniBoomerangEvent() = default; + + bool On(int32_t eventType, ani_ref handler, bool isOnce); + bool Off(int32_t eventType); + void OnEvent(int32_t eventType, int32_t value, bool isOnce); + +protected: + bool OffOnce(int32_t eventType, ani_ref handler); + + void ClearEventMap(); + bool RemoveAllCallback(int32_t eventType); + bool SaveCallbackByEvent(int32_t eventType, ani_ref handler, bool isOnce, + std::map>> events); + bool IsNoExistCallback(std::list>, + ani_ref handler, int32_t eventType); + void SaveCallback(int32_t eventType, ani_ref onHandlerRef, bool isOnce); + + ani_env env_ { nullptr }; + ani_ref thisVarRef_ { nullptr }; + std::mutex mutex_; + std::vector data_; + std::map>> events_; + std::map>> eventOnces_; +}; + +} // namespace DeviceStatus +} // namespace Msdp +} // namespace OHOS +// #endif // DEVICESTATUS_EVENT_H diff --git a/frameworks/ets/metadataBinding/include/ani_boomerang_manager.h b/frameworks/ets/metadataBinding/include/ani_boomerang_manager.h new file mode 100644 index 000000000..a75c8d6de --- /dev/null +++ b/frameworks/ets/metadataBinding/include/ani_boomerang_manager.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2023 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. + */ + +#pragma once + +#include +#include +#include + +#include "ohos.multimodalAwareness.metadataBinding.proj.hpp" +#include "ohos.multimodalAwareness.metadataBinding.impl.hpp" +#include "ani_boomerang.h" +#include "taihe/runtime.hpp" +#include "taihe/callback.hpp" +#include "taihe/optional.hpp" +#include "stdexcept" +#include "boomerang_data.h" +#include "boomerang_callback_stub.h" +#include "devicestatus_client.h" +#include "devicestatus_errors.h" +#include "boomerang_manager.h" +#include + +namespace OHOS { +namespace Msdp { +namespace DeviceStatus { +// AniBoomerang == BoomerangNapi +using namespace ::taihe; +#ifndef RET_OK + #define RET_OK (0) +#endif + +const std::map MetadataBindingLogInfo = { + {SUBSCRIBE_FAILED, "Subscribe Failed. Possible causes: 1. Abnormal system capability;" + "2. IPC communication abnormality; 3. Algorithm loading exception."}, + {UNSUBSCRIBE_FAILED, "Unsubscribe Failed. Possible causes: 1. Abnormal system capability;" + "2. IPC communication abnormality."}, + {HANDLER_FAILD, "notify metadataBinding event error by Create execution."}, + {ENCODE_FAILED, "encode image error by Create execution"}, + {DECODE_FAILED, "decode image error by Create execution"} +}; + +// class MetadataBindingCommon final { +// public: +// static void ExecAsyncCallbackPromise(ani_env *env, ani_resolver deferred, ani_ref data, ani_ref businessError); +// static ani_ref CreateBusinessError(ani_env* env, ani_int code, const std::string& msg); +// static ani_object WrapBusinessError(ani_env* env, const std::string& msg); +// static ani_status GetAniEnv(ani_vm* vm, ani_env** env); +// }; + +class AniBoomerangCallback : public BoomerangCallbackStub { +public: + explicit AniBoomerangCallback() = default; + virtual ~AniBoomerangCallback() = default; + bool init(uintptr_t opq = 0); + + void OnScreenshotResult(const BoomerangData& screentshotData) override; + void OnNotifyMetadata(const std::string& metadata) override; + void EmitOnEvent(const DeviceStatus::BoomerangData* data); + void EmitOnMetadata(ani_env env, std::string metadata); + static void EmitOnEncodeImage(ani_env env, std::shared_ptr pixelMap, + ani_resolver deferred); + + + ani_vm* vm_ = nullptr; + ani_env *env_ = nullptr; + ani_env* envT_ = nullptr; + ani_object funObject_ = nullptr; + ani_ref ref_ = nullptr; + ani_object promise_ = nullptr; + ani_resolver deferred_ = nullptr; + bool attach_ = false; + bool result_ = false; + + std::mutex mutex_; + BoomerangData data_; + std::string metadata_; +}; + +class AniBoomerang : public AniBoomerangEvent { +public: + AniBoomerang(); + DISALLOW_COPY_AND_MOVE(AniBoomerang); + ~AniBoomerang(); + void onMetadata(std::string bundleName, ::taihe::callback_view callbck, uintptr_t opq); + void offMetadata(std::string bundleName, ::taihe::optional_view opq); + void notifyMetadataBindingEvent(std::string bundleName, ani_object& promise); + void submitMetadata(std::string metadata); + void encodeImage(uintptr_t srcImage, std::string metadata, ani_object& promise); + void decodeImage(uintptr_t encodedImage, ani_object& promise); + static std::shared_ptr GetInstance(); + void setDeferred(std::string data); + void OnScreenshot(int32_t type, int32_t status, bool isOnce); +private: + bool EncodeImageFunc(std::shared_ptr &pixelMap, const std::string &content, + std::shared_ptr &resultPixelMap); + bool DecodeImageFunc(std::shared_ptr &pixelMap, std::string &content); + + ani_ref ref_; + ani_env *env_ = nullptr; + std::string metadata_; + inline static std::mutex mutex_; +}; + +#define ANI_BOOMERANG_MGR BoomerangManager::GetInstance() +} // namespace DeviceStatus +} // namespace Msdp +} // namespace OHOS +// #endif // JS_COOPERATE_MANAGER_H \ No newline at end of file diff --git a/frameworks/ets/metadataBinding/src/ani_boomerang.cpp b/frameworks/ets/metadataBinding/src/ani_boomerang.cpp new file mode 100644 index 000000000..e51b08d79 --- /dev/null +++ b/frameworks/ets/metadataBinding/src/ani_boomerang.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2024-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 "ani_boomerang.h" + +#include + +#include "devicestatus_define.h" +#include "fi_log.h" + +#undef LOG_TAG +#define LOG_TAG "AniBoomerangEvent" + +namespace OHOS { +namespace Msdp { +namespace DeviceStatus { +namespace { +constexpr size_t EVENT_MAP_MAX { 20 }; +constexpr size_t EVENT_LIST_MAX { 30 }; +} // namespace + +bool AniBoomerangEvent::On(int32_t eventType, ani_ref handler, bool isOnce) +{ + FI_HILOGD("%{public}s On for event:%{public}d, isOnce:%{public}d", LOG_TAG, eventType, isOnce); + std::lock_guard guard(mutex_); + if ((events_.size() > EVENT_MAP_MAX) || (eventOnces_.size() > EVENT_MAP_MAX)) { + FI_HILOGE("%{public}s events_ or eventOnces_ size over", LOG_TAG); + return false; + } + if (events_[eventType].size() > EVENT_LIST_MAX || eventOnces_[eventType].size() > EVENT_LIST_MAX) { + FI_HILOGE("%{public}s list size over", LOG_TAG); + return false; + } + if (isOnce) { + if (!SaveCallbackByEvent(eventType, handler, isOnce, eventOnces_)) { + FI_HILOGE("%{public}s Failed to save eventOnces_ callback", LOG_TAG); + return false; + } + } else { + if (!SaveCallbackByEvent(eventType, handler, isOnce, events_)) { + FI_HILOGE("%{public}s Failed to save events_ callback", LOG_TAG); + return false; + } + } + return true; +} + +bool AniBoomerangEvent::SaveCallbackByEvent(int32_t eventType, ani_ref handler, bool isOnce, + std::map>> events) +{ + CALL_DEBUG_ENTER; + ani_ref onHandlerRef = nullptr; + ani_env *env = taihe::get_env(); + ani_status status = env->GlobalReference_Create(handler, &onHandlerRef); + if (status != ANI_OK) { + FI_HILOGE("%{public}s Failed to napi_create_reference", LOG_TAG); + return false; + } + auto iter = events.find(eventType); + if (iter == events.end()) { + FI_HILOGE("%{public}s eventType:%{public}d not exists", LOG_TAG, eventType); + events[eventType] = std::list>(); + } + if (events[eventType].empty()) { + FI_HILOGE("%{public}s events save callback", LOG_TAG); + SaveCallback(eventType, onHandlerRef, isOnce); + return true; + } + if (!IsNoExistCallback(events[eventType], handler, eventType)) { + FI_HILOGE("%{public}s Callback already exists", LOG_TAG); + return false; + } + SaveCallback(eventType, onHandlerRef, isOnce); + return true; +} + +bool AniBoomerangEvent::IsNoExistCallback(std::list>, + ani_ref handler, int32_t eventType) +{ + CALL_DEBUG_ENTER; + for (const auto &item : events_[eventType]) { + ani_boolean isEqual = false; + auto isDuplicate = taihe::get_env()->Reference_StrictEquals(handler, item->onHandlerRef, &isEqual); + if (isDuplicate != ANI_OK) { + taihe::get_env()->GlobalReference_Delete(handler); + FI_HILOGD("%{public}s callback already registered", LOG_TAG); + return true; + } + } + return false; +} + +void AniBoomerangEvent::SaveCallback(int32_t eventType, ani_ref onHandlerRef, bool isOnce) +{ + auto listener = std::make_shared(); + listener->onHandlerRef = onHandlerRef; + if (isOnce) { + eventOnces_[eventType].push_back(listener); + } else { + events_[eventType].push_back(listener); + } + FI_HILOGD("%{public}s Add handler to list %{public}d", LOG_TAG, eventType); +} + +bool AniBoomerangEvent::Off(int32_t eventType) +{ + FI_HILOGD("%{public}s Unregister handler of event(%{public}d)", LOG_TAG, eventType); + std::lock_guard guard(mutex_); + return RemoveAllCallback(eventType); +} + +bool AniBoomerangEvent::OffOnce(int32_t eventType, ani_ref handler) +{ + FI_HILOGD("%{public}s AniBoomerangEvent OffOnce in for event:%{public}d", LOG_TAG, eventType); + auto iter = eventOnces_.find(eventType); + if (iter == eventOnces_.end()) { + FI_HILOGE("%{public}s eventType %{public}d not found", LOG_TAG, eventType); + return false; + } + for (const auto &listener : eventOnces_[eventType]) { + ani_boolean is_equal = false; + if (ANI_OK == taihe::get_env()->Reference_StrictEquals(handler, listener->onHandlerRef, &is_equal) && is_equal) { + eventOnces_[eventType].remove(listener); + break; + } + } + return events_[eventType].empty(); +} + +bool AniBoomerangEvent::RemoveAllCallback(int32_t eventType) +{ + CALL_DEBUG_ENTER; + auto iter = events_.find(eventType); + if (iter == events_.end()) { + FI_HILOGE("%{public}s evenType %{public}d not found", LOG_TAG, eventType); + return false; + } + for (auto& listener : events_[eventType]) { + listener->onHandlerRef = nullptr; + } + events_.erase(eventType); + return true; +} + +void AniBoomerangEvent::OnEvent(int32_t eventType, int32_t value, bool isOnce) +{ + CALL_DEBUG_ENTER; + FI_HILOGD("%{public}s OnEvent for %{public}d, isOnce:%{public}d", LOG_TAG, eventType, isOnce); + std::map>>::iterator typeHandler; + if (isOnce) { + typeHandler = eventOnces_.find(eventType); + if (typeHandler == eventOnces_.end()) { + FI_HILOGE("%{public}s OnEvent eventType %{public}d not found", LOG_TAG, eventType); + return; + } + } else { + typeHandler = events_.find(eventType); + if (typeHandler == events_.end()) { + FI_HILOGE("%{public}s OnEvent eventType %{public}d not found", LOG_TAG, eventType); + return; + } + } + FI_HILOGD("%{public}s %{public}zu callbacks of eventType %{public}d are sent", LOG_TAG, + typeHandler->second.size(), eventType); + for (auto handler : typeHandler->second) { + BoomerangData data = { + .type = static_cast(eventType), + .status = static_cast(value) + }; + data_.push_back(data); + } +} + +void AniBoomerangEvent::ClearEventMap() +{ + for (auto &iter : events_) { + iter.second.clear(); + } + for (auto &iter : eventOnces_) { + iter.second.clear(); + } + events_.clear(); + eventOnces_.clear(); +} + +} // namespace DeviceStatus +} // namespace Msdp +} // namespace OHOS diff --git a/frameworks/ets/metadataBinding/src/ani_boomerang_manager.cpp b/frameworks/ets/metadataBinding/src/ani_boomerang_manager.cpp new file mode 100644 index 000000000..e3e3e6aa8 --- /dev/null +++ b/frameworks/ets/metadataBinding/src/ani_boomerang_manager.cpp @@ -0,0 +1,443 @@ +/* + * Copyright (c) 2023 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 "ani_boomerang_manager.h" + +#undef LOG_TAG +#define LOG_TAG "ohos.multimodalAwareness.metadataBinding" + +namespace OHOS { +namespace Msdp { +namespace DeviceStatus { + +#define BOOMERANG_ALGO_SO_PATH "system/lib64/libmsdp_boomerang_algo.z.so" + +std::map> callbacks_; + +static constexpr size_t MSDP_PATH_MAX = 4096; + +bool AniBoomerangCallback::init(uintptr_t opq) +{ + CALL_DEBUG_ENTER; + env_ = taihe::get_env(); + if (env_ == nullptr) { + FI_HILOGE("%{public}s ANI Get env is nullptr", LOG_TAG); + return false; + } + ani_status status = ANI_OK; + if (ANI_OK != env_->GetVM(&vm_)) { + FI_HILOGE("env GetVM faild"); + return false; + } + if (opq != 0) { + FI_HILOGD("%{public}s beign init callback", LOG_TAG); + funObject_ = reinterpret_cast(opq); + if ((status= env_->GlobalReference_Create(funObject_, &ref_)) != ANI_OK) { + FI_HILOGE("%{public}s create callback object failed, status = %{public}d", LOG_TAG, status); + ref_ = nullptr; + return false; + } + } else { + if ((status = env_->Promise_New(&deferred_, &promise_)) != ANI_OK) { + FI_HILOGE("%{public}s create promise object failed, status = %{public}d", LOG_TAG, status); + return false; + } + } + return true; +} + +void AniBoomerangCallback::OnScreenshotResult(const DeviceStatus::BoomerangData& screentshotData) +{ + std::lock_guard guard(mutex_); + data_ = screentshotData; + AniBoomerang::GetInstance()->OnScreenshot(data_.type, data_.status, false); +} + +void AniBoomerangCallback::OnNotifyMetadata(const std::string &metadata) +{ + CALL_DEBUG_ENTER; + std::lock_guard guard(mutex_); + this->metadata_ = metadata; + EmitOnMetadata(*env_, metadata); +} + +void AniBoomerangCallback::EmitOnMetadata(ani_env env, std::string metadata) +{ + AniBoomerang::GetInstance()->setDeferred(metadata); +} + +AniBoomerang::AniBoomerang() : AniBoomerangEvent() +{ + env_ = taihe::get_env(); + ref_ = nullptr; + DeviceStatusClient::GetInstance().RegisterDeathListener([this] { + FI_HILOGI("%{public}s Receive death notification", LOG_TAG); + callbacks_.clear(); + ClearEventMap(); + }); +} + +AniBoomerang::~AniBoomerang() +{ + if (ref_ != nullptr) { + env_->GlobalReference_Delete(ref_); + } + env_ = nullptr; +} + +std::shared_ptr AniBoomerang::GetInstance() +{ + static std::once_flag flag; + static std::shared_ptr instance_; + + std::call_once(flag, []() { + instance_ = std::make_shared(); + }); + return instance_; +} + +void AniBoomerang::onMetadata(std::string bundleName, ::taihe::callback_view handle, uintptr_t opq) +{ + if (bundleName.empty()) { + FI_HILOGE("%{public}s Failed to get arguments", LOG_TAG); + return; + } + std::lock_guard lock(mutex_); + ani_object callbackObj = reinterpret_cast(opq); + ani_ref callbackRef; + if (env_ == nullptr || ANI_OK != env_->GlobalReference_Create(callbackObj, &callbackRef)) { + FI_HILOGE("%{public}s ani_env is nullptr or GlobalReference_Create failed", LOG_TAG); + return; + } + if (!AniBoomerang::GetInstance()->On(BoomerangType::BOOMERANG_TYPE_BOOMERANG, callbackRef, false)) { + FI_HILOGE("%{public}s type:%{public}d already exists", LOG_TAG, BoomerangType::BOOMERANG_TYPE_BOOMERANG); + return; + } + if (callbacks_.find(BoomerangType::BOOMERANG_TYPE_BOOMERANG) != callbacks_.end()) { + FI_HILOGE("%{public}s key:%{public}d Callback exists", LOG_TAG, BoomerangType::BOOMERANG_TYPE_BOOMERANG); + return; + } + sptr callback = new (std::nothrow) AniBoomerangCallback(); + if (nullptr == callback) { + FI_HILOGE("%{public}s callback is nullptr", LOG_TAG); + taihe::set_business_error(COMMON_PARAMETER_ERROR, "callback is nullptr"); + return; + } + if (!callback->init(opq)) { + FI_HILOGE("%{public}s AniBoomerangCallback init fail", LOG_TAG); + taihe::set_business_error(OTHER_ERROR, "AniBoomerangCallback init fail"); + return; + } + int32_t ret = ANI_BOOMERANG_MGR->SubscribeCallback( + static_cast(BoomerangType::BOOMERANG_TYPE_BOOMERANG), bundleName, callback); + if (ret != RET_OK) { + FI_HILOGE("%{public}s type:%{public}d return fail,err msg:%{public}s.", LOG_TAG, SUBSCRIBE_FAILED, + MetadataBindingLogInfo.at(SUBSCRIBE_FAILED).c_str()); + taihe::set_business_error(SUBSCRIBE_FAILED, MetadataBindingLogInfo.at(SUBSCRIBE_FAILED)); + } + callbacks_.insert(std::pair>(BoomerangType::BOOMERANG_TYPE_BOOMERANG, callback)); +} + +void AniBoomerang::offMetadata(std::string bundleName, ::taihe::optional_view opq) +{ + FI_HILOGD("%{public}s unRegisterListener enter", LOG_TAG); + std::lock_guard lock(mutex_); + if (!opq.has_value()) { + FI_HILOGD("%{public}s opq is nullptr!", LOG_TAG); + return; + } + if (!AniBoomerang::GetInstance()->Off(BoomerangType::BOOMERANG_TYPE_BOOMERANG)) { + FI_HILOGE("%{public}s Not ready to unsubscribe for type:%{public}d", LOG_TAG, BoomerangType::BOOMERANG_TYPE_BOOMERANG); + return; + } + auto item = callbacks_.find(BoomerangType::BOOMERANG_TYPE_BOOMERANG); + if (item == callbacks_.end()) { + FI_HILOGE("%{public}s No existed callbacks_", LOG_TAG); + return; + } + int32_t ret = ANI_BOOMERANG_MGR->UnsubscribeCallback( + static_cast(BoomerangType::BOOMERANG_TYPE_BOOMERANG), bundleName, item->second); + if (ret != RET_OK) { + FI_HILOGE("%{public}s type:%{public}d return fail,err msg:%{public}s.", LOG_TAG, UNSUBSCRIBE_FAILED, + MetadataBindingLogInfo.at(UNSUBSCRIBE_FAILED).c_str()); + taihe::set_business_error(UNSUBSCRIBE_FAILED, MetadataBindingLogInfo.at(UNSUBSCRIBE_FAILED)); + } + callbacks_.erase(BoomerangType::BOOMERANG_TYPE_BOOMERANG); +} + +void AniBoomerang::notifyMetadataBindingEvent(std::string bundleName, ani_object& promise) +{ + FI_HILOGD("%{public}s notifyMetadataBindingEventPromise enter", LOG_TAG); + std::lock_guard lock(mutex_); + OHOS::sptr callback = new (std::nothrow) AniBoomerangCallback(); + if (nullptr == callback) { + FI_HILOGE("%{public}s callback is nullptr", LOG_TAG); + taihe::set_business_error(COMMON_PARAMETER_ERROR, "callback is nullptr"); + return; + } + if (!callback->init()) { + FI_HILOGE("%{public}s AniBoomerangCallback init fail", LOG_TAG); + taihe::set_business_error(OTHER_ERROR, "AniBoomerangCallback init fail"); + return; + } + promise = callback->promise_; + int32_t ret = ANI_BOOMERANG_MGR->NotifyMetadataBindingEvent(bundleName, callback); + if (ret != RET_OK) { + FI_HILOGE("%{public}s type:%{public}d return fail,err msg:%{public}s.", LOG_TAG, HANDLER_FAILD, + MetadataBindingLogInfo.at(HANDLER_FAILD).c_str()); + taihe::set_business_error(HANDLER_FAILD, MetadataBindingLogInfo.at(HANDLER_FAILD)); + } +} + +void AniBoomerang::submitMetadata(std::string metadata) +{ + FI_HILOGD("%{public}s submitMetadataPromise enter", LOG_TAG); + std::lock_guard lock(mutex_); + int32_t ret = ANI_BOOMERANG_MGR->SubmitMetadata(metadata); + if (ret != RET_OK) { + FI_HILOGE("%{public}s type:%{public}d return fail,err msg:Internal handling failed. File creation failed.", + LOG_TAG, HANDLER_FAILD); + taihe::set_business_error(HANDLER_FAILD, "Internal handling failed. File creation failed."); + } +} + +void AniBoomerang::encodeImage(uintptr_t srcImage, std::string metadata, ani_object& promise) +{ + FI_HILOGD("%{public}s encodeImagePromise enter", LOG_TAG); + std::lock_guard lock(mutex_); + OHOS::sptr callback = new (std::nothrow) AniBoomerangCallback(); + if (nullptr == callback) { + FI_HILOGE("%{public}s callback is nullptr", LOG_TAG); + taihe::set_business_error(COMMON_PARAMETER_ERROR, "callback is nullptr"); + return; + } + if (!callback->init()) { + FI_HILOGE("%{public}s AniBoomerangCallback init fail", LOG_TAG); + taihe::set_business_error(OTHER_ERROR, "AniBoomerangCallback init fail"); + return; + } + promise = callback->promise_; + ani_object object = reinterpret_cast(srcImage); + std::shared_ptr pixelMap = OHOS::Media::PixelMapTaiheAni::GetNativePixelMap(env_, object); + int32_t ret = ANI_BOOMERANG_MGR->BoomerangEncodeImage(pixelMap, metadata, callback); + if (ret != RET_OK) { + FI_HILOGE("%{public}s type:%{public}d return fail,err msg:%{public}s.", LOG_TAG, ENCODE_FAILED, + MetadataBindingLogInfo.at(ENCODE_FAILED).c_str()); + taihe::set_business_error(ENCODE_FAILED, MetadataBindingLogInfo.at(ENCODE_FAILED)); + } +} + +void AniBoomerang::decodeImage(uintptr_t encodedImage, ani_object& promise) +{ + std::lock_guard lock(mutex_); + ani_object object = reinterpret_cast(encodedImage); + std::shared_ptr pixelMap = OHOS::Media::PixelMapTaiheAni::GetNativePixelMap(env_, object); + OHOS::sptr callback = new (std::nothrow) AniBoomerangCallback(); + if (nullptr == callback) { + FI_HILOGE("%{public}s callback is nullptr", LOG_TAG); + taihe::set_business_error(COMMON_PARAMETER_ERROR, "callback is nullptr"); + return; + } + if (!callback->init()) { + FI_HILOGE("%{public}s AniBoomerangCallback init fail", LOG_TAG); + taihe::set_business_error(OTHER_ERROR, "AniBoomerangCallback init fail"); + return; + } + promise = callback->promise_; + std::string content; + DecodeImageFunc(pixelMap, content); + int32_t ret = ANI_BOOMERANG_MGR->BoomerangDecodeImage(pixelMap, callback); + if (ret != RET_OK) { + FI_HILOGE("%{public}s type:%{public}d return fail,err msg:%{public}s.", LOG_TAG, DECODE_FAILED, + MetadataBindingLogInfo.at(DECODE_FAILED).c_str()); + taihe::set_business_error(DECODE_FAILED, MetadataBindingLogInfo.at(DECODE_FAILED)); + } +} + +bool AniBoomerang::EncodeImageFunc(std::shared_ptr &pixelMap, const std::string &content, + std::shared_ptr &resultPixelMap) +{ + char realPath[MSDP_PATH_MAX] = {}; + if (realpath(BOOMERANG_ALGO_SO_PATH, realPath) == nullptr) { + FI_HILOGE("%{public}s %{public}s Path is error", LOG_TAG, realPath); + return false; + } + void *handle = dlopen(realPath, RTLD_LAZY); + char *error = nullptr; + if (((error = dlerror()) != nullptr) || (handle == nullptr)) { + FI_HILOGE("%{public}s Boomerang Algo Encode Load failed, error: %{public}s", LOG_TAG, error); + return false; + } + EncodeImagePtr encodeImage = reinterpret_cast(dlsym(handle, "EncodeImage")); + if ((error = dlerror()) != nullptr || encodeImage == nullptr) { + FI_HILOGE("%{public}s Boomerang Algo Encode find symbol failed, error: %{public}s", LOG_TAG, error); + dlclose(handle); + return false; + } + encodeImage(pixelMap, content, resultPixelMap); + dlclose(handle); + FI_HILOGD("%{public}s Boomerang Algo Encode success", LOG_TAG); + return true; +} + +bool AniBoomerang::DecodeImageFunc(std::shared_ptr &pixelMap, std::string &content) +{ + char realPath[MSDP_PATH_MAX] = {}; + if (realpath(BOOMERANG_ALGO_SO_PATH, realPath) == nullptr) { + FI_HILOGE("%{public}s %{public}s Path is error", LOG_TAG, realPath); + return false; + } + void *handle = dlopen(realPath, RTLD_LAZY); + char *error = nullptr; + if (((error = dlerror()) != nullptr) || (handle == nullptr)) { + FI_HILOGE("%{public}s Boomerang Algo Decode Load failed, error: %{public}s", LOG_TAG, error); + return false; + } + DecodeImagePtr decodeImageFunc = reinterpret_cast(dlsym(handle, "DecodeImage")); + if (((error = dlerror()) != nullptr) || (decodeImageFunc == nullptr)) { + dlclose(handle); + FI_HILOGE("%{public}s Boomerang Algo Decode find symbol failed, error: %{public}s", LOG_TAG, error); + return false; + } + decodeImageFunc(pixelMap, content); + dlclose(handle); + FI_HILOGD("%{public}s Boomerang Algo Decode success", LOG_TAG); + return true; +} + +void AniBoomerang::setDeferred(std::string data) +{ + this->metadata_ = data; +} + +void AniBoomerang::OnScreenshot(int32_t type, int32_t status, bool isOnce) +{ + OnEvent(type, status, isOnce); +} +#if 0 +void MetadataBindingCommon::ExecAsyncCallbackPromise(ani_env *env, ani_resolver deferred, ani_ref data, ani_ref businessError) +{ + CALL_DEBUG_ENTER; + if (nullptr == env) { + FI_HILOGE("%{public}s env is null", LOG_TAG); + return; + } + if (nullptr == deferred) { + FI_HILOGE("%{public}s deferred is null", LOG_TAG); + return; + } + ani_status status = ANI_OK; + if (businessError != nullptr) { + if ((status = env->PromiseResolver_Reject(deferred, static_cast(businessError))) != ANI_OK) { + FI_HILOGE("%{public}s promise reject failed, status = %{public}d", LOG_TAG, status); + } + return; + } + if (nullptr == data) { + if ((status = env->GetUndefined(&data)) != ANI_OK) { + FI_HILOGE("%{public}s get undefined value failed, status = %{public}d", LOG_TAG, status); + return; + } + } + if ((status = env->PromiseResolver_Resolve(deferred, data)) != ANI_OK) { + FI_HILOGE("%{public}s promiseResolver resolve failed, status = %{public}d", LOG_TAG, status); + return; + } + return; +} + +ani_ref MetadataBindingCommon::CreateBusinessError(ani_env* env, ani_int code, const std::string& msg) +{ + ani_class cls; + ani_status status = ANI_OK; + if ((status = env->FindClass("L@ohos/base/BusinessError;", &cls)) != ANI_OK) { + FI_HILOGE("%{public}s BusinessError FindClass fail, status:%{public}d", LOG_TAG, status); + return nullptr; + } + ani_method ctor; + if ((status = env->Class_FindMethod(cls, "", "DLescompat/Error;:V", &ctor)) != ANI_OK) { + FI_HILOGE("%{public}s Class_FindMethod fail, status:%{public}d", LOG_TAG, status); + return nullptr; + } + ani_object error = MetadataBindingCommon::WrapBusinessError(env, msg); + if (error == nullptr) { + FI_HILOGE("%{public}s WrapBusinessError fail env is null", LOG_TAG); + return nullptr; + } + ani_object obj = nullptr; + ani_double dCode(code); + if ((status = env->Object_New(cls, ctor, &obj, dCode, error)) != ANI_OK) { + FI_HILOGE("%{public}s Object_New fail, status:%{public}d", LOG_TAG, status); + return nullptr; + } + return reinterpret_cast(obj); +} + +ani_object MetadataBindingCommon::WrapBusinessError(ani_env* env, const std::string& msg) +{ + ani_class cls {}; + ani_method method {}; + ani_object obj = nullptr; + ani_status status = ANI_ERROR; + if (env == nullptr) { + FI_HILOGE("%{public}s env is null", LOG_TAG); + return nullptr; + } + + ani_string aniMsg = nullptr; + if ((status = env->String_NewUTF8(msg.c_str(), msg.size(), &aniMsg)) != ANI_OK) { + FI_HILOGE("%{public}s String_NewUTF8 fail, status:%{public}d", LOG_TAG, status); + return nullptr; + } + + ani_ref undefRef; + if ((status = env->GetUndefined(&undefRef)) != ANI_OK) { + FI_HILOGE("%{public}s GetUndefined fail, status:%{public}d", LOG_TAG, status); + return nullptr; + } + + if ((status = env->FindClass("Lescompat/Error;", &cls)) != ANI_OK) { + FI_HILOGE("%{public}s Lescompat/Error find class fail, status:%{public}d", LOG_TAG, status); + return nullptr; + } + status = env->Class_FindMethod(cls, "", "Lstd/core/String;Lescompat/ErrorOptions;:V", &method); + if (status != ANI_OK) { + FI_HILOGE("%{public}s ErrorOptions Class_FindMethod is fail, status:%{public}d", LOG_TAG, status); + return nullptr; + } + + if ((status = env->Object_New(cls, method, &obj, aniMsg, undefRef)) != ANI_OK) { + FI_HILOGE("%{public}s Object_New fail, status:%{public}d", LOG_TAG, status); + return nullptr; + } + return obj; +} + +ani_status MetadataBindingCommon::GetAniEnv(ani_vm* vm, ani_env** env) +{ + CALL_DEBUG_ENTER; + if (nullptr == vm) { + FI_HILOGE("%{public}s vm is null", LOG_TAG); + return ANI_ERROR; + } + ani_options aniOpt {0, nullptr}; + auto status = vm->AttachCurrentThread(&aniOpt, ANI_VERSION_1, env); + return status; +} +#endif +} // namespace DeviceStatus +} // namespace Msdp +} // namespace OHOS +// #endif // JS_COOPERATE_MANAGER_H \ No newline at end of file diff --git a/frameworks/ets/metadataBinding/src/ani_constructor.cpp b/frameworks/ets/metadataBinding/src/ani_constructor.cpp new file mode 100644 index 000000000..077426d18 --- /dev/null +++ b/frameworks/ets/metadataBinding/src/ani_constructor.cpp @@ -0,0 +1,21 @@ +#include "taihe.platform.ani.ani.hpp" +#include "ohos.multimodalAwareness.metadataBinding.ani.hpp" +#if __has_include() +#include +#elif __has_include() +#include +#else +#error "ani.h not found. Please ensure the Ani SDK is correctly installed." +#endif +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) { + ani_env *env; + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + return ANI_ERROR; + } + if (ANI_OK != ohos::multimodalAwareness::metadataBinding::ANIRegister(env)) { + std::cerr << "Error from ohos::multimodalAwareness::metadataBinding::ANIRegister" << std::endl; + return ANI_ERROR; + } + *result = ANI_VERSION_1; + return ANI_OK; +} \ No newline at end of file diff --git a/frameworks/ets/metadataBinding/src/ohos.multimodalAwareness.metadataBinding.impl.cpp b/frameworks/ets/metadataBinding/src/ohos.multimodalAwareness.metadataBinding.impl.cpp new file mode 100644 index 000000000..50a84fa0f --- /dev/null +++ b/frameworks/ets/metadataBinding/src/ohos.multimodalAwareness.metadataBinding.impl.cpp @@ -0,0 +1,55 @@ +#include "ani_boomerang_manager.h" + +#undef LOG_TAG +#define LOG_TAG "ohos.multimodalAwareness.metadataBinding" + +namespace { +using namespace ::taihe; +using namespace OHOS::Msdp::DeviceStatus; +void onMetadata(::taihe::string_view bundleName, ::taihe::callback_view callbck, uintptr_t opq) +{ + AniBoomerang::GetInstance()->onMetadata(std::string(bundleName), callbck, opq); +} + +void offMetadata(::taihe::string_view bundleName, ::taihe::optional_view opq) +{ + AniBoomerang::GetInstance()->offMetadata(std::string(bundleName), opq); +} + +uintptr_t notifyMetadataBindingEventPromise(::taihe::string_view bundleName) +{ + ani_object promise; + AniBoomerang::GetInstance()->notifyMetadataBindingEvent(std::string(bundleName), promise); + return reinterpret_cast(promise); +} + +void submitMetadata(::taihe::string_view metadata) +{ + AniBoomerang::GetInstance()->submitMetadata(std::string(metadata)); +} + +uintptr_t encodeImagePromise(uintptr_t srcImage, ::taihe::string_view metadata) +{ + ani_object promise; + AniBoomerang::GetInstance()->encodeImage(srcImage, std::string(metadata), promise); + return reinterpret_cast(promise); +} + +uintptr_t decodeImagePromise(uintptr_t encodedImage) +{ + ani_object promise; + AniBoomerang::GetInstance()->decodeImage(encodedImage, promise); + return reinterpret_cast(promise); +} + +} // namespace + +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_onMetadata(onMetadata); +TH_EXPORT_CPP_API_offMetadata(offMetadata); +TH_EXPORT_CPP_API_submitMetadata(submitMetadata); +TH_EXPORT_CPP_API_notifyMetadataBindingEventPromise(notifyMetadataBindingEventPromise); +TH_EXPORT_CPP_API_encodeImagePromise(encodeImagePromise); +TH_EXPORT_CPP_API_decodeImagePromise(decodeImagePromise); +// NOLINTEND \ No newline at end of file diff --git a/frameworks/ets/metadataBinding/test/test_main.ets b/frameworks/ets/metadataBinding/test/test_main.ets new file mode 100644 index 000000000..b6e100aab --- /dev/null +++ b/frameworks/ets/metadataBinding/test/test_main.ets @@ -0,0 +1,102 @@ +import metadataBinding from '@ohos.multimodalAwareness.metadataBinding'; +import { BusinessError, AsyncCallback} from '@ohos.base'; +import image from '@ohos.multimedia.image'; + +const Tag:String = "metadataBinding" + +function test_onMetadata() { + let fun_name: string = 'test_onMetadata'; + console.log(Tag, `into func ${fun_name}`); + + let bundleName: string = ''; + try { + metadataBinding.on('operationSubmitMetadata', bundleName, (event: number) =>{ + if (event == 1) { + console.info("The screenshot request is intercepted and the app link is obtained"); + } + }); + } catch (err) { + console.error(Tag, `${fun_name} catch ${err}`); + } + console.log(Tag, `end func ${fun_name}`); +} + +function test_offMetadata() { + let fun_name: string = 'test_offMetadata'; + console.log(Tag, `into func ${fun_name}`); + + let bundleName: string = ''; + try { + metadataBinding.off('operationSubmitMetadata', bundleName, (evnet: number)=>{}); + } catch (err) { + console.error(Tag, `${fun_name} catch ${err}`); + } + console.log(Tag, `end func ${fun_name}`); +} + +function test_notifyMetadataBindingEvent() { + let fun_name: string = 'test_notifyMetadataBindingEvent'; + console.log(Tag, `into func ${fun_name}`); + let metadata:string = ''; + metadataBinding.notifyMetadataBindingEvent(metadata).catch((err)=>{ + console.error(Tag, `${fun_name} catch ${err}`); + }); + console.log(Tag, `end func ${fun_name}`); +} + +function test_submitMetadata() { + let fun_name: string = 'test_submitMetadata'; + console.log(Tag, `into func ${fun_name}`); + + let metadata: string = ""; + try { + metadataBinding.submitMetadata(metadata); + } catch (err) { + console.error(Tag, `${fun_name} catch ${err}`); + } + console.log(Tag, `end func ${fun_name}`); +} + +function test_encodeImage() { + let fun_name: string = 'test_encodeImage'; + console.log(Tag, `into func ${fun_name}`); + let captureImage: image.PixelMap | undefined = undefined; + let metadata: string = ""; + let srcImage: image.PixelMap | undefined = undefined; + metadataBinding.encodeImage(srcImage, metadata).then((pixelMap: image.PixelMap) =>{ + captureImage = pixelMap; + }).catch((err)=>{ + console.error(Tag, `${fun_name} catch ${err}`); + }); + console.log(Tag, `end func ${fun_name}`); +} + +function test_decodeImage() { + let fun_name: string = 'test_decodeImage'; + console.log(Tag, `into func ${fun_name}`); + + let encodeImage: image.PixelMap | undefined = undefined; + let captrueMetadata: string = ""; + metadataBinding.decodeImage(encodeImage).then((metadata: string) =>{ + captrueMetadata = metadata; + }).catch((err)=>{ + console.error(Tag, `${fun_name} catch ${err}`); + }); + console.log(Tag, `end func ${fun_name}`); +} + +function main() { + console.println(Tag + ` into main`); + test_onMetadata(); + console.println(Tag + ` **********************************`); + test_offMetadata(); + console.println(Tag + ` **********************************`); + test_notifyMetadataBindingEvent(); + console.println(Tag + ` **********************************`); + test_submitMetadata(); + console.println(Tag + ` **********************************`); + test_encodeImage(); + console.println(Tag + ` **********************************`); + test_decodeImage(); + console.println(Tag + ` out main`); +} \ No newline at end of file -- Gitee From 237f2b9d61bde46d5f4f6021172a16cd4cbab48c Mon Sep 17 00:00:00 2001 From: KangPeng Date: Fri, 12 Sep 2025 17:37:49 +0800 Subject: [PATCH 2/4] msdp taihe 1.2 test 2 Signed-off-by: KangPeng --- bundle.json | 4 +-- frameworks/ets/drag/BUILD.gn | 7 ++++ .../ohos.deviceStatus.dragInteraction.taihe | 4 ++- .../ohos.deviceStatus.dragInteraction.impl.h | 2 ++ ...ohos.deviceStatus.dragInteraction.impl.cpp | 26 ++++++++++++++ frameworks/ets/drag/test/test_main.ets | 34 +++++++++++++++++++ 6 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 frameworks/ets/drag/test/test_main.ets diff --git a/bundle.json b/bundle.json index bf17818b9..c0a24c913 100644 --- a/bundle.json +++ b/bundle.json @@ -100,8 +100,8 @@ "//base/msdp/device_status/frameworks/js/napi/boomerang:metadatabinding_napi", "//base/msdp/device_status/frameworks/js/napi/device_status:devicestatus_napi", "//base/msdp/device_status/frameworks/js/napi/underage_model:userstatus_napi", - "//base/msdp/device_status/frameworks/ets/drag:dragInteraction"£¬ - "//base/msdp/device_status/frameworks/ets/metadataBinding:metadataBinding" + "//base/msdp/device_status/frameworks/ets/drag:dragInteraction", + "//base/msdp/device_status/frameworks/ets/metadataBinding:metadataBinding" ], "service_group":[ "//base/msdp/device_status/libs:devicestatus_algo", diff --git a/frameworks/ets/drag/BUILD.gn b/frameworks/ets/drag/BUILD.gn index b76c36209..8548e0d2d 100644 --- a/frameworks/ets/drag/BUILD.gn +++ b/frameworks/ets/drag/BUILD.gn @@ -78,9 +78,16 @@ ohos_prebuilt_etc("drag_etc") { subsystem_name = "$subsystem_name" deps = [ ":drag_abc" ] } +generate_static_abc("drag_taihe_test") { + base_url = "${device_status_frameworks_path}/ets/drag" + files = [ "$base_url/test/test_main.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/drag_taihe_test.abc" +} group("dragInteraction") { deps = [ ":drag_etc", ":DragInteraction", + ":drag_taihe_test", ] } \ No newline at end of file diff --git a/frameworks/ets/drag/idl/ohos.deviceStatus.dragInteraction.taihe b/frameworks/ets/drag/idl/ohos.deviceStatus.dragInteraction.taihe index dbd4e6cca..cd8e4351b 100644 --- a/frameworks/ets/drag/idl/ohos.deviceStatus.dragInteraction.taihe +++ b/frameworks/ets/drag/idl/ohos.deviceStatus.dragInteraction.taihe @@ -42,4 +42,6 @@ struct Summary { """) function registerListener(f: (info: DragState) => void, opq: Opaque); function unRegisterListener(opq: Optional); -function getDataSummary(): Array; \ No newline at end of file +function getDataSummary(): Array; +function setDragSwitchState(enabled: bool): void; +function setAppDragSwitchState(enabled: bool, bundleName: String): void; \ No newline at end of file diff --git a/frameworks/ets/drag/include/ohos.deviceStatus.dragInteraction.impl.h b/frameworks/ets/drag/include/ohos.deviceStatus.dragInteraction.impl.h index 8ef41ee56..fa9741ba0 100644 --- a/frameworks/ets/drag/include/ohos.deviceStatus.dragInteraction.impl.h +++ b/frameworks/ets/drag/include/ohos.deviceStatus.dragInteraction.impl.h @@ -60,6 +60,8 @@ public: void unRegisterListener(optional_view opq); void OnDragMessage(DeviceStatus::DragState state) override; array getDataSummary(); + void setDragSwitchState(bool enabled); + void setAppDragSwitchState(bool enabled, ::taihe::string_view bundleName); static std::shared_ptr GetInstance(); diff --git a/frameworks/ets/drag/src/ohos.deviceStatus.dragInteraction.impl.cpp b/frameworks/ets/drag/src/ohos.deviceStatus.dragInteraction.impl.cpp index b32114fa0..38fb3551a 100644 --- a/frameworks/ets/drag/src/ohos.deviceStatus.dragInteraction.impl.cpp +++ b/frameworks/ets/drag/src/ohos.deviceStatus.dragInteraction.impl.cpp @@ -19,6 +19,7 @@ #define LOG_TAG "ohos.deviceStatus.dragInteraction" namespace { +static constexpr size_t MAX_PKG_NAME_LEN = 128; static DragState ConverDragState(DeviceStatus::DragState state) { switch (state) { @@ -159,6 +160,21 @@ array EtsDragManager::getDataSummary() return array(arr); } +void EtsDragManager::setDragSwitchState(bool enabled) { + INTERACTION_MGR->SetDragSwitchState(enabled, true); +} + +void EtsDragManager::setAppDragSwitchState(bool enabled, ::taihe::string_view bundleName) { + TH_THROW(std::runtime_error, "setAppDragSwitchState not implemented"); + std::string pkgName(bundleName); + size_t length = pkgName.length(); + if (length <= 0 || length > MAX_PKG_NAME_LEN) { + FI_HILOGE("Invalid pkgName length:%{public}zu", length); + return; + } + INTERACTION_MGR->SetAppDragSwitchState(enabled, pkgName, true); +} + void registerListener(callback_view f, uintptr_t opq) { return EtsDragManager::GetInstance()->registerListener(f, opq); @@ -173,6 +189,14 @@ array getDataSummary() { return EtsDragManager::GetInstance()->getDataSummary(); } + +void setDragSwitchState(bool enabled) { + EtsDragManager::GetInstance()->setDragSwitchState(enabled); +} + +void setAppDragSwitchState(bool enabled, ::taihe::string_view bundleName) { + EtsDragManager::GetInstance()->setAppDragSwitchState(enabled, bundleName); +} } // namespace // Since these macros are auto-generate, lint will cause false positive. @@ -180,4 +204,6 @@ array getDataSummary() TH_EXPORT_CPP_API_registerListener(registerListener); TH_EXPORT_CPP_API_unRegisterListener(unRegisterListener); TH_EXPORT_CPP_API_getDataSummary(getDataSummary); +TH_EXPORT_CPP_API_setDragSwitchState(setDragSwitchState); +TH_EXPORT_CPP_API_setAppDragSwitchState(setAppDragSwitchState); // NOLINTEND \ No newline at end of file diff --git a/frameworks/ets/drag/test/test_main.ets b/frameworks/ets/drag/test/test_main.ets new file mode 100644 index 000000000..f520b5dc7 --- /dev/null +++ b/frameworks/ets/drag/test/test_main.ets @@ -0,0 +1,34 @@ +import dragInteraction from '@ohos.deviceStatus.dragInteraction'; +import { BusinessError, AsyncCallback} from '@ohos.base'; + +const Tag:String = "dragInteraction" + +function test_setDragSwitchState() { + let fun_name: string = 'test_setDragSwitchState'; + console.log(Tag, `into func ${fun_name}`); + try { + dragInteraction.setDragSwitchState(false); + } catch (err) { + console.error(Tag, `${fun_name} catch ${err}`); + } + console.log(Tag, `end func ${fun_name}`); +} + +function test_setAppDragSwitchState() { + let fun_name: string = 'test_setAppDragSwitchState'; + console.log(Tag, `into func ${fun_name}`); + try { + dragInteraction.setAppDragSwitchState(true, "com.app.bundleName"); + } catch (err) { + console.error(Tag, `${fun_name} catch ${err}`); + } + console.log(Tag, `end func ${fun_name}`); +} + +function main() { + console.println(Tag + ` into main`); + test_setDragSwitchState(); + console.println(Tag + ` **********************************`); + test_setAppDragSwitchState(); + console.println(Tag + ` out main`); +} \ No newline at end of file -- Gitee From f7ace8274b171247a7e617132da5f3ee2c9cf3da Mon Sep 17 00:00:00 2001 From: KangPeng Date: Sat, 13 Sep 2025 08:10:23 +0000 Subject: [PATCH 3/4] update frameworks/ets/metadataBinding/test/test_main.ets. Signed-off-by: KangPeng --- frameworks/ets/metadataBinding/test/test_main.ets | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/frameworks/ets/metadataBinding/test/test_main.ets b/frameworks/ets/metadataBinding/test/test_main.ets index b6e100aab..ed2e53278 100644 --- a/frameworks/ets/metadataBinding/test/test_main.ets +++ b/frameworks/ets/metadataBinding/test/test_main.ets @@ -1,6 +1,7 @@ import metadataBinding from '@ohos.multimodalAwareness.metadataBinding'; import { BusinessError, AsyncCallback} from '@ohos.base'; import image from '@ohos.multimedia.image'; +import rpc from "@ohos.rpc"; const Tag:String = "metadataBinding" @@ -62,7 +63,8 @@ function test_encodeImage() { console.log(Tag, `into func ${fun_name}`); let captureImage: image.PixelMap | undefined = undefined; let metadata: string = ""; - let srcImage: image.PixelMap | undefined = undefined; + let parcel:rpc.MessageSequence = new rpc.MessageSequence(); + let srcImage : image.PixelMap = image.createPixelMapFromParcel(parcel); metadataBinding.encodeImage(srcImage, metadata).then((pixelMap: image.PixelMap) =>{ captureImage = pixelMap; }).catch((err)=>{ @@ -75,7 +77,8 @@ function test_decodeImage() { let fun_name: string = 'test_decodeImage'; console.log(Tag, `into func ${fun_name}`); - let encodeImage: image.PixelMap | undefined = undefined; + let parcel:rpc.MessageSequence = new rpc.MessageSequence(); + let encodeImage : image.PixelMap = image.createPixelMapFromParcel(parcel); let captrueMetadata: string = ""; metadataBinding.decodeImage(encodeImage).then((metadata: string) =>{ captrueMetadata = metadata; -- Gitee From f7f6dc09397103ba9fbab59f4fc85f43661d5bf6 Mon Sep 17 00:00:00 2001 From: KangPeng Date: Sat, 13 Sep 2025 08:11:49 +0000 Subject: [PATCH 4/4] update frameworks/ets/metadataBinding/BUILD.gn. Signed-off-by: KangPeng --- frameworks/ets/metadataBinding/BUILD.gn | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/frameworks/ets/metadataBinding/BUILD.gn b/frameworks/ets/metadataBinding/BUILD.gn index fd361485e..598c51b83 100644 --- a/frameworks/ets/metadataBinding/BUILD.gn +++ b/frameworks/ets/metadataBinding/BUILD.gn @@ -42,7 +42,6 @@ taihe_shared_library("MetadataBinding") { debug = false } include_dirs = [ - #"../common", "include", "${device_status_utils_path}/include", "${device_status_root_path}/utils/common/include", @@ -57,14 +56,12 @@ taihe_shared_library("MetadataBinding") { "hilog:libhilog", "image_framework:image_native", "image_framework:image_taihe", - #"${device_status_interfaces_path}/innerkits:devicestatus_client", ] sources += [ "src/ani_constructor.cpp", "src/ani_boomerang.cpp", "src/ani_boomerang_manager.cpp", "src/ohos.multimodalAwareness.metadataBinding.impl.cpp", - #"${device_status_interfaces_path}/../intention/boomerang/client/src/boomerang_client.cpp" ] deps = [ ":run_taihe", @@ -100,6 +97,6 @@ group("metadataBinding") { deps = [ ":metadataBinding_etc", ":MetadataBinding", - ":metadataBinding_taihe_test", + #":metadataBinding_taihe_test", ] } \ No newline at end of file -- Gitee