1 /*
2  * Copyright (c) 2024 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 "napi_async_work_promise.h"
17 
18 #include "app_log_wrapper.h"
19 
20 namespace OHOS {
21 namespace AppExecFwk {
22 namespace LIBZIP {
23 using namespace std;
24 
NapiAsyncWorkPromise(napi_env env,NapiValue thisPtr)25 NapiAsyncWorkPromise::NapiAsyncWorkPromise(napi_env env, NapiValue thisPtr) : NapiAsyncWorkFactory(env)
26 {
27     ctx_ = new NAsyncContextPromise(thisPtr);
28 }
29 
~NapiAsyncWorkPromise()30 NapiAsyncWorkPromise::~NapiAsyncWorkPromise()
31 {
32     if (ctx_ != nullptr) {
33         delete ctx_;
34         ctx_ = nullptr;
35     }
36 }
37 
PromiseOnExec(napi_env env,void * data)38 static void PromiseOnExec(napi_env env, void *data)
39 {
40     auto ctx = static_cast<NAsyncContextPromise *>(data);
41     if (ctx != nullptr && ctx->cbExec_ != nullptr) {
42         ctx->err_ = ctx->cbExec_(env);
43     }
44 }
45 
PromiseOnComplete(napi_env env,napi_status status,void * data)46 static void PromiseOnComplete(napi_env env, napi_status status, void *data)
47 {
48     auto ctx = static_cast<NAsyncContextPromise *>(data);
49     if (ctx == nullptr) {
50         return;
51     }
52 
53     if (ctx->cbComplete_ != nullptr) {
54         ctx->res_ = ctx->cbComplete_(env, ctx->err_);
55     }
56 
57     if (!ctx->res_.TypeIsError(true)) {
58         status = napi_resolve_deferred(env, ctx->deferred_, ctx->res_.val_);
59         if (status != napi_ok) {
60             APP_LOGE("Internal BUG, cannot resolve promise for %{public}d", status);
61         }
62     } else {
63         status = napi_reject_deferred(env, ctx->deferred_, ctx->res_.val_);
64         if (status != napi_ok) {
65             APP_LOGE("Internal BUG, cannot reject promise for %{public}d", status);
66         }
67     }
68 
69     ctx->deferred_ = nullptr;
70     napi_delete_async_work(env, ctx->awork_);
71     delete ctx;
72 }
73 
Schedule(string procedureName,NContextCBExec cbExec,NContextCBComplete cbComplete)74 NapiValue NapiAsyncWorkPromise::Schedule(string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete)
75 {
76     ctx_->cbExec_ = move(cbExec);
77     ctx_->cbComplete_ = move(cbComplete);
78 
79     napi_value result = nullptr;
80     napi_status status = napi_create_promise(env_, &ctx_->deferred_, &result);
81     if (status != napi_ok) {
82         APP_LOGE("INNER BUG. Cannot create promise for %{public}d", status);
83         return NapiValue();
84     }
85 
86     napi_value resource = NapiValue::CreateUTF8String(env_, procedureName).val_;
87     status = napi_create_async_work(env_, nullptr, resource, PromiseOnExec, PromiseOnComplete, ctx_, &ctx_->awork_);
88     if (status != napi_ok) {
89         APP_LOGE("INNER BUG. Failed to create async work for %{public}d", status);
90         return NapiValue();
91     }
92 
93     status = napi_queue_async_work(env_, ctx_->awork_);
94     if (status != napi_ok) {
95         APP_LOGE("INNER BUG. Failed to queue async work for %{public}d", status);
96         return NapiValue();
97     }
98 
99     ctx_ = nullptr;  // The ownership of ctx_ has been transferred
100     return {env_, result};
101 }
102 }  // namespace LIBZIP
103 }  // namespace AppExecFwk
104 }  // namespace OHOS