1/*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <securec.h>
17#include <cassert>
18#include "ability_manager.h"
19#include "napi/native_api.h"
20#include "napi/native_node_api.h"
21#include "ability_errors.h"
22
23#define GET_PARAMS(env, info, num) \
24    do {                           \
25    size_t argc = num;             \
26    napi_value argv[num];          \
27    napi_value thisVar;            \
28    void* data;                    \
29    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data) \
30    while (0)
31
32using struct _SetTimeAsyncContext {
33    napi_env env;
34    napi_async_work work;
35
36    int64_t time;
37    napi_deferred deferred;
38    napi_ref callbackRef;
39
40    int status;
41} SetTimeAsyncContext;
42
43static int JSAafwkStartAbility(napi_env env, napi_callback_info info)
44{
45    napi_status status;
46    size_t argc = 1;
47    napi_value args[1] = {0};
48    status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
49    assert(status == napi_ok);
50
51    napi_valuetype types[1];
52    status = napi_typeof(env, args[0], types);
53    assert(status == napi_ok);
54    assert(argc == 1 && types[0] == napi_object);
55
56    Want want;
57    if (memset_s(&want, sizeof(Want), 0x00, sizeof(Want)) != 0) {
58        return MEMORY_MALLOC_ERROR;
59    }
60    if (GetWantFromNapiValue(env, args[0], want) == false) {
61        return PARAM_CHECK_ERROR;
62    }
63    StartAbility(&want);
64    ClearWant(&want);
65}
66
67static int JSAafwkStopAbility(napi_env env, napi_callback_info info)
68{
69    napi_status status;
70    size_t argc = 1;
71    napi_value args[1] = {0};
72    status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
73    assert(status == napi_ok);
74
75    napi_valuetype types[1];
76    status = napi_typeof(env, args[0], types);
77    assert(status == napi_ok);
78    assert(argc == 1 && types[0] == napi_object);
79
80    Want want;
81    if (memset_s(&want, sizeof(Want), 0x00, sizeof(Want)) != 0) {
82        return MEMORY_MALLOC_ERROR;
83    }
84    if (GetWantFromNapiValue(env, args[0], want) == false) {
85        return PARAM_CHECK_ERROR;
86    }
87    StopAbility(&want);
88    ClearWant(&want);
89}
90
91static bool GetWantFromNapiValue(napi_env env, napi_value args, Want& want)
92{
93    ElementName element;
94    if (memset_s(&element, sizeof(ElementName), 0x00, sizeof(ElementName)) != 0) {
95        return MEMORY_MALLOC_ERROR;
96    }
97
98    napi_value data;
99    napi_get_named_property(env, args, "want_param", &data);
100
101    napi_value elementName;
102    if (napi_get_named_property(env, args, "elementName", &elementName) != napi_ok) {
103        return COMMAND_ERROR;
104    }
105
106    napi_value napi_deviceId;
107    napi_get_named_property(env, elementName, "deviceId", &napi_deviceId);
108    char *deviceId = nullptr;
109    GetCharPointerArgument(env, napi_deviceId, deviceId);
110    SetElementDeviceID(&element, deviceId);
111    free(deviceId);
112    deviceId = nullptr;
113
114    napi_value napi_bundleName;
115    napi_get_named_property(env, elementName, "bundleName", &napi_bundleName);
116    char *bundleName = nullptr;
117    GetCharPointerArgument(env, napi_bundleName, bundleName);
118    SetElementBundleName(&element, bundleName);
119    free(bundleName);
120    bundleName = nullptr;
121
122    napi_value napi_abilityName;
123    napi_get_named_property(env, elementName, "abilityName", &napi_abilityName);
124    char *abilityName = nullptr;
125    GetCharPointerArgument(env, napi_abilityName, abilityName);
126    SetElementAbilityName(&element, abilityName);
127    free(abilityName);
128    abilityName = nullptr;
129
130    SetWantData(&want, (void *)data, sizeof(data));
131    SetWantElement(&want, element);
132    ClearElement(&element);
133}
134
135// Function to read string argument from napi_value
136static bool GetCharPointerArgument(napi_env env, napi_value value, char* result)
137{
138    napi_status status;
139    size_t bufLength = 0;
140    result = nullptr;
141    bool ret = false;
142    // get buffer length first and get buffer based on length
143    status = napi_get_value_string_utf8(env, value, nullptr, 0, &bufLength);
144    if (status == napi_ok && bufLength > 0) {
145        // Create a buffer and create std::string later from it
146        result = (char *) malloc((bufLength + 1) * sizeof(char));
147        if (result != nullptr) {
148            status = napi_get_value_string_utf8(env, value, result, bufLength + 1, &bufLength);
149            if (status == napi_ok) {
150                ret = true;
151            }
152        }
153    }
154    return ret;
155}
156
157EXTERN_C_START
158using namespace OHOS {
159napi_value AafwkExport(napi_env env, napi_value exports)
160{
161    static napi_property_descriptor desc[] = {
162        DECLARE_NAPI_FUNCTION("startAbility", JSAafwkStartAbility),
163        DECLARE_NAPI_FUNCTION("stopAbility", JSAafwkStopAbility),
164    };
165    NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
166    return exports;
167}
168}
169EXTERN_C_END
170
171static napi_module aafwk_module = {
172    .nm_version = 1,
173    .nm_flags = 0,
174    .nm_filename = nullptr,
175    .nm_register_func = AafwkExport,
176    .nm_modname = "aafwk",
177    .nm_priv = ((void*)0),
178    .reserved = {0}
179};
180
181extern "C" __attribute__((constructor)) void AafwkRegister()
182{
183    napi_module_register(&aafwk_module);
184}