1/*
2 * Copyright (c) 2023 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 <iostream>
17#include <stdexcept>
18#include "napi/native_api.h"
19#include <bits/alltypes.h>
20#include <ctime>
21#include <native_vsync/native_vsync.h>
22#include <stdexcept>
23#include <cstdio>
24#include <zconf.h>
25
26#define SUCCESS 0
27#define FAIL (-1)
28#define PARAM_0 0
29#define NUMBER_2 2
30#define NUMBER_3 3
31#define TIMEOUT_FIVE 10
32#define NUMBER_254 254
33#define NUMBER_256 256
34#define NUMBER_500 500
35#define NUMBER_40001000 40001000
36static bool g_flag = false;
37static void OnVSync(long long timestamp, void *data) { g_flag = true; }
38
39static napi_value OHNativeVSyncCreate(napi_env env, napi_callback_info info)
40{
41    napi_value result = nullptr;
42    char name[] = "test";
43    OH_NativeVSync *nativeVSync = OH_NativeVSync_Create(name, sizeof(name));
44    if (nativeVSync != nullptr) {
45        napi_create_int32(env, SUCCESS, &result);
46        OH_NativeVSync_Destroy(nativeVSync);
47    } else {
48        napi_create_int32(env, FAIL, &result);
49    }
50    return result;
51}
52
53static napi_value OHNativeVSyncCreateFOne(napi_env env, napi_callback_info info)
54{
55    napi_value result = nullptr;
56    unsigned int length = 0;
57    OH_NativeVSync *nativeVSync = OH_NativeVSync_Create(nullptr, length);
58    if (nativeVSync != nullptr) {
59        napi_create_int32(env, FAIL, &result);
60    } else {
61        napi_create_int32(env, SUCCESS, &result);
62    }
63    return result;
64}
65
66static napi_value OHNativeVSyncRequestFrame(napi_env env, napi_callback_info info)
67{
68    napi_value result = nullptr;
69    char name[] = "test";
70    OH_NativeVSync *nativeVSync = OH_NativeVSync_Create(name, sizeof(name));
71    OH_NativeVSync_FrameCallback callback = OnVSync;
72    int ret = OH_NativeVSync_RequestFrame(nativeVSync, callback, nullptr);
73    if (ret == SUCCESS) {
74        napi_create_int32(env, SUCCESS, &result);
75    } else {
76        napi_create_int32(env, FAIL, &result);
77    }
78    if (nativeVSync) {
79        OH_NativeVSync_Destroy(nativeVSync);
80    }
81    return result;
82}
83
84static napi_value OHNativeVSyncRequestFrameFOne(napi_env env, napi_callback_info info)
85{
86    napi_value result = nullptr;
87    int ret = OH_NativeVSync_RequestFrame(nullptr, nullptr, nullptr);
88    if (ret != SUCCESS) {
89        napi_create_int32(env, SUCCESS, &result);
90    } else {
91        napi_create_int32(env, FAIL, &result);
92    }
93    return result;
94}
95
96static napi_value OHNativeVSyncRequestFrameFTwo(napi_env env, napi_callback_info info)
97{
98    napi_value result = nullptr;
99    char name[] = "test";
100    OH_NativeVSync *nativeVSync = OH_NativeVSync_Create(name, sizeof(name));
101    int ret = OH_NativeVSync_RequestFrame(nativeVSync, nullptr, nullptr);
102    if (ret != SUCCESS) {
103        napi_create_int32(env, SUCCESS, &result);
104    } else {
105        napi_create_int32(env, FAIL, &result);
106    }
107    if (nativeVSync) {
108        OH_NativeVSync_Destroy(nativeVSync);
109    }
110    return result;
111}
112
113static napi_value OHNativeVSyncGetPeriod(napi_env env, napi_callback_info info)
114{
115    napi_value result = nullptr;
116    char name[] = "test";
117    OH_NativeVSync *nativeVSync = OH_NativeVSync_Create(name, sizeof(name));
118    OH_NativeVSync_FrameCallback callback = OnVSync;
119    OH_NativeVSync_RequestFrame(nativeVSync, callback, nullptr);
120    time_t startTime = time(PARAM_0);
121    double diffTime = 0;
122    while (!g_flag && diffTime < TIMEOUT_FIVE) {
123        time_t curTime = time(PARAM_0);
124        diffTime = difftime(curTime, startTime);
125    }
126    long long period;
127    int ret = OH_NativeVSync_GetPeriod(nativeVSync, &period);
128    if (ret == SUCCESS) {
129        napi_create_int32(env, SUCCESS, &result);
130    } else {
131        napi_create_int32(env, FAIL, &result);
132    }
133    if (nativeVSync) {
134        OH_NativeVSync_Destroy(nativeVSync);
135    }
136    return result;
137}
138
139static napi_value OHNativeVSyncGetPeriodFOne(napi_env env, napi_callback_info info)
140{
141    napi_value result = nullptr;
142    long long period;
143    int ret = OH_NativeVSync_GetPeriod(nullptr, &period);
144    if (ret != SUCCESS) {
145        napi_create_int32(env, SUCCESS, &result);
146    } else {
147        napi_create_int32(env, FAIL, &result);
148    }
149    return result;
150}
151
152static napi_value OHNativeVSyncCreateNull(napi_env env, napi_callback_info info)
153{
154    napi_value result = nullptr;
155    unsigned int length = 0;
156    OH_NativeVSync *nativeVSync = OH_NativeVSync_Create(nullptr, length);
157    if (nativeVSync == nullptr) {
158        napi_create_int32(env, FAIL, &result);
159    } else {
160        napi_create_int32(env, SUCCESS, &result);
161    }
162    return result;
163}
164
165static napi_value OHNativeVSyncCreateNotEq(napi_env env, napi_callback_info info)
166{
167    napi_value result = nullptr;
168    char name[] = "testCase";
169    unsigned int length = NUMBER_2;
170    OH_NativeVSync *nativeVSync = OH_NativeVSync_Create(name, length);
171    if (nativeVSync == nullptr) {
172        napi_create_int32(env, FAIL, &result);
173    } else {
174        napi_create_int32(env, SUCCESS, &result);
175    }
176    OH_NativeVSync_Destroy(nativeVSync);
177    return result;
178}
179
180static napi_value OHNativeVSyncCreateNormal(napi_env env, napi_callback_info info)
181{
182    napi_value result = nullptr;
183    char name[] = "testCase";
184    unsigned int length = strlen(name);
185    OH_NativeVSync *nativeVSync1 = OH_NativeVSync_Create(name, length);
186    napi_create_array_with_length(env, NUMBER_2, &result);
187    napi_value result1 = nullptr;
188    napi_value result2 = nullptr;
189    if (nativeVSync1 == nullptr) {
190        napi_create_int32(env, FAIL, &result1);
191    } else {
192        napi_create_int32(env, SUCCESS, &result1);
193    }
194    napi_set_element(env, result, 0, result1);
195
196    OH_NativeVSync *nativeVSync2 = OH_NativeVSync_Create(name, length);
197    if (nativeVSync2 == nullptr) {
198        napi_create_int32(env, FAIL, &result2);
199    } else {
200        napi_create_int32(env, SUCCESS, &result2);
201    }
202
203    napi_set_element(env, result, 1, result2);
204    OH_NativeVSync_Destroy(nativeVSync1);
205    OH_NativeVSync_Destroy(nativeVSync2);
206    return result;
207}
208
209static napi_value OHNativeVSyncCreateAbnormal(napi_env env, napi_callback_info info)
210{
211    napi_value result = nullptr;
212    OH_NativeVSync *nativeVSync = OH_NativeVSync_Create(NULL, 0);
213    if (nativeVSync == nullptr) {
214        napi_create_int32(env, SUCCESS, &result);
215    } else {
216        napi_create_int32(env, FAIL, &result);
217        return result;
218    }
219    nativeVSync = OH_NativeVSync_Create(0, 0);
220    if (nativeVSync == nullptr) {
221        napi_create_int32(env, SUCCESS, &result);
222    } else {
223        napi_create_int32(env, FAIL, &result);
224        return result;
225    }
226    OH_NativeVSync_Destroy(nativeVSync);
227    return result;
228}
229
230void MyFrameCallback(long long timestamp, void *data)
231{
232    int *myData = static_cast<int *>(data);
233    return;
234}
235
236static napi_value OHNativeVSyncCreateDifLenth(napi_env env, napi_callback_info info)
237{
238    napi_value result = nullptr;
239    std::vector<std::string> myArray = {
240        "0",
241        "a",
242        "你",
243        "!@#¥%^&*()_+",
244        " ",
245        "  ",
246        "这里有好多好多字符qazwsxedcrfvtgbyhnujqazwsxedcrfvtgbyhnujqazwsxedcrfvtgbyhnujqazwsxedcrfvtgbyhnuj",
247        "ab_cdefghijklmnopqrstuvwxyz",
248        "abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde"};
249    napi_create_array_with_length(env, myArray.size(), &result);
250
251    for (uint32_t index = 0; index < myArray.size(); index++) {
252        unsigned int len = strlen(myArray[index].c_str());
253        OH_NativeVSync *nativeVSync = nullptr;
254        napi_value resultIndex = nullptr;
255        nativeVSync = OH_NativeVSync_Create(myArray[index].c_str(), len);
256        if (nativeVSync == nullptr) {
257            napi_create_int32(env, FAIL+index, &result);
258            OH_NativeVSync_Destroy(nativeVSync);
259            return result;
260        } else {
261            napi_create_int32(env, SUCCESS, &result);
262            OH_NativeVSync_Destroy(nativeVSync);
263            continue;
264        }
265    }
266    return result;
267}
268
269static napi_value OHNativeVSyncCreateMuch(napi_env env, napi_callback_info info)
270{
271    napi_value result = nullptr;
272    char name[] = "testcase";
273    unsigned int length = strlen(name);
274    OH_NativeVSync *nativeVSyncArr[NUMBER_500];
275    int success = 0;
276    for (uint32_t i = 0; i < NUMBER_500; i++) {
277        nativeVSyncArr[i] = OH_NativeVSync_Create(name, length);
278        if (nativeVSyncArr[i] != nullptr) {
279            success = success + 1;
280            continue;
281        }
282    }
283    if (success == NUMBER_254) {
284        napi_create_int32(env, SUCCESS, &result);
285    } else {
286        napi_create_int32(env, success, &result);
287    }
288    for (uint32_t i = 0; i < NUMBER_500; i++) {
289        OH_NativeVSync_Destroy(nativeVSyncArr[i]);
290    }
291    return result;
292}
293
294static napi_value OHNativeVSyncGetPeriodNullptr(napi_env env, napi_callback_info info)
295{
296    napi_value result = nullptr;
297    long long period;
298    int res = OH_NativeVSync_GetPeriod(nullptr, &period);
299    napi_create_int32(env, res, &result);
300    return result;
301}
302
303static napi_value OHNativeVSyncRequestFrameNullptr(napi_env env, napi_callback_info info)
304{
305    napi_value result = nullptr;
306    char name[] = "testcase";
307    unsigned int length = strlen(name);
308    OH_NativeVSync *nativeVSync = OH_NativeVSync_Create(name, length);
309    napi_create_array_with_length(env, NUMBER_3, &result);
310    int param = 0;
311    int res = OH_NativeVSync_RequestFrame(nullptr, MyFrameCallback, &param);
312    if (res != NUMBER_40001000) {
313        napi_create_int32(env, FAIL, &result);
314        return result;
315    }
316    res = OH_NativeVSync_RequestFrame(nativeVSync, nullptr, &param);
317    if (res != NUMBER_40001000) {
318        napi_create_int32(env, FAIL, &result);
319        return result;
320    }
321    res = OH_NativeVSync_RequestFrame(nativeVSync, MyFrameCallback, nullptr);
322    if (res != 0) {
323        napi_create_int32(env, FAIL, &result);
324        return result;
325    }
326    napi_create_int32(env, SUCCESS, &result);
327    return result;
328}
329
330static napi_value OHNativeVSyncRequestFrameNormal(napi_env env, napi_callback_info info)
331{
332    napi_value result = nullptr;
333    char name[] = "testcase";
334    unsigned int length = strlen(name);
335    OH_NativeVSync *nativeVSync = OH_NativeVSync_Create(name, length);
336    int *param = nullptr;
337    int res = OH_NativeVSync_RequestFrame(nativeVSync, MyFrameCallback, param);
338    napi_create_int32(env, res, &result);
339    OH_NativeVSync_Destroy(nativeVSync);
340    return result;
341}
342
343static napi_value OHNativeVSyncRequestFrameParamErr(napi_env env, napi_callback_info info)
344{
345    napi_value result = nullptr;
346    char name[] = "testcase";
347    unsigned int length = strlen(name);
348    OH_NativeVSync *nativeVSync = OH_NativeVSync_Create(name, length);
349    char param[] = "test";
350    int res = OH_NativeVSync_RequestFrame(nativeVSync, MyFrameCallback, &param);
351    napi_create_int32(env, res, &result);
352    OH_NativeVSync_Destroy(nativeVSync);
353    return result;
354}
355
356EXTERN_C_START
357static napi_value Init(napi_env env, napi_value exports)
358{
359    napi_property_descriptor desc[] = {
360        {"oHNativeVSyncCreate", nullptr, OHNativeVSyncCreate, nullptr, nullptr, nullptr, napi_default, nullptr},
361        {"oHNativeVSyncCreateFOne", nullptr, OHNativeVSyncCreateFOne, nullptr, nullptr, nullptr, napi_default, nullptr},
362        {"oHNativeVSyncRequestFrame", nullptr, OHNativeVSyncRequestFrame, nullptr, nullptr, nullptr, napi_default,
363         nullptr},
364        {"oHNativeVSyncRequestFrameFOne", nullptr, OHNativeVSyncRequestFrameFOne, nullptr, nullptr, nullptr,
365         napi_default, nullptr},
366        {"oHNativeVSyncRequestFrameFTwo", nullptr, OHNativeVSyncRequestFrameFTwo, nullptr, nullptr, nullptr,
367         napi_default, nullptr},
368        {"oHNativeVSyncGetPeriod", nullptr, OHNativeVSyncGetPeriod, nullptr, nullptr, nullptr, napi_default, nullptr},
369        {"oHNativeVSyncGetPeriodFOne", nullptr, OHNativeVSyncGetPeriodFOne, nullptr, nullptr, nullptr, napi_default,
370         nullptr},
371        {"oHNativeVSyncCreateNull", nullptr, OHNativeVSyncCreateNull, nullptr, nullptr, nullptr, napi_default, nullptr},
372        {"oHNativeVSyncCreateNotEq", nullptr, OHNativeVSyncCreateNotEq, nullptr, nullptr, nullptr, napi_default,
373         nullptr},
374        {"oHNativeVSyncCreateNormal", nullptr, OHNativeVSyncCreateNormal, nullptr, nullptr, nullptr, napi_default,
375         nullptr},
376        {"oHNativeVSyncCreateAbnormal", nullptr, OHNativeVSyncCreateAbnormal, nullptr, nullptr, nullptr, napi_default,
377         nullptr},
378        {"oHNativeVSyncCreateDifLenth", nullptr, OHNativeVSyncCreateDifLenth, nullptr, nullptr, nullptr, napi_default,
379         nullptr},
380        {"oHNativeVSyncCreateMuch", nullptr, OHNativeVSyncCreateMuch, nullptr, nullptr, nullptr, napi_default, nullptr},
381        {"oHNativeVSyncGetPeriodNullptr", nullptr, OHNativeVSyncGetPeriodNullptr, nullptr, nullptr, nullptr,
382         napi_default, nullptr},
383        {"oHNativeVSyncRequestFrameNullptr", nullptr, OHNativeVSyncRequestFrameNullptr, nullptr, nullptr, nullptr,
384         napi_default, nullptr},
385        {"oHNativeVSyncRequestFrameNormal", nullptr, OHNativeVSyncRequestFrameNormal, nullptr, nullptr, nullptr,
386         napi_default, nullptr},
387        {"oHNativeVSyncRequestFrameParamErr", nullptr, OHNativeVSyncRequestFrameParamErr, nullptr, nullptr, nullptr,
388         napi_default, nullptr},
389    };
390    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
391    return exports;
392}
393EXTERN_C_END
394
395static napi_module demoModule = {
396    .nm_version = 1,
397    .nm_flags = 0,
398    .nm_filename = nullptr,
399    .nm_register_func = Init,
400    .nm_modname = "nativevsync",
401    .nm_priv = ((void *)0),
402    .reserved = {0},
403};
404
405extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); };
406