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 "js_ans_dialog_callback.h"
17 
18 #include <uv.h>
19 
20 #include "ans_dialog_callback_interface.h"
21 #include "ans_inner_errors.h"
22 #include "ans_log_wrapper.h"
23 
24 namespace OHOS {
25 using Notification::ANS_LABEL;
26 using Notification::AnsLogWrapper;
27 using Notification::AnsLogLevel;
28 
29 namespace NotificationNapi {
Init(napi_env env,AsyncCallbackInfoIsEnable * callbackInfo,JsAnsDialogCallbackComplete complete)30 bool JsAnsDialogCallback::Init(napi_env env,
31     AsyncCallbackInfoIsEnable* callbackInfo,
32     JsAnsDialogCallbackComplete complete)
33 {
34     ANS_LOGD("enter");
35     if (env == nullptr || callbackInfo == nullptr || complete == nullptr) {
36         ANS_LOGE("invalid data");
37         return false;
38     }
39     env_ = env;
40     callbackInfo_ = callbackInfo;
41     complete_ = complete;
42     return true;
43 }
44 
GetErrCodeFromStatus(EnabledDialogStatus status)45 int32_t JsAnsDialogCallback::GetErrCodeFromStatus(EnabledDialogStatus status)
46 {
47     switch (static_cast<EnabledDialogStatus>(status)) {
48         case EnabledDialogStatus::ALLOW_CLICKED:
49             return ERR_OK;
50         case EnabledDialogStatus::DENY_CLICKED:
51             return ERR_ANS_NOT_ALLOWED;
52         case EnabledDialogStatus::CRASHED:
53             return ERROR_INTERNAL_ERROR;
54         default:
55             return ERROR_INTERNAL_ERROR;
56     }
57     return ERROR_INTERNAL_ERROR;
58 }
59 
ProcessDialogStatusChanged(const DialogStatusData & data)60 void JsAnsDialogCallback::ProcessDialogStatusChanged(const DialogStatusData& data)
61 {
62     ANS_LOGD("enter");
63     std::unique_ptr<AsyncCallbackInfoIsEnable> callbackInfo(callbackInfo_);
64     if (env_ == nullptr || callbackInfo == nullptr || complete_ == nullptr) {
65         ANS_LOGE("invalid data");
66         AnsDialogHostClient::Destroy();
67         return;
68     }
69 
70     callbackInfo->info.errorCode = JsAnsDialogCallback::GetErrCodeFromStatus(
71         static_cast<EnabledDialogStatus>(data.GetStatus()));
72 
73     uv_loop_s* loop = nullptr;
74     napi_get_uv_event_loop(env_, &loop);
75     if (loop == nullptr) {
76         ANS_LOGE("loop is nullptr");
77         AnsDialogHostClient::Destroy();
78         return;
79     }
80 
81     auto work = std::make_unique<uv_work_t>();
82     struct WorkData {
83         decltype(env_) env = nullptr;
84         decltype(callbackInfo_) callbackInfo = nullptr;
85         decltype(complete_) complete = nullptr;
86     };
87     auto workData = std::make_unique<WorkData>();
88     workData->env = env_;
89     workData->callbackInfo = callbackInfo_;
90     workData->complete = complete_;
91 
92     work->data = static_cast<void*>(workData.get());
93     auto jsCb = [](uv_work_t* work, int status) {
94         ANS_LOGD("enter");
95         std::unique_ptr<uv_work_t> workSP(work);
96         if (work == nullptr || work->data == nullptr) {
97             ANS_LOGE("invalid data");
98             return;
99         }
100         auto* data = static_cast<WorkData*>(work->data);
101         std::unique_ptr<WorkData> dataSP(data);
102         std::unique_ptr<AsyncCallbackInfoIsEnable> callbackInfoSP(data->callbackInfo);
103         if (data->env == nullptr ||
104             data->callbackInfo == nullptr ||
105             data->complete == nullptr) {
106             return;
107         }
108         auto* callbackInfoPtr = callbackInfoSP.release();
109         data->complete(data->env, static_cast<void*>(callbackInfoPtr));
110     };
111 
112     int ret = uv_queue_work_with_qos(loop,
113         work.get(),
114         [](uv_work_t *work) {},
115         jsCb,
116         uv_qos_user_initiated);
117     if (ret != 0) {
118         ANS_LOGE("uv_queue_work failed");
119         return;
120     }
121     callbackInfo.release();
122     workData.release();
123     work.release();
124 }
125 } // namespace NotificationNapi
126 } // namespace OHOS
127