15ccb8f90Sopenharmony_ci/*
25ccb8f90Sopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
35ccb8f90Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
45ccb8f90Sopenharmony_ci * you may not use this file except in compliance with the License.
55ccb8f90Sopenharmony_ci * You may obtain a copy of the License at
65ccb8f90Sopenharmony_ci *
75ccb8f90Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
85ccb8f90Sopenharmony_ci *
95ccb8f90Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
105ccb8f90Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
115ccb8f90Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
125ccb8f90Sopenharmony_ci * See the License for the specific language governing permissions and
135ccb8f90Sopenharmony_ci * limitations under the License.
145ccb8f90Sopenharmony_ci */
155ccb8f90Sopenharmony_ci
165ccb8f90Sopenharmony_ci#include "runninglock_napi.h"
175ccb8f90Sopenharmony_ci
185ccb8f90Sopenharmony_ci#include <memory>
195ccb8f90Sopenharmony_ci
205ccb8f90Sopenharmony_ci#include "napi_errors.h"
215ccb8f90Sopenharmony_ci#include "napi_utils.h"
225ccb8f90Sopenharmony_ci#include "power_common.h"
235ccb8f90Sopenharmony_ci#include "power_log.h"
245ccb8f90Sopenharmony_ci#include "runninglock_entity.h"
255ccb8f90Sopenharmony_ci#include "xpower_event_js.h"
265ccb8f90Sopenharmony_ci
275ccb8f90Sopenharmony_cinamespace OHOS {
285ccb8f90Sopenharmony_cinamespace PowerMgr {
295ccb8f90Sopenharmony_cinamespace {
305ccb8f90Sopenharmony_ciconstexpr uint32_t CREATE_PROMISE_MAX_ARGC = 2;
315ccb8f90Sopenharmony_ciconstexpr uint32_t CREATE_CALLBACK_MAX_ARGC = 3;
325ccb8f90Sopenharmony_ciconstexpr uint32_t ISSUPPORTED_MAX_ARGC = 1;
335ccb8f90Sopenharmony_ciconstexpr uint32_t HOLD_MAX_ARGC = 1;
345ccb8f90Sopenharmony_ciconstexpr int32_t INDEX_0 = 0;
355ccb8f90Sopenharmony_ciconstexpr int32_t INDEX_1 = 1;
365ccb8f90Sopenharmony_ciconstexpr int32_t INDEX_2 = 2;
375ccb8f90Sopenharmony_ci}
385ccb8f90Sopenharmony_ci
395ccb8f90Sopenharmony_cinapi_value RunningLockNapi::Create(napi_env& env, napi_callback_info& info, napi_ref& napiRunningLockIns)
405ccb8f90Sopenharmony_ci{
415ccb8f90Sopenharmony_ci    size_t argc = CREATE_CALLBACK_MAX_ARGC;
425ccb8f90Sopenharmony_ci    napi_value argv[argc];
435ccb8f90Sopenharmony_ci    NapiUtils::GetCallbackInfo(env, info, argc, argv);
445ccb8f90Sopenharmony_ci
455ccb8f90Sopenharmony_ci    NapiErrors error;
465ccb8f90Sopenharmony_ci    if (argc != CREATE_CALLBACK_MAX_ARGC && argc != CREATE_PROMISE_MAX_ARGC) {
475ccb8f90Sopenharmony_ci        return error.ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
485ccb8f90Sopenharmony_ci    }
495ccb8f90Sopenharmony_ci
505ccb8f90Sopenharmony_ci    std::unique_ptr<AsyncCallbackInfo> asyncInfo = std::make_unique<AsyncCallbackInfo>();
515ccb8f90Sopenharmony_ci    RETURN_IF_WITH_RET(asyncInfo == nullptr, nullptr);
525ccb8f90Sopenharmony_ci    asyncInfo->GetData().SetRunningLockInstance(napiRunningLockIns);
535ccb8f90Sopenharmony_ci    // callback
545ccb8f90Sopenharmony_ci    if (argc == CREATE_CALLBACK_MAX_ARGC) {
555ccb8f90Sopenharmony_ci        return CreateAsyncCallback(env, argv, asyncInfo);
565ccb8f90Sopenharmony_ci    }
575ccb8f90Sopenharmony_ci
585ccb8f90Sopenharmony_ci    // promise
595ccb8f90Sopenharmony_ci    return CreatePromise(env, argv, asyncInfo);
605ccb8f90Sopenharmony_ci}
615ccb8f90Sopenharmony_ci
625ccb8f90Sopenharmony_cinapi_value RunningLockNapi::IsSupported(napi_env env, napi_callback_info info)
635ccb8f90Sopenharmony_ci{
645ccb8f90Sopenharmony_ci    size_t argc = ISSUPPORTED_MAX_ARGC;
655ccb8f90Sopenharmony_ci    napi_value argv[argc];
665ccb8f90Sopenharmony_ci    NapiUtils::GetCallbackInfo(env, info, argc, argv);
675ccb8f90Sopenharmony_ci
685ccb8f90Sopenharmony_ci    NapiErrors error;
695ccb8f90Sopenharmony_ci    if (argc != ISSUPPORTED_MAX_ARGC || !NapiUtils::CheckValueType(env, argv[INDEX_0], napi_number)) {
705ccb8f90Sopenharmony_ci        return error.ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
715ccb8f90Sopenharmony_ci    }
725ccb8f90Sopenharmony_ci
735ccb8f90Sopenharmony_ci    int32_t numType;
745ccb8f90Sopenharmony_ci    napi_get_value_int32(env, argv[INDEX_0], &numType);
755ccb8f90Sopenharmony_ci    RunningLockType type = static_cast<RunningLockType>(numType);
765ccb8f90Sopenharmony_ci
775ccb8f90Sopenharmony_ci    bool isSupported = (type == RunningLockType::RUNNINGLOCK_BACKGROUND) ||
785ccb8f90Sopenharmony_ci        (type == RunningLockType::RUNNINGLOCK_PROXIMITY_SCREEN_CONTROL);
795ccb8f90Sopenharmony_ci
805ccb8f90Sopenharmony_ci    napi_value result;
815ccb8f90Sopenharmony_ci    napi_get_boolean(env, isSupported, &result);
825ccb8f90Sopenharmony_ci    return result;
835ccb8f90Sopenharmony_ci}
845ccb8f90Sopenharmony_ci
855ccb8f90Sopenharmony_cinapi_value RunningLockNapi::Hold(napi_env env, napi_callback_info info)
865ccb8f90Sopenharmony_ci{
875ccb8f90Sopenharmony_ci    size_t argc = HOLD_MAX_ARGC;
885ccb8f90Sopenharmony_ci    napi_value argv[argc];
895ccb8f90Sopenharmony_ci    napi_value thisArg = NapiUtils::GetCallbackInfo(env, info, argc, argv);
905ccb8f90Sopenharmony_ci    NapiErrors error;
915ccb8f90Sopenharmony_ci    if (argc != HOLD_MAX_ARGC || !NapiUtils::CheckValueType(env, argv[INDEX_0], napi_number)) {
925ccb8f90Sopenharmony_ci        return error.ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
935ccb8f90Sopenharmony_ci    }
945ccb8f90Sopenharmony_ci
955ccb8f90Sopenharmony_ci    int32_t timeOut;
965ccb8f90Sopenharmony_ci    if (napi_ok != napi_get_value_int32(env, argv[INDEX_0], &timeOut)) {
975ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_RUNNING_LOCK, "napi_get_value_uint32 failed");
985ccb8f90Sopenharmony_ci        return nullptr;
995ccb8f90Sopenharmony_ci    }
1005ccb8f90Sopenharmony_ci    auto runningLock = UnwrapRunningLock(env, thisArg);
1015ccb8f90Sopenharmony_ci    RETURN_IF_WITH_RET(runningLock == nullptr, nullptr);
1025ccb8f90Sopenharmony_ci    ErrCode code = runningLock->Lock(timeOut);
1035ccb8f90Sopenharmony_ci    if (code == E_PERMISSION_DENIED) {
1045ccb8f90Sopenharmony_ci        return error.ThrowError(env, PowerErrors::ERR_PERMISSION_DENIED);
1055ccb8f90Sopenharmony_ci    }
1065ccb8f90Sopenharmony_ci    OHOS::HiviewDFX::ReportXPowerJsStackSysEvent(env, "RunningLockNapi::Hold");
1075ccb8f90Sopenharmony_ci    return nullptr;
1085ccb8f90Sopenharmony_ci}
1095ccb8f90Sopenharmony_ci
1105ccb8f90Sopenharmony_cinapi_value RunningLockNapi::IsHolding(napi_env env, napi_callback_info info)
1115ccb8f90Sopenharmony_ci{
1125ccb8f90Sopenharmony_ci    size_t argc = 0;
1135ccb8f90Sopenharmony_ci    napi_value thisArg = NapiUtils::GetCallbackInfo(env, info, argc, nullptr);
1145ccb8f90Sopenharmony_ci    auto runningLock = UnwrapRunningLock(env, thisArg);
1155ccb8f90Sopenharmony_ci    RETURN_IF_WITH_RET(runningLock == nullptr, nullptr);
1165ccb8f90Sopenharmony_ci    bool isUsed = runningLock->IsUsed();
1175ccb8f90Sopenharmony_ci    napi_value result;
1185ccb8f90Sopenharmony_ci    napi_get_boolean(env, isUsed, &result);
1195ccb8f90Sopenharmony_ci    return result;
1205ccb8f90Sopenharmony_ci}
1215ccb8f90Sopenharmony_ci
1225ccb8f90Sopenharmony_cinapi_value RunningLockNapi::UnHold(napi_env env, napi_callback_info info)
1235ccb8f90Sopenharmony_ci{
1245ccb8f90Sopenharmony_ci    size_t argc = 0;
1255ccb8f90Sopenharmony_ci    napi_value thisArg = NapiUtils::GetCallbackInfo(env, info, argc, nullptr);
1265ccb8f90Sopenharmony_ci    auto runningLock = UnwrapRunningLock(env, thisArg);
1275ccb8f90Sopenharmony_ci    RETURN_IF_WITH_RET(runningLock == nullptr, nullptr);
1285ccb8f90Sopenharmony_ci    ErrCode code = runningLock->UnLock();
1295ccb8f90Sopenharmony_ci    NapiErrors error;
1305ccb8f90Sopenharmony_ci    if (code == E_PERMISSION_DENIED) {
1315ccb8f90Sopenharmony_ci        return error.ThrowError(env, PowerErrors::ERR_PERMISSION_DENIED);
1325ccb8f90Sopenharmony_ci    }
1335ccb8f90Sopenharmony_ci    return nullptr;
1345ccb8f90Sopenharmony_ci}
1355ccb8f90Sopenharmony_ci
1365ccb8f90Sopenharmony_cinapi_value RunningLockNapi::CreateAsyncCallback(
1375ccb8f90Sopenharmony_ci    napi_env& env, napi_value argv[], std::unique_ptr<AsyncCallbackInfo>& asyncInfo)
1385ccb8f90Sopenharmony_ci{
1395ccb8f90Sopenharmony_ci    bool isStr = NapiUtils::CheckValueType(env, argv[INDEX_0], napi_string);
1405ccb8f90Sopenharmony_ci    bool isNum = NapiUtils::CheckValueType(env, argv[INDEX_1], napi_number);
1415ccb8f90Sopenharmony_ci    bool isFunc = NapiUtils::CheckValueType(env, argv[INDEX_2], napi_function);
1425ccb8f90Sopenharmony_ci    if (!isStr || !isNum || !isFunc) {
1435ccb8f90Sopenharmony_ci        POWER_HILOGD(
1445ccb8f90Sopenharmony_ci            FEATURE_RUNNING_LOCK, "isStr: %{public}d, isNum: %{public}d, isFunc: %{public}d", isStr, isNum, isFunc);
1455ccb8f90Sopenharmony_ci        return asyncInfo->GetError().ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
1465ccb8f90Sopenharmony_ci    }
1475ccb8f90Sopenharmony_ci    asyncInfo->GetData().SetName(env, argv[INDEX_0]);
1485ccb8f90Sopenharmony_ci    asyncInfo->GetData().SetType(env, argv[INDEX_1]);
1495ccb8f90Sopenharmony_ci    asyncInfo->CreateCallback(env, argv[INDEX_2]);
1505ccb8f90Sopenharmony_ci
1515ccb8f90Sopenharmony_ci    AsyncWork(
1525ccb8f90Sopenharmony_ci        env, asyncInfo, "CreateAsyncCallback",
1535ccb8f90Sopenharmony_ci        [](napi_env env, void* data) {
1545ccb8f90Sopenharmony_ci            AsyncCallbackInfo* asyncInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
1555ccb8f90Sopenharmony_ci            RETURN_IF(asyncInfo == nullptr);
1565ccb8f90Sopenharmony_ci            auto error = asyncInfo->GetData().CreateRunningLock();
1575ccb8f90Sopenharmony_ci            asyncInfo->GetError().Error(error);
1585ccb8f90Sopenharmony_ci        },
1595ccb8f90Sopenharmony_ci        [](napi_env env, napi_status status, void* data) {
1605ccb8f90Sopenharmony_ci            AsyncCallbackInfo* asyncInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
1615ccb8f90Sopenharmony_ci            RETURN_IF(asyncInfo == nullptr);
1625ccb8f90Sopenharmony_ci            napi_value result = asyncInfo->GetData().CreateInstanceForRunningLock(env);
1635ccb8f90Sopenharmony_ci            asyncInfo->CallFunction(env, result);
1645ccb8f90Sopenharmony_ci            asyncInfo->Release(env);
1655ccb8f90Sopenharmony_ci            delete asyncInfo;
1665ccb8f90Sopenharmony_ci        });
1675ccb8f90Sopenharmony_ci    return nullptr;
1685ccb8f90Sopenharmony_ci}
1695ccb8f90Sopenharmony_ci
1705ccb8f90Sopenharmony_cinapi_value RunningLockNapi::CreatePromise(
1715ccb8f90Sopenharmony_ci    napi_env& env, napi_value argv[], std::unique_ptr<AsyncCallbackInfo>& asyncInfo)
1725ccb8f90Sopenharmony_ci{
1735ccb8f90Sopenharmony_ci    bool isStr = NapiUtils::CheckValueType(env, argv[INDEX_0], napi_string);
1745ccb8f90Sopenharmony_ci    bool isNum = NapiUtils::CheckValueType(env, argv[INDEX_1], napi_number);
1755ccb8f90Sopenharmony_ci    if (!isStr || !isNum) {
1765ccb8f90Sopenharmony_ci        POWER_HILOGW(FEATURE_RUNNING_LOCK, "isStr: %{public}d, isNum: %{public}d", isStr, isNum);
1775ccb8f90Sopenharmony_ci        return asyncInfo->GetError().ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
1785ccb8f90Sopenharmony_ci    }
1795ccb8f90Sopenharmony_ci
1805ccb8f90Sopenharmony_ci    napi_value promise;
1815ccb8f90Sopenharmony_ci    asyncInfo->CreatePromise(env, promise);
1825ccb8f90Sopenharmony_ci    RETURN_IF_WITH_RET(promise == nullptr, nullptr);
1835ccb8f90Sopenharmony_ci    asyncInfo->GetData().SetName(env, argv[INDEX_0]);
1845ccb8f90Sopenharmony_ci    asyncInfo->GetData().SetType(env, argv[INDEX_1]);
1855ccb8f90Sopenharmony_ci
1865ccb8f90Sopenharmony_ci    AsyncWork(
1875ccb8f90Sopenharmony_ci        env, asyncInfo, "CreatePromise",
1885ccb8f90Sopenharmony_ci        [](napi_env env, void* data) {
1895ccb8f90Sopenharmony_ci            AsyncCallbackInfo* asyncInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
1905ccb8f90Sopenharmony_ci            RETURN_IF(asyncInfo == nullptr);
1915ccb8f90Sopenharmony_ci            auto error = asyncInfo->GetData().CreateRunningLock();
1925ccb8f90Sopenharmony_ci            asyncInfo->GetError().Error(error);
1935ccb8f90Sopenharmony_ci        },
1945ccb8f90Sopenharmony_ci        [](napi_env env, napi_status status, void* data) {
1955ccb8f90Sopenharmony_ci            AsyncCallbackInfo* asyncInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
1965ccb8f90Sopenharmony_ci            RETURN_IF(asyncInfo == nullptr);
1975ccb8f90Sopenharmony_ci            if (asyncInfo->GetError().IsError()) {
1985ccb8f90Sopenharmony_ci                napi_reject_deferred(env, asyncInfo->GetDeferred(), asyncInfo->GetError().GetNapiError(env));
1995ccb8f90Sopenharmony_ci            } else {
2005ccb8f90Sopenharmony_ci                napi_value result = asyncInfo->GetData().CreateInstanceForRunningLock(env);
2015ccb8f90Sopenharmony_ci                napi_resolve_deferred(env, asyncInfo->GetDeferred(), result);
2025ccb8f90Sopenharmony_ci            }
2035ccb8f90Sopenharmony_ci            asyncInfo->Release(env);
2045ccb8f90Sopenharmony_ci            delete asyncInfo;
2055ccb8f90Sopenharmony_ci        });
2065ccb8f90Sopenharmony_ci    return promise;
2075ccb8f90Sopenharmony_ci}
2085ccb8f90Sopenharmony_ci
2095ccb8f90Sopenharmony_civoid RunningLockNapi::AsyncWork(napi_env& env, std::unique_ptr<AsyncCallbackInfo>& asyncInfo,
2105ccb8f90Sopenharmony_ci    const std::string& resourceName, napi_async_execute_callback execute, napi_async_complete_callback complete)
2115ccb8f90Sopenharmony_ci{
2125ccb8f90Sopenharmony_ci    napi_value resource = nullptr;
2135ccb8f90Sopenharmony_ci    napi_create_string_utf8(env, resourceName.c_str(), NAPI_AUTO_LENGTH, &resource);
2145ccb8f90Sopenharmony_ci    napi_create_async_work(env, nullptr, resource, execute, complete,
2155ccb8f90Sopenharmony_ci        reinterpret_cast<void*>(asyncInfo.get()), &asyncInfo->GetAsyncWork());
2165ccb8f90Sopenharmony_ci    NAPI_CALL_RETURN_VOID(env, napi_queue_async_work_with_qos(env, asyncInfo->GetAsyncWork(), napi_qos_utility));
2175ccb8f90Sopenharmony_ci    asyncInfo.release();
2185ccb8f90Sopenharmony_ci}
2195ccb8f90Sopenharmony_ci
2205ccb8f90Sopenharmony_cistd::shared_ptr<RunningLock> RunningLockNapi::UnwrapRunningLock(napi_env& env, napi_value& thisArg)
2215ccb8f90Sopenharmony_ci{
2225ccb8f90Sopenharmony_ci    RunningLockEntity* entity = nullptr;
2235ccb8f90Sopenharmony_ci    if (napi_ok != napi_unwrap(env, thisArg, (void**)&entity)) {
2245ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_RUNNING_LOCK, "Cannot unwrap for pointer");
2255ccb8f90Sopenharmony_ci        return nullptr;
2265ccb8f90Sopenharmony_ci    }
2275ccb8f90Sopenharmony_ci    if (entity == nullptr || entity->runningLock == nullptr) {
2285ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_RUNNING_LOCK, "Entity runningLock is nullptr");
2295ccb8f90Sopenharmony_ci        return nullptr;
2305ccb8f90Sopenharmony_ci    }
2315ccb8f90Sopenharmony_ci    return entity->runningLock;
2325ccb8f90Sopenharmony_ci}
2335ccb8f90Sopenharmony_ci} // namespace PowerMgr
2345ccb8f90Sopenharmony_ci} // namespace OHOS
235