* Copyright (c) 2026 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 "overlay_params.h"
#include "ani_utils.h"
#include "core/common/ace_engine.h"
#include "frameworks/base/error/error_code.h"
namespace OHOS::Ace {
bool GetLevelMode(ani_env* env, ani_object object, LevelMode& result)
{
ani_int resultInt;
if (!AniUtils::GetEnumInt(env, object, "levelMode", "@ohos.promptAction.LevelMode", resultInt)) {
return false;
}
result = static_cast<LevelMode>(resultInt);
return true;
}
bool GetOrderOverlayOptions(ani_env* env, ani_object object, NG::OrderOverlayOptions& result)
{
if (AniUtils::IsUndefinedObject(env, object)) {
return false;
}
if (!AniUtils::IsClassObject(env, object, "@ohos.arkui.UIContext.OrderOverlayOptions")) {
return false;
}
GetLevelMode(env, object, result.levelMode);
result.levelUniqueId = -1;
AniUtils::GetInt32Param(env, object, "levelUniqueId", result.levelUniqueId);
return true;
}
bool GetOrderOverlayOptionsInternal(ani_env* env, ani_object object, NG::OrderOverlayOptions& result)
{
if (AniUtils::IsUndefinedObject(env, object)) {
return false;
}
if (!AniUtils::IsClassObject(env, object, "@ohos.overlayManager.OrderOverlayOptionsInternal")) {
return false;
}
AniUtils::GetDoubleParamOpt(env, object, "levelOrder", result.levelOrder);
return true;
}
std::function<void(int32_t)> GetOpenOrderOverlayPromise(std::shared_ptr<OverlayAsyncContext>& asyncContext)
{
auto callback = [asyncContext](int32_t errorCode) mutable {
if (!asyncContext) {
return;
}
auto container = AceEngine::Get().GetContainer(asyncContext->instanceId);
if (!container) {
return;
}
auto taskExecutor = container->GetTaskExecutor();
if (!taskExecutor) {
return;
}
auto task = [asyncContext, errorCode]() {
if (!asyncContext || !asyncContext->deferred) {
return;
}
ani_env* env = nullptr;
ani_status status = asyncContext->vm->GetEnv(ANI_VERSION_1, &env);
if (status != ANI_OK || env == nullptr) {
TAG_LOGE(AceLogTag::ACE_OVERLAY, "[ANI] GetEnv fail. status: %{public}d", status);
return;
}
ani_size nrRefs = 16;
status = env->CreateLocalScope(nrRefs);
if (status != ANI_OK) {
TAG_LOGE(AceLogTag::ACE_OVERLAY, "[ANI] CreateLocalScope fail. status: %{public}d", status);
return;
}
if (errorCode == ERROR_CODE_NO_ERROR) {
ani_ref successRef;
env->GetUndefined(&successRef);
status = env->PromiseResolver_Resolve(asyncContext->deferred, successRef);
if (status != ANI_OK) {
TAG_LOGW(AceLogTag::ACE_OVERLAY, "[ANI] PromiseResolver_Resolve fail. status: %{public}d", status);
}
} else {
std::string errorMsg = AniUtils::ErrorToMessage(errorCode);
ani_error error = AniUtils::GetErrorObject(env, errorMsg, errorCode);
status = env->PromiseResolver_Reject(asyncContext->deferred, error);
if (status != ANI_OK) {
TAG_LOGW(AceLogTag::ACE_OVERLAY, "[ANI] PromiseResolver_Reject fail. status: %{public}d", status);
}
}
env->DestroyLocalScope();
};
taskExecutor->PostTask(std::move(task), TaskExecutor::TaskType::JS, "ArkUIOpenOrderOverlayCallback");
asyncContext = nullptr;
};
return callback;
}
}