From d50587cd2cc0365891acedc90716180aad9029e7 Mon Sep 17 00:00:00 2001 From: liuxiaoxiyumemng Date: Sat, 16 Aug 2025 09:21:59 +0000 Subject: [PATCH 1/2] =?UTF-8?q?photoeditor=E9=80=82=E9=85=8DarkTs1.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liuxiaoxiyumemng --- bundle.json | 1 + .../include/ets_photo_editor_extension.h | 63 ++++ .../ets_photo_editor_extension_context.h | 63 ++++ .../include/ets_photo_editor_extension_impl.h | 60 ++++ .../ets_photo_editor_extension_instance.h | 29 ++ .../src/ets_photo_editor_extension.cpp | 90 +++++ .../ets_photo_editor_extension_context.cpp | 322 ++++++++++++++++++ .../src/ets_photo_editor_extension_impl.cpp | 152 +++++++++ .../ets_photo_editor_extension_instance.cpp | 55 +++ ...pp.ability.PhotoEditorExtensionAbility.ets | 61 ++++ frameworks/ets/ets/BUILD.gn | 23 ++ .../PhotoEditorExtensionContext.ets | 100 ++++++ frameworks/native/ability/native/BUILD.gn | 91 +++++ .../photo_editor_extension.cpp | 3 + 14 files changed, 1113 insertions(+) create mode 100644 frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension.h create mode 100644 frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension_context.h create mode 100644 frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension_impl.h create mode 100644 frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension_instance.h create mode 100644 frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension.cpp create mode 100644 frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_context.cpp create mode 100644 frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_impl.cpp create mode 100644 frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_instance.cpp create mode 100644 frameworks/ets/ets/@ohos.app.ability.PhotoEditorExtensionAbility.ets create mode 100644 frameworks/ets/ets/application/PhotoEditorExtensionContext.ets diff --git a/bundle.json b/bundle.json index 1f9d759a7c8..7b67a689da9 100644 --- a/bundle.json +++ b/bundle.json @@ -131,6 +131,7 @@ "//foundation/ability/ability_runtime/frameworks/native/ability/native:service_extension_ani", "//foundation/ability/ability_runtime/frameworks/native/ability/native:ui_ability_ani", "//foundation/ability/ability_runtime/frameworks/native/ability/native:ui_extension_ani", + "//foundation/ability/ability_runtime/frameworks/native/ability/native:photo_editor_extension_ani", "//foundation/ability/ability_runtime/frameworks/native/appkit:ability_stage_ani", "//foundation/ability/ability_runtime/frameworks/native/appkit:test_runner_ani", "//foundation/ability/ability_runtime/frameworks/native/child_process:child_process", diff --git a/frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension.h b/frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension.h new file mode 100644 index 00000000000..0e143bfde81 --- /dev/null +++ b/frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension.h @@ -0,0 +1,63 @@ +/* + * 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_ABILITY_RUNTIME_ETS_PHOTO_EDITOR_EXTENSION_H +#define OHOS_ABILITY_RUNTIME_ETS_PHOTO_EDITOR_EXTENSION_H + +#include "ani.h" +#include "ets_native_reference.h" +#include "photo_editor_extension.h" +#include "ets_photo_editor_extension_impl.h" + +class NativeReference; +namespace OHOS { +namespace AbilityRuntime { +class PhotoEditorExtension; +class EtsPhotoEditorExtensionImpl; +class ETSRuntime; + +class EtsPhotoEditorExtension : public PhotoEditorExtension, + public std::enable_shared_from_this { +public: + explicit EtsPhotoEditorExtension(const std::unique_ptr &etsRuntime); + + virtual ~EtsPhotoEditorExtension() override = default; + + /** + * @brief Init the photo editor extension. + * + * @param record the photo editor extension record. + * @param application the application info. + * @param handler the photo editor extension handler. + * @param token the remote token. + */ + virtual void Init(const std::shared_ptr &record, + const std::shared_ptr &application, + std::shared_ptr &handler, const sptr &token) override; + + /** + * @brief Create JsPhotoEditorExtension. + * + * @param runtime The runtime. + * @return The JsPhotoEditorExtension instance. + */ + static EtsPhotoEditorExtension *Create(const std::unique_ptr &runtime); + +private: + std::shared_ptr impl_ = nullptr; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_PHOTO_EDITOR_EXTENSION_H \ No newline at end of file diff --git a/frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension_context.h b/frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension_context.h new file mode 100644 index 00000000000..d072c3ba175 --- /dev/null +++ b/frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension_context.h @@ -0,0 +1,63 @@ +/* + * 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_ABILITY_RUNTIME_ETS_PHOTO_EDITOR_EXTENSION_CONTEXT_H +#define OHOS_ABILITY_RUNTIME_ETS_PHOTO_EDITOR_EXTENSION_CONTEXT_H + +#include "photo_editor_extension_context.h" +#include "native_engine/native_engine.h" +#include "image_packer.h" +#include "ani.h" + +namespace OHOS { +namespace AbilityRuntime { +ani_object CreateEtsPhotoEditorExtensionContext(ani_env *env, std::shared_ptr context); + +class EtsPhotoEditorExtensionContext { +public: + explicit EtsPhotoEditorExtensionContext(const std::shared_ptr &context) + : context_(context) + {} + + virtual ~EtsPhotoEditorExtensionContext() = default; + + static void Finalizer(ani_env* aniEnv, ani_object obj); + + static EtsPhotoEditorExtensionContext* GetEtsPhotoEditorExtensionContext(ani_env* aniEnv, ani_object obj); + + static void SaveEditedContentWithUri(ani_env* aniEnv, ani_object obj, ani_string uri, ani_object callback); + + static void SaveEditedContentWithImage(ani_env* aniEnv, ani_object obj, ani_object imageObj, + ani_object optionObj, ani_object callback); + + std::weak_ptr GetAbilityContext() + { + return context_; + } +private: + void OnSaveEditedContentWithUri(ani_env* aniEnv, ani_object obj, ani_string uri, ani_object callback); + + void OnSaveEditedContentWithImage(ani_env* aniEnv, ani_object obj, ani_object imageObj, + ani_object optionObj, ani_object callback); + + bool UnwrapPackOption(ani_env* aniEnv, ani_object optionObj, Media::PackOption &packOption); + +private: + std::weak_ptr context_; +}; +} // namespace AbilityRuntime +} // namespace OHOS + +#endif // OHOS_ABILITY_RUNTIME_ETS_PHOTO_EDITOR_EXTENSION_CONTEXT_H \ No newline at end of file diff --git a/frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension_impl.h b/frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension_impl.h new file mode 100644 index 00000000000..928b88124db --- /dev/null +++ b/frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension_impl.h @@ -0,0 +1,60 @@ +/* + * 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_ABILITY_RUNTIME_ETS_PHOTO_EDITOR_EXTENSION_IMPL_H +#define OHOS_ABILITY_RUNTIME_ETS_PHOTO_EDITOR_EXTENSION_IMPL_H + +#include +#include "ani.h" +#include "ets_native_reference.h" +#include "ets_ui_extension.h" +#include "photo_editor_extension_context.h" +#include "ets_ui_extension_base.h" + + +namespace OHOS { +namespace AbilityRuntime { + +class PhotoEditorExtensionContext; + +class EtsPhotoEditorExtensionImpl : public EtsUIExtensionBase { +public: + explicit EtsPhotoEditorExtensionImpl(const std::unique_ptr &etsRuntime); + virtual ~EtsPhotoEditorExtensionImpl() override = default; + + void SetContext(const std::shared_ptr &context) + { + context_ = context; + EtsUIExtensionBase::SetContext(context); + } + +protected: + void BindContext() override; + void OnForeground(const Want &want, sptr sessionInfo) override; + +private: + void OnStartContentEditing(const AAFwk::Want &want, const sptr &sessionInfo); + ani_object CreateETSContext(ani_env *env, std::shared_ptr context); +protected: + std::shared_ptr context_ = nullptr; + std::set uiExtensionComponentIdSet_; + +private: + using EtsUIExtensionBase::SetContext; +}; +} // namespace AbilityRuntime +} // namespace OHOS + +#endif // OHOS_ABILITY_RUNTIME_ETS_PHOTO_EDITOR_EXTENSION_IMPL_H \ No newline at end of file diff --git a/frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension_instance.h b/frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension_instance.h new file mode 100644 index 00000000000..36bc7a43d3b --- /dev/null +++ b/frameworks/ets/ani/photo_editor_extension_ability/include/ets_photo_editor_extension_instance.h @@ -0,0 +1,29 @@ +/* + * 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_ABILITY_RUNTIME_ETS_PHOTO_EDITOR_EXTENSION_INSTANCE_H +#define OHOS_ABILITY_RUNTIME_ETS_PHOTO_EDITOR_EXTENSION_INSTANCE_H + +#include "photo_editor_extension.h" + +namespace OHOS { +namespace AbilityRuntime { +class PhotoEditorExtension; +class Runtime; + +PhotoEditorExtension *CreateETSPhotoEditorExtension(const std::unique_ptr &runtime); +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_PHOTO_EDITOR_EXTENSION_INSTANCE_H \ No newline at end of file diff --git a/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension.cpp b/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension.cpp new file mode 100644 index 00000000000..e5000fcf012 --- /dev/null +++ b/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension.cpp @@ -0,0 +1,90 @@ +/* + * 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 "ets_photo_editor_extension.h" +#include "ets_photo_editor_extension_context.h" +#include +#include + +#include "ability_info.h" +#include "ani_common_want.h" +#include "ets_runtime.h" +#include "photo_editor_extension.h" +#include "hilog_tag_wrapper.h" + +#include "connection_manager.h" + +namespace OHOS { +namespace AbilityRuntime { +using namespace OHOS::AppExecFwk; + +EtsPhotoEditorExtension* EtsPhotoEditorExtension::Create(const std::unique_ptr& runtime) +{ + return new (std::nothrow) EtsPhotoEditorExtension(runtime); +} + +EtsPhotoEditorExtension::EtsPhotoEditorExtension(const std::unique_ptr &eTSRuntime) +{ + impl_ = std::make_shared(eTSRuntime); + SetUIExtensionBaseImpl(impl_); +} + +void EtsPhotoEditorExtension::Init(const std::shared_ptr &record, + const std::shared_ptr &application, + std::shared_ptr &handler, const sptr &token) +{ + TAG_LOGD(AAFwkTag::UI_EXT, "Begin init photo editor extension"); + std::shared_ptr context = std::make_shared(); + context->SetToken(token); + auto appContext = Context::GetApplicationContext(); + if (appContext == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null appContext"); + return; + } + context->SetApplicationInfo(appContext->GetApplicationInfo()); + context->SetResourceManager(appContext->GetResourceManager()); + context->SetParentContext(appContext); + + if (record == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null record"); + return; + } + TAG_LOGD(AAFwkTag::UI_EXT, "Begin init abilityInfo"); + auto abilityInfo = record->GetAbilityInfo(); + context->SetAbilityInfo(abilityInfo); + context->InitHapModuleInfo(abilityInfo); + context->SetConfiguration(appContext->GetConfiguration()); + if (abilityInfo->applicationInfo.multiProjects) { + std::shared_ptr moduleContext = context->CreateModuleContext(abilityInfo->moduleName); + if (moduleContext != nullptr) { + auto rm = moduleContext->GetResourceManager(); + context->SetResourceManager(rm); + } + } + + Extension::Init(record, application, handler, token); + impl_->SetContext(context); + // 此处调用extensionBase基类 + impl_->SetAbilityInfo(Extension::abilityInfo_); + auto extensionCommon = impl_->Init(record, application, handler, token); + ExtensionBase::SetExtensionCommon(extensionCommon); +} +} // namespace AbilityRuntime +} // namespace OHOS + +extern "C" __attribute__((visibility("default"))) OHOS::AbilityRuntime::PhotoEditorExtension *OHOS_ETS_Extension_Create( + const std::unique_ptr &runtime) +{ + return OHOS::AbilityRuntime::EtsPhotoEditorExtension::Create(runtime); +} \ No newline at end of file diff --git a/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_context.cpp b/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_context.cpp new file mode 100644 index 00000000000..fac9347b49d --- /dev/null +++ b/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_context.cpp @@ -0,0 +1,322 @@ +/* + * 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 "ets_photo_editor_extension_context.h" +#include "hilog_tag_wrapper.h" +#include "ui_extension_context.h" +#include "ani_common_want.h" +#include "ets_context_utils.h" +#include "ets_error_utils.h" +#include "ability_manager_client.h" +#include "common_fun_ani.h" +#include "ets_context_utils.h" +#include "ets_error_utils.h" +#include "ets_extension_context.h" +#include "ani_common_start_options.h" +#include "ani_common_ability_result.h" +#include "ani_common_util.h" +#include "ani_enum_convert.h" +#include "pixel_map_taihe_ani.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace { + +constexpr const char *ERR_MSG_PARAMS_ERROR = "Params error"; +constexpr const char *ERR_MSG_INTERNAL_ERROR = "Internal error"; + +constexpr const char* PHOTO_EDITOR_EXTENSION_CONTEXT_CLASS_NAME = + "Lapplication/PhotoEditorExtensionContext/PhotoEditorExtensionContext;"; + +constexpr const char* CLEANER_CLASS_NAME = "Lapplication/PhotoEditorExtensionContext/Cleaner;"; + +bool BindNativeMethods(ani_env *env, ani_class &cls) +{ + ani_status status = ANI_ERROR; + std::array functions = { + ani_native_function { "nativeSaveEditedContentWithUri", nullptr, + reinterpret_cast(EtsPhotoEditorExtensionContext::SaveEditedContentWithUri) }, + ani_native_function { "nativeSaveEditedContentWithImage", nullptr, + reinterpret_cast(EtsPhotoEditorExtensionContext::SaveEditedContentWithImage) }, + }; + if ((status = env->Class_BindNativeMethods(cls, functions.data(), functions.size())) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to bindNativeMethods status: %{public}d", status); + return false; + } + + ani_class cleanerCls = nullptr; + status = env->FindClass(CLEANER_CLASS_NAME, &cleanerCls); + if (status != ANI_OK || cleanerCls == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to find class, status : %{public}d", status); + return false; + } + std::array CleanerMethods = { + ani_native_function { "clean", nullptr, reinterpret_cast(EtsPhotoEditorExtensionContext::Finalizer) }, + }; + if ((status = env->Class_BindNativeMethods(cleanerCls, CleanerMethods.data(), CleanerMethods.size())) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "bind method status : %{public}d", status); + return false; + } + return true; +} +} // namespace + +void EtsPhotoEditorExtensionContext::Finalizer(ani_env *env, ani_object obj) +{ + TAG_LOGD(AAFwkTag::UI_EXT, "TerminateSelf"); + if (env == nullptr) { + TAG_LOGD(AAFwkTag::UI_EXT, "null env"); + return; + } + ani_long nativeEtsContextPtr; + if (env->Object_GetFieldByName_Long(obj, "nativeExtensionContext", &nativeEtsContextPtr) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to get nativeExtensionContext"); + return; + } + if (nativeEtsContextPtr != 0) { + delete reinterpret_cast(nativeEtsContextPtr); + } +} + +ani_object CreateEtsPhotoEditorExtensionContext( + ani_env *env, std::shared_ptr context) +{ + TAG_LOGD(AAFwkTag::UI_EXT, "CreateEtsPhotoEditorExtensionContext begin"); + if (env == nullptr || context == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null env or context"); + return nullptr; + } + + ani_class cls = nullptr; + ani_status status = ANI_ERROR; + ani_method method = nullptr; + ani_object contextObj = nullptr; + if ((env->FindClass(PHOTO_EDITOR_EXTENSION_CONTEXT_CLASS_NAME, &cls)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "fail to find class status: %{public}d", status); + return nullptr; + } + if (!BindNativeMethods(env, cls)) { + TAG_LOGE(AAFwkTag::UI_EXT, "fail to BindNativeMethods"); + return nullptr; + } + + if ((status = env->Class_FindMethod(cls, "", "J:V", &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to find constructor status: %{public}d", status); + return nullptr; + } + + std::unique_ptr workContext = + std::make_unique(context); + if (workContext == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "Failed to create etsServiceExtensionContext"); + return nullptr; + } + auto photoEditorContextPtr = new std::weak_ptr (workContext->GetAbilityContext()); + + if ((status = env->Object_New(cls, method, &contextObj, (ani_long)workContext.release())) != ANI_OK|| + contextObj == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to create object, status: %{public}d", status); + return nullptr; + } + + if (!ContextUtil::SetNativeContextLong(env, contextObj, (ani_long)(photoEditorContextPtr))) { + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to setNativeContext long"); + return nullptr; + } + + ContextUtil::CreateEtsBaseContext(env, cls, contextObj, context); + CreateEtsExtensionContext(env, cls, contextObj, context, context->GetAbilityInfo()); + TAG_LOGD(AAFwkTag::UI_EXT, "CreateEtsPhotoEditorExtensionContext end"); + + return contextObj; +} + + +EtsPhotoEditorExtensionContext* EtsPhotoEditorExtensionContext::GetEtsPhotoEditorExtensionContext( + ani_env* aniEnv, ani_object obj) +{ + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null env"); + return nullptr; + } + EtsPhotoEditorExtensionContext* etsContext = nullptr; + ani_status status = ANI_ERROR; + ani_long etsContextLong = 0; + if ((status = aniEnv->Object_GetFieldByName_Long(obj, "nativeExtensionContext", &etsContextLong)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "status: %{public}d", status); + return nullptr; + } + etsContext = reinterpret_cast(etsContextLong); + if (etsContext == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "etsContext null"); + return nullptr; + } + return etsContext; +} + +void EtsPhotoEditorExtensionContext::SaveEditedContentWithUri(ani_env* aniEnv, ani_object obj, ani_string uri, + ani_object callback) +{ + TAG_LOGD(AAFwkTag::UI_EXT, "SaveEditedContentWithUri called"); + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null env"); + return; + } + auto etsPhotoEditorExtensionContext = GetEtsPhotoEditorExtensionContext(aniEnv, obj); + if (etsPhotoEditorExtensionContext == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null etsPhotoEditorExtensionContext"); + return; + } + etsPhotoEditorExtensionContext->OnSaveEditedContentWithUri(aniEnv, obj, uri, callback); +} + +void EtsPhotoEditorExtensionContext::SaveEditedContentWithImage(ani_env* aniEnv, ani_object obj, ani_object imageObj, + ani_object optionObj, ani_object callback) +{ + TAG_LOGD(AAFwkTag::UI_EXT, "SaveEditedContentWithImage called"); + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null env"); + return; + } + auto etsPhotoEditorExtensionContext = GetEtsPhotoEditorExtensionContext(aniEnv, obj); + if (etsPhotoEditorExtensionContext == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null etsPhotoEditorExtensionContext"); + return; + } + etsPhotoEditorExtensionContext->OnSaveEditedContentWithImage(aniEnv, obj, imageObj, optionObj, callback); +} + + +void EtsPhotoEditorExtensionContext::OnSaveEditedContentWithUri(ani_env* aniEnv, ani_object obj, ani_string uri, + ani_object callback) +{ + TAG_LOGD(AAFwkTag::UI_EXT, "OnSaveEditedContentWithUri called"); + + ani_object aniObject = nullptr; + ErrCode ret = ERR_OK; + auto context = context_.lock(); + if (context == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "context is nullptr"); + aniObject = EtsErrorUtil::CreateError(aniEnv, (ani_int)PhotoEditorErrorCode::ERROR_CODE_INTERNAL_ERROR, + ERR_MSG_INTERNAL_ERROR); + AppExecFwk::AsyncCallback(aniEnv, callback, aniObject, nullptr); + return; + } + + std::string uriStr {""}; + if (!AppExecFwk::GetStdString(aniEnv, uri, uriStr)) { + aniObject = EtsErrorUtil::CreateError(aniEnv, (ani_int)PhotoEditorErrorCode::ERROR_CODE_PARAM_ERROR, + ERR_MSG_PARAMS_ERROR); + AppExecFwk::AsyncCallback(aniEnv, callback, aniObject, nullptr); + return; + } + TAG_LOGD(AAFwkTag::UI_EXT, "Uri:%{public}s", uriStr.c_str()); + + AAFwk::Want newWant; + PhotoEditorErrorCode errCode = context->SaveEditedContent(uriStr, newWant); + ani_object abilityResult = AppExecFwk::WrapAbilityResult(aniEnv, static_cast(errCode), newWant); + if (abilityResult == nullptr) { + TAG_LOGW(AAFwkTag::UI_EXT, "null abilityResult"); + ret = static_cast(PhotoEditorErrorCode::ERROR_CODE_INTERNAL_ERROR); + aniObject = EtsErrorUtil::CreateError(aniEnv, ret, "null abilityResult"); + AppExecFwk::AsyncCallback(aniEnv, callback, aniObject, nullptr); + return; + } + // 传参ret的确认 + aniObject = EtsErrorUtil::CreateErrorByNativeErr(aniEnv, static_cast(errCode)); + AppExecFwk::AsyncCallback(aniEnv, callback, aniObject, abilityResult); +} + +void EtsPhotoEditorExtensionContext::OnSaveEditedContentWithImage(ani_env* aniEnv, ani_object obj, ani_object imageObj, + ani_object optionObj, ani_object callback) +{ + TAG_LOGD(AAFwkTag::UI_EXT, "OnSaveEditedContentWithImage called"); + ani_object aniObject = nullptr; + ani_int ret = ERR_OK; + + auto context = context_.lock(); + if (context == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "context is nullptr"); + ret = (ani_int)PhotoEditorErrorCode::ERROR_CODE_INTERNAL_ERROR; + aniObject = EtsErrorUtil::CreateError(aniEnv, ret, ERR_MSG_INTERNAL_ERROR); + AppExecFwk::AsyncCallback(aniEnv, callback, aniObject, nullptr); + return; + } + + auto image = OHOS::Media::PixelMapTaiheAni::GetNativePixelMap(aniEnv, imageObj); + if (!image) { + TAG_LOGE(AAFwkTag::UI_EXT, "Get edited image fail"); + ret = (ani_int)PhotoEditorErrorCode::ERROR_CODE_PARAM_ERROR; + aniObject = EtsErrorUtil::CreateError(aniEnv, ret, ERR_MSG_PARAMS_ERROR); + AppExecFwk::AsyncCallback(aniEnv, callback, aniObject, nullptr); + return; + } + + Media::PackOption packOption; + if (!UnwrapPackOption(aniEnv, optionObj, packOption)) { + TAG_LOGE(AAFwkTag::UI_EXT, "unwrap packoption failed"); + aniObject = EtsErrorUtil::CreateInvalidParamError(aniEnv, "unwrap packoption failed"); + AppExecFwk::AsyncCallback(aniEnv, callback, aniObject, nullptr); + return; + } + + TAG_LOGD(AAFwkTag::UI_EXT, "UnwrapPackOption end"); + + AAFwk::Want newWant; + PhotoEditorErrorCode errCode = context->SaveEditedContent(image, packOption, newWant); + ani_object abilityResult = AppExecFwk::WrapAbilityResult(aniEnv, static_cast(errCode), newWant); + if (abilityResult == nullptr) { + TAG_LOGW(AAFwkTag::UI_EXT, "null abilityResult"); + ret = static_cast(PhotoEditorErrorCode::ERROR_CODE_INTERNAL_ERROR); + aniObject = EtsErrorUtil::CreateError(aniEnv, ret, "null abilityResult"); + AppExecFwk::AsyncCallback(aniEnv, callback, aniObject, nullptr); + return; + } + TAG_LOGD(AAFwkTag::UI_EXT, "SaveEditedContent end"); + // 传参ret的确认 + aniObject = EtsErrorUtil::CreateErrorByNativeErr(aniEnv, static_cast(errCode)); + AppExecFwk::AsyncCallback(aniEnv, callback, aniObject, abilityResult); + TAG_LOGD(AAFwkTag::UI_EXT, "OnSaveEditedContentWithImage called"); +} + +bool EtsPhotoEditorExtensionContext::UnwrapPackOption(ani_env* aniEnv, ani_object optionObj, + Media::PackOption &packOption) +{ + // 传递对应的option参数 + std::string format {""}; + if (!AppExecFwk::GetStringProperty(aniEnv, optionObj, "format", format)) { + TAG_LOGE(AAFwkTag::UI_EXT, "Wrong argument type format"); + return false; + } + if (format == "") { + EtsErrorUtil::ThrowError(aniEnv, static_cast(PhotoEditorErrorCode::ERROR_CODE_PARAM_ERROR), + ERR_MSG_PARAMS_ERROR); + return false; + } + TAG_LOGD(AAFwkTag::UI_EXT, "Unwrap pack option result, format=%{public}s", format.c_str()); + + int32_t quality = 0; + if (!AppExecFwk::GetIntPropertyValue(aniEnv, optionObj, "quality", quality)) { + TAG_LOGE(AAFwkTag::UI_EXT, "Wrong argument type quality"); + return false; + } + TAG_LOGD(AAFwkTag::UI_EXT, "Unwrap pack option result, format=%{public}s, quality=%{public}d", format.c_str(), + quality); + packOption.format = format; + packOption.quality = static_cast(quality); + return true; +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_impl.cpp b/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_impl.cpp new file mode 100644 index 00000000000..b044210adf8 --- /dev/null +++ b/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_impl.cpp @@ -0,0 +1,152 @@ +/* + * 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 "ets_photo_editor_extension_impl.h" +#include "ets_ui_extension.h" +#include "ability_context.h" +#include "ability_delegator_registry.h" +#include "ability_info.h" +#include "ability_manager_client.h" +#include "ability_start_setting.h" +#include "configuration_utils.h" +#include "connection_manager.h" +#include "context.h" +#include "hitrace_meter.h" +#include "hilog_tag_wrapper.h" +#include "insight_intent_executor_info.h" +#include "insight_intent_executor_mgr.h" +#include "int_wrapper.h" +#include "ani_common_want.h" +#include "ui_extension_window_command.h" +#include "want_params_wrapper.h" +#include "ets_data_struct_converter.h" +#include "ets_ui_extension_context.h" +#include "ets_photo_editor_extension_context.h" + +namespace OHOS { +namespace AbilityRuntime { +using namespace OHOS::AppExecFwk; + + +namespace { + +} // namespace + +EtsPhotoEditorExtensionImpl::EtsPhotoEditorExtensionImpl(const std::unique_ptr &etsRuntime) + : EtsUIExtensionBase(etsRuntime) +{ +} + +ani_object EtsPhotoEditorExtensionImpl::CreateETSContext(ani_env* env, + std::shared_ptr context) +{ + ani_object obj = CreateEtsPhotoEditorExtensionContext(env, context); + return obj; +} + +void EtsPhotoEditorExtensionImpl::BindContext() +{ + auto env = etsRuntime_.GetAniEnv(); // 使用base基类的etsRuntime_ + + if (context_ == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null Context"); + return; + } + + TAG_LOGD(AAFwkTag::UI_EXT, "BindContext CreateJsPhotoEditorExtensionContext"); + ani_object contextObj = CreateETSContext(env, context_); + if (contextObj == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null contextObj"); + return; + } + + ani_field contextField = nullptr; + auto status = env->Class_FindField(etsObj_->aniCls, "context", &contextField); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "BindContext::Class_FindField status : %{public}d", status); + return; + } + ani_ref contextRef = nullptr; + if ((status = env->GlobalReference_Create(contextObj, &contextRef)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "BindContext::GlobalReference_Create status : %{public}d", status); + return; + } + + if ((status = env->Object_SetField_Ref(etsObj_->aniObj, contextField, contextRef)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "BindContext::Object_SetField_Ref status : %{public}d", status); + return; + } + shellContextRef_ = std::make_shared(); + shellContextRef_->aniObj = contextObj; + shellContextRef_->aniRef = contextRef; + context_->Bind(etsRuntime_, &(shellContextRef_->aniRef)); // 绑定aniRef指针,否则前端获取不到abilityContext + TAG_LOGD(AAFwkTag::UI_EXT, "EtsUIExtensionBase bind etsRuntime_"); + + TAG_LOGD(AAFwkTag::UI_EXT, "EtsPhotoEditorExtensionImpl::BindContext end"); +} + +void EtsPhotoEditorExtensionImpl::OnForeground(const Want &want, sptr sessionInfo) +{ + EtsUIExtensionBase::OnForeground(want, sessionInfo); + auto componentId = sessionInfo->uiExtensionComponentId; + if (uiExtensionComponentIdSet_.find(componentId) == uiExtensionComponentIdSet_.end()) { + OnStartContentEditing(want, sessionInfo); + uiExtensionComponentIdSet_.emplace(componentId); + } +} + +void EtsPhotoEditorExtensionImpl::OnStartContentEditing(const AAFwk::Want &want, + const sptr &sessionInfo) +{ + TAG_LOGD(AAFwkTag::UI_EXT, "EtPhotoEditorExtension want: (%{public}s), begin", want.ToUri().c_str()); + + std::string imageUri = want.GetStringParam("ability.params.stream"); + if (imageUri.empty()) { + TAG_LOGE(AAFwkTag::UI_EXT, "empty imageUri"); + return; + } + + TAG_LOGD(AAFwkTag::UI_EXT, "EtsPhotoEditorExtension imageUri: (%{public}s), begin", imageUri.c_str()); + if (context_ == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null context"); + return; + } + context_->SetWant(std::make_shared(want)); + + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null env"); + return; + } + ani_ref wantRef = AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null aniWant"); + return; + } + + ani_string aniImageUri {}; + env->String_NewUTF8(imageUri.c_str(), imageUri.size(), &aniImageUri); + ani_ref sessionObj = contentSessions_[sessionInfo->uiExtensionComponentId]; + if (sessionObj == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null sessionObj"); + return; + } + // c++调js,元能力封装 + CallObjectMethod(false, "onStartContentEditing", nullptr, aniImageUri, wantRef, sessionObj); + + TAG_LOGD(AAFwkTag::UI_EXT, "OnStartContentEditing End"); +} +} +} \ No newline at end of file diff --git a/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_instance.cpp b/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_instance.cpp new file mode 100644 index 00000000000..da3bcbbebf4 --- /dev/null +++ b/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_instance.cpp @@ -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. + */ + +#include "ets_photo_editor_extension_instance.h" + +#include +#include + +#include "hilog_tag_wrapper.h" +#include "hitrace_meter.h" +#include "string_wrapper.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace { +const char *ETS_ANI_LIBNAME = "libphoto_editor_extension_ani.z.so"; +const char *ETS_ANI_Create_FUNC = "OHOS_ETS_Extension_Create"; +using CreatePhotoEditorExtensionFunc = PhotoEditorExtension*(*)(const std::unique_ptr&); +CreatePhotoEditorExtensionFunc g_etsCreateFunc = nullptr; +} + +PhotoEditorExtension *CreateETSPhotoEditorExtension(const std::unique_ptr &runtime) +{ + if (g_etsCreateFunc != nullptr) { + return g_etsCreateFunc(runtime); + } + auto handle = dlopen(ETS_ANI_LIBNAME, RTLD_LAZY); + if (handle == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "dlopen failed %{public}s, %{public}s", ETS_ANI_LIBNAME, dlerror()); + return nullptr; + } + auto symbol = dlsym(handle, ETS_ANI_Create_FUNC); + if (symbol == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "dlsym failed %{public}s, %{public}s", ETS_ANI_Create_FUNC, dlerror()); + dlclose(handle); + return nullptr; + } + g_etsCreateFunc = reinterpret_cast(symbol); + TAG_LOGI(AAFwkTag::UI_EXT, "dlopen success %{public}s", ETS_ANI_LIBNAME); + return g_etsCreateFunc(runtime); +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/ets/@ohos.app.ability.PhotoEditorExtensionAbility.ets b/frameworks/ets/ets/@ohos.app.ability.PhotoEditorExtensionAbility.ets new file mode 100644 index 00000000000..a53f4f3f9d6 --- /dev/null +++ b/frameworks/ets/ets/@ohos.app.ability.PhotoEditorExtensionAbility.ets @@ -0,0 +1,61 @@ +/* + * 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 AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import Want from '@ohos.app.ability.Want'; +import UIExtensionContext from 'application.UIExtensionContext'; +import { AbilityUtils } from './utils/AbilityUtils'; +import PhotoEditorExtensionContext from 'application.PhotoEditorExtensionContext'; +import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession'; + + +export default class PhotoEditorExtensionAbility extends UIExtensionContext { + // 异步回调相关 + private callOnDestroy(): boolean { + const derivedClassType = AbilityUtils.getClassType(this); + if (derivedClassType === undefined) { + this.onDestroy(); + return false; + } + const PhotoEditorExtensionAbilityClassType = AbilityUtils.getClassType(new PhotoEditorExtensionAbility()); + if (PhotoEditorExtensionAbilityClassType === undefined) { + this.onDestroy(); + return false; + } + if (AbilityUtils.isOverride(derivedClassType, "onDestroyAsync", PhotoEditorExtensionAbilityClassType)) { + this.onDestroyAsync(); + return true; + } + this.onDestroy(); + return false; + } + + context: PhotoEditorExtensionContext = {}; + + onCreate(): void {} + + onForeground(): void {} + + onBackground(): void {} + + onDestroy(): void {} + + onDestroyAsync(): Promise { + return new Promise((resolve: (a: undefined)=>void, reject: (err: Error)=>void): void => {}); + } + + onStartContentEditing(uri: string, want: Want, session: UIExtensionContentSession): void {} + +} \ No newline at end of file diff --git a/frameworks/ets/ets/BUILD.gn b/frameworks/ets/ets/BUILD.gn index 128a246f4b8..a8c86f660ed 100644 --- a/frameworks/ets/ets/BUILD.gn +++ b/frameworks/ets/ets/BUILD.gn @@ -431,6 +431,28 @@ ohos_prebuilt_etc("ability_runtime_auto_fill_manager_abc_etc") { deps = [ ":ability_runtime_auto_fill_manager_abc" ] } +generate_static_abc("photo_editor_extension_ability_ani_abc") { + base_url = "./" + files = [ + "./application/PhotoEditorExtensionContext.ets", + "./@ohos.app.ability.PhotoEditorExtensionAbility.ets", + ] + + dst_file = "$target_out_dir/photo_editor_extension_ability_ani.abc" + out_puts = [ "$target_out_dir/photo_editor_extension_ability_ani.abc" ] + + is_boot_abc = "True" + device_dst_file = "/system/framework/photo_editor_extension_ability_ani.abc" +} + +ohos_prebuilt_etc("photo_editor_extension_ability_etc") { + source = "$target_out_dir/photo_editor_extension_ability_ani.abc" + deps = [ ":photo_editor_extension_ability_ani_abc" ] + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" +} + generate_static_abc("ui_extension_ability_ani_abc") { base_url = "./" @@ -1337,6 +1359,7 @@ group("ets_packages") { ":form_extension_ability_etc", ":service_extension_ability_abc_etc", ":ui_extension_ability_ani_etc", + ":photo_editor_extension_ability_etc", ":uri_permission_manager_abc_etc", ":form_extension_ability_etc", ":appRecovery_abc_etc", diff --git a/frameworks/ets/ets/application/PhotoEditorExtensionContext.ets b/frameworks/ets/ets/application/PhotoEditorExtensionContext.ets new file mode 100644 index 00000000000..7c2212c7b9b --- /dev/null +++ b/frameworks/ets/ets/application/PhotoEditorExtensionContext.ets @@ -0,0 +1,100 @@ +/* + * 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 Want from '@ohos.app.ability.Want'; +import image from '@ohos.multimedia.image'; +import { AbilityResult } from 'ability.abilityResult'; +import { AsyncCallback } from '@ohos.base'; +import { BusinessError } from '@ohos.base'; +import AsyncCallbackWrapper from '../utils/AbilityUtils'; +import ExtensionContext from 'application.ExtensionContext'; + + +class Cleaner { + static callback(cleaner: Cleaner): void { + cleaner.clean() + } + constructor(targetPtr: long) { + this.targetPtr = targetPtr + } + native clean(): void + private targetPtr: long = 0 +} + +export function callback(cleaner: Cleaner): void { + cleaner.clean(); +} + +let destroyRegister = new FinalizationRegistry(Cleaner.callback) +let unregisterToken = new object() + +export default class PhotoEditorExtensionContext extends ExtensionContext { + nativeExtensionContext:long = 0; + private cleaner: Cleaner | null = null; + registerCleaner(ptr: long): void { + this.cleaner = new Cleaner(ptr) + destroyRegister.register(this, this.cleaner!, unregisterToken); + } + unregisterCleaner(): void { + destroyRegister.unregister(unregisterToken); + } + constructor(context:long) { + if(this.nativeExtensionContext == 0){ + this.nativeExtensionContext = context; + } + this.registerCleaner(this.nativeExtensionContext) + } + + private native nativeSaveEditedContentWithUri(uri: string, callback: AsyncCallbackWrapper): void; + private native nativeSaveEditedContentWithImage(image: image.PixelMap, options: image.PackingOption, + callback: AsyncCallbackWrapper): void; + + saveEditedContentWithUri(uri: string): Promise { + let p = new Promise((resolve: (data: AbilityResult) => void, + reject: (err: BusinessError) => void): void => { + let myCall = + new AsyncCallbackWrapper((err: BusinessError | null, data: AbilityResult | undefined) => { + if (err == null || err.code == 0) { + resolve(data as AbilityResult); + } else { + reject(err); + } + }); + taskpool.execute((): void => { + this.nativeSaveEditedContentWithUri(uri, myCall); + }); + }); + return p; + } + + saveEditedContentWithImage(image: image.PixelMap, options: image.PackingOption): Promise { + let p = new Promise((resolve: (data: AbilityResult) => void, + reject: (err: BusinessError) => void): void => { + let myCall = + new AsyncCallbackWrapper((err: BusinessError | null, data: AbilityResult | undefined) => { + if (err == null || err.code == 0) { + resolve(data as AbilityResult); + } else { + reject(err); + } + }); + taskpool.execute((): void => { + this.nativeSaveEditedContentWithImage(image, options, myCall); + }); + }); + return p; + } +} diff --git a/frameworks/native/ability/native/BUILD.gn b/frameworks/native/ability/native/BUILD.gn index f8410ce6f89..a3034d37314 100644 --- a/frameworks/native/ability/native/BUILD.gn +++ b/frameworks/native/ability/native/BUILD.gn @@ -2096,6 +2096,92 @@ ohos_shared_library("ui_extension") { part_name = "ability_runtime" } +ohos_shared_library("photo_editor_extension_ani") { + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + configs = [ ":photo_editor_extension_config" ] + + include_dirs = [ + "${ability_runtime_path}/frameworks/ets/ani/ani_common/include", + "${ability_runtime_path}/frameworks/ets/ani/ui_extension_ability/include", + "${ability_runtime_path}/frameworks/ets/ani/ui_extension_base/include", + "${ability_runtime_path}/frameworks/ets/ani/photo_editor_extension_ability/include", + "${ability_runtime_path}/frameworks/ets/ani/enum_convert", + "${ability_runtime_path}/interfaces/kits/native/ability/native/ui_extension_ability", + "${ability_runtime_path}/interfaces/kits/native/ability/native/ui_extension_base", + "${ability_runtime_path}/interfaces/kits/native/ability/native/ui_service_extension_ability", + "${ability_runtime_path}/interfaces/inner_api/insight_intent/insight_intent_context", + "${ability_runtime_path}/interfaces/kits/native/ability/native/photo_editor_extension_ability", + ] + + sources = [ + "${ability_runtime_path}/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension.cpp", + "${ability_runtime_path}/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_context.cpp", + "${ability_runtime_path}/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_impl.cpp", + ] + + deps = [ + ":abilitykit_native", + ":photo_editor_extension", + ":ui_extension", + ":ui_extension_ani", + "${ability_runtime_innerkits_path}/ability_manager:ability_manager", + "${ability_runtime_innerkits_path}/runtime:runtime", + "${ability_runtime_napi_path}/inner/napi_common:napi_common", + "${ability_runtime_native_path}/ability:ability_context_native", + "${ability_runtime_native_path}/ability/native:ability_business_error", + "${ability_runtime_native_path}/appkit:app_context", + "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", + ":extensionkit_native", + ":ui_service_extension_connection", + "${ability_runtime_innerkits_path}/ability_manager:ability_start_options", + "${ability_runtime_native_path}/ability/native:configuration_helper", + "${ability_runtime_native_path}/ability/native:insight_intent_executor", + "${ability_runtime_native_path}/appkit:app_context_utils", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "app_file_service:fileuri_native", + "c_utils:utils", + "eventhandler:libeventhandler", + "hilog:libhilog", + "hitrace:hitrace_meter", + "image_framework:image", + "image_framework:image_native", + "image_framework:image_taihe", + "ipc:ipc_napi", + "ipc:ipc_single", + "napi:ace_napi", + "ability_base:base", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "ace_engine:ace_uicontent", + "bundle_framework:bms_ani_common", + "bundle_framework:libappexecfwk_common", + "ipc:ipc_core", + "window_manager:embeddablewindowstage_kit", + "window_manager:embeddablewindowstageani_kit", + "window_manager:extensionwindow_napi", + ] + + if (ability_runtime_graphics) { + external_deps += [ "window_manager:libwm" ] + } + + subsystem_name = "ability" + innerapi_tags = [ "platformsdk" ] + part_name = "ability_runtime" +} + ohos_shared_library("ui_extension_ani") { sanitize = { cfi = true @@ -2981,12 +3067,17 @@ ohos_shared_library("photo_editor_extension") { } configs = [ ":photo_editor_extension_config" ] + include_dirs = [ + "${ability_runtime_path}/frameworks/ets/ani/photo_editor_extension_ability/include", + ] + sources = [ "${ability_runtime_native_path}/ability/native/photo_editor_extension_ability/js_photo_editor_extension.cpp", "${ability_runtime_native_path}/ability/native/photo_editor_extension_ability/js_photo_editor_extension_context.cpp", "${ability_runtime_native_path}/ability/native/photo_editor_extension_ability/js_photo_editor_extension_impl.cpp", "${ability_runtime_native_path}/ability/native/photo_editor_extension_ability/photo_editor_extension.cpp", "${ability_runtime_native_path}/ability/native/photo_editor_extension_ability/photo_editor_extension_context.cpp", + "${ability_runtime_path}/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_instance.cpp", ] deps = [ diff --git a/frameworks/native/ability/native/photo_editor_extension_ability/photo_editor_extension.cpp b/frameworks/native/ability/native/photo_editor_extension_ability/photo_editor_extension.cpp index 935e356b8d0..716bc17412b 100644 --- a/frameworks/native/ability/native/photo_editor_extension_ability/photo_editor_extension.cpp +++ b/frameworks/native/ability/native/photo_editor_extension_ability/photo_editor_extension.cpp @@ -19,6 +19,7 @@ #include "cj_photo_editor_extension_instance.h" #include "runtime.h" #include "photo_editor_extension_context.h" +#include "ets_photo_editor_extension_instance.h" namespace OHOS { namespace AbilityRuntime { @@ -33,6 +34,8 @@ PhotoEditorExtension *PhotoEditorExtension::Create(const std::unique_ptr Date: Mon, 18 Aug 2025 04:07:57 +0000 Subject: [PATCH 2/2] =?UTF-8?q?static=5Fcodecheck=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liuxiaoxiyumemng --- .../src/ets_photo_editor_extension_impl.cpp | 4 +--- .../ets/@ohos.app.ability.PhotoEditorExtensionAbility.ets | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_impl.cpp b/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_impl.cpp index b044210adf8..08dec6b8e3d 100644 --- a/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_impl.cpp +++ b/frameworks/ets/ani/photo_editor_extension_ability/src/ets_photo_editor_extension_impl.cpp @@ -25,8 +25,6 @@ #include "context.h" #include "hitrace_meter.h" #include "hilog_tag_wrapper.h" -#include "insight_intent_executor_info.h" -#include "insight_intent_executor_mgr.h" #include "int_wrapper.h" #include "ani_common_want.h" #include "ui_extension_window_command.h" @@ -108,7 +106,7 @@ void EtsPhotoEditorExtensionImpl::OnForeground(const Want &want, sptr &sessionInfo) + const sptr &sessionInfo) { TAG_LOGD(AAFwkTag::UI_EXT, "EtPhotoEditorExtension want: (%{public}s), begin", want.ToUri().c_str()); diff --git a/frameworks/ets/ets/@ohos.app.ability.PhotoEditorExtensionAbility.ets b/frameworks/ets/ets/@ohos.app.ability.PhotoEditorExtensionAbility.ets index a53f4f3f9d6..99011e916f1 100644 --- a/frameworks/ets/ets/@ohos.app.ability.PhotoEditorExtensionAbility.ets +++ b/frameworks/ets/ets/@ohos.app.ability.PhotoEditorExtensionAbility.ets @@ -29,12 +29,12 @@ export default class PhotoEditorExtensionAbility extends UIExtensionContext { this.onDestroy(); return false; } - const PhotoEditorExtensionAbilityClassType = AbilityUtils.getClassType(new PhotoEditorExtensionAbility()); - if (PhotoEditorExtensionAbilityClassType === undefined) { + const photoEditorExtensionAbilityClassType = AbilityUtils.getClassType(new PhotoEditorExtensionAbility()); + if (photoEditorExtensionAbilityClassType === undefined) { this.onDestroy(); return false; } - if (AbilityUtils.isOverride(derivedClassType, "onDestroyAsync", PhotoEditorExtensionAbilityClassType)) { + if (AbilityUtils.isOverride(derivedClassType, "onDestroyAsync", photoEditorExtensionAbilityClassType)) { this.onDestroyAsync(); return true; } -- Gitee