1 /*
2  * Copyright (c) 2020 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 #include "js_async_work.h"
16 #include "ace_log.h"
17 
18 namespace OHOS {
19 namespace ACELite {
20 // Initialization of static variables
21 QueueHandler JsAsyncWork::appQueuehandler_ = nullptr;
22 FatalHandleFunc JsAsyncWork::isFatalErrorHitted_ = nullptr;
23 FatalHandleFunc JsAsyncWork::isAppExiting_ = nullptr;
24 #if (defined(__LINUX__) || defined(__LITEOS_A__))
25 PostUITaskFunc JsAsyncWork::postUITask_ = nullptr;
26 #endif
27 bool JsAsyncWork::isEnvInitialized_ = false;
28 
SetAppQueueHandler(const QueueHandler handler)29 void JsAsyncWork::SetAppQueueHandler(const QueueHandler handler)
30 {
31     appQueuehandler_ = handler;
32 }
33 
SetEnvStatus(bool envInitialized)34 void JsAsyncWork::SetEnvStatus(bool envInitialized)
35 {
36     isEnvInitialized_ = envInitialized;
37 }
38 
DispatchToLoop(AbilityMsgId msgId,void * data)39 bool JsAsyncWork::DispatchToLoop(AbilityMsgId msgId, void *data)
40 {
41     if (appQueuehandler_ == nullptr || !isEnvInitialized_) {
42         HILOG_ERROR(HILOG_MODULE_ACE, "JsAsyncWork:DispatchAsyncWork app not launched yet!");
43         return false;
44     }
45 
46     if (msgId >= MSG_ID_MAX) {
47         HILOG_ERROR(HILOG_MODULE_ACE, "JsAsyncWork:DispatchAsyncWork invalid msgId[%{public}d]!", msgId);
48         return false;
49     }
50 
51     if (isFatalErrorHitted_ != nullptr && isFatalErrorHitted_()) {
52         HILOG_ERROR(HILOG_MODULE_ACE, "JsAsyncWork:DispatchAsyncWork fatal error hitted, app will exit");
53         return false;
54     }
55 
56     if (isAppExiting_ != nullptr && isAppExiting_()) {
57         HILOG_ERROR(HILOG_MODULE_ACE, "JsAsyncWork:DispatchAsyncWork app is exiting");
58         return false;
59     }
60 
61     AbilityInnerMsg innerMsg;
62     innerMsg.msgId = msgId;
63     innerMsg.data = data;
64     int8_t ret = MessageQueueUtils::PutMessage(appQueuehandler_, static_cast<void *>(&innerMsg), 0);
65     return (ret == MSGQ_OK);
66 }
67 
DispatchAsyncWork(AsyncWorkHandler workHandler,void * data)68 bool JsAsyncWork::DispatchAsyncWork(AsyncWorkHandler workHandler, void *data)
69 {
70     return DispatchAsyncWorkInner(workHandler, nullptr, data);
71 }
72 
DispatchAsyncWork(AsyncHandler handler,void * data)73 bool JsAsyncWork::DispatchAsyncWork(AsyncHandler handler, void *data)
74 {
75     return DispatchAsyncWorkInner(nullptr, handler, data);
76 }
77 
DispatchAsyncWorkInner(AsyncWorkHandler workHandler,AsyncHandler handler,void * data)78 bool JsAsyncWork::DispatchAsyncWorkInner(AsyncWorkHandler workHandler, AsyncHandler handler, void *data)
79 {
80     if ((workHandler == nullptr) && (handler == nullptr)) {
81         HILOG_ERROR(HILOG_MODULE_ACE, "JsAsyncWork:DispatchAsyncWork parameters invalid");
82         return false;
83     }
84 
85     if ((isFatalErrorHitted_ != nullptr) && (isFatalErrorHitted_())) {
86         HILOG_ERROR(HILOG_MODULE_ACE, "JsAsyncWork:DispatchAsyncWork fatal processing, app will exit");
87         return false;
88     }
89 #if (defined(__LINUX__) || defined(__LITEOS_A__))
90     if ((workHandler != nullptr) && (postUITask_ != nullptr)) {
91         auto task1 = [workHandler, data]() {
92             workHandler(data);
93         };
94         return postUITask_(task1);
95     }
96     if ((handler != nullptr) && (postUITask_ != nullptr)) {
97         auto task2 = [handler, data]() {
98             handler(data, ERR_OK);
99         };
100         return postUITask_(task2);
101     }
102     return false;
103 #else
104     AsyncWork* asyncWork = new AsyncWork();
105     if (asyncWork == nullptr) {
106         HILOG_ERROR(HILOG_MODULE_ACE, "JsAsyncWork:DispatchAsyncWork create async work failed!");
107         return false;
108     }
109     asyncWork->workHandler = workHandler;
110     asyncWork->handler = handler;
111     asyncWork->data = data;
112 
113     bool ret = DispatchToLoop(ASYNCWORK, static_cast<void *>(asyncWork));
114     if (!ret) {
115         HILOG_ERROR(HILOG_MODULE_ACE, "JsAsyncWork:DispatchAsyncWork failed!, dispatch to loop failed]");
116         delete(asyncWork);
117         asyncWork = nullptr;
118     }
119     return ret;
120 #endif
121 }
122 
ExecuteAsyncWork(AsyncWork * & asyncWork,int8_t statusCode)123 void JsAsyncWork::ExecuteAsyncWork(AsyncWork *&asyncWork, int8_t statusCode)
124 {
125     if (asyncWork == nullptr) {
126         HILOG_ERROR(HILOG_MODULE_ACE, "JsAsyncWork:ExecuteAsyncWork parameters invalid!");
127         return;
128     }
129     AsyncWorkHandler workHandler = asyncWork->workHandler;
130     if (workHandler != nullptr) {
131         workHandler(asyncWork->data);
132     }
133     AsyncHandler handler = asyncWork->handler;
134     if (handler != nullptr) {
135         handler(asyncWork->data, statusCode);
136     }
137     delete asyncWork;
138     asyncWork = nullptr;
139 }
140 
SetFatalHandleFunc(FatalHandleFunc isFatalErrorHitted,FatalHandleFunc isAppExiting)141 void JsAsyncWork::SetFatalHandleFunc(FatalHandleFunc isFatalErrorHitted, FatalHandleFunc isAppExiting)
142 {
143     isFatalErrorHitted_ = isFatalErrorHitted;
144     isAppExiting_ = isAppExiting;
145 }
146 
147 #if (defined(__LINUX__) || defined(__LITEOS_A__))
SetPostUITaskFunc(PostUITaskFunc postUITask)148 void JsAsyncWork::SetPostUITaskFunc(PostUITaskFunc postUITask)
149 {
150     postUITask_ = postUITask;
151 }
152 #endif
153 } // namespace ACELite
154 } // namespace OHOS
155