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_ability_thread.h"
17
18 #include "abilityms_log.h"
19 #include "ability_errors.h"
20 #include "ability_inner_message.h"
21 #include "adapter.h"
22 #include "js_ability.h"
23 #include "js_async_work.h"
24 #include "los_task.h"
25 #include "slite_ability_loader.h"
26
27 namespace OHOS {
28 namespace AbilitySlite {
29 constexpr uint16_t APP_TASK_PRI = 25;
30 constexpr uint32_t QUEUE_LENGTH = 32;
31 static char g_jsAppTask[] = "AppTask";
32
33 JsAbilityThread::JsAbilityThread() = default;
34
~JsAbilityThread()35 JsAbilityThread::~JsAbilityThread()
36 {
37 delete ability_;
38 ability_ = nullptr;
39 if (messageQueueId_ != nullptr) {
40 osMessageQueueDelete(messageQueueId_);
41 messageQueueId_ = nullptr;
42 }
43 }
44
InitAbilityThread(const AbilityRecord * abilityRecord)45 int32_t JsAbilityThread::InitAbilityThread(const AbilityRecord *abilityRecord)
46 {
47 if (abilityRecord == nullptr) {
48 HILOG_ERROR(HILOG_MODULE_AAFWK, "JsAbilityThread init fail, abilityRecord is null");
49 return PARAM_NULL_ERROR;
50 }
51 if (abilityRecord->appName == nullptr) {
52 HILOG_ERROR(HILOG_MODULE_AAFWK, "JsAbilityThread init fail, appName is null");
53 return PARAM_NULL_ERROR;
54 }
55 if (state_ != AbilityThreadState::ABILITY_THREAD_UNINITIALIZED) {
56 HILOG_ERROR(HILOG_MODULE_AAFWK, "JsAbilityThread init fail, the AbilityThread is already inited");
57 return PARAM_CHECK_ERROR;
58 }
59
60 messageQueueId_ = osMessageQueueNew(QUEUE_LENGTH, sizeof(SliteAbilityInnerMsg), nullptr);
61 if (messageQueueId_ == nullptr) {
62 HILOG_ERROR(HILOG_MODULE_AAFWK, "JsAbilityThread init fail: messageQueueId is null");
63 return MEMORY_MALLOC_ERROR;
64 }
65
66 TSK_INIT_PARAM_S stTskInitParam = { nullptr };
67 LOS_TaskLock();
68 stTskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC) (JsAbilityThread::AppTaskHandler);
69 stTskInitParam.uwStackSize = TASK_STACK_SIZE;
70 stTskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST - APP_TASK_PRI;
71 stTskInitParam.pcName = g_jsAppTask;
72 stTskInitParam.uwResved = 0;
73 stTskInitParam.uwArg = reinterpret_cast<uintptr_t>(messageQueueId_);
74 uint32_t ret = LOS_TaskCreate(&appTaskId_, &stTskInitParam);
75 if (ret != LOS_OK) {
76 HILOG_ERROR(HILOG_MODULE_AAFWK, "JsAbilityThread init fail: LOS_TaskCreate ret %{public}d", ret);
77 osMessageQueueDelete(messageQueueId_);
78 LOS_TaskUnlock();
79 return CREATE_APPTASK_ERROR;
80 }
81 state_ = AbilityThreadState::ABILITY_THREAD_INITIALIZED;
82 ability_ = SliteAbilityLoader::GetInstance().CreateAbility(SliteAbilityType::JS_ABILITY, abilityRecord->appName);
83 if (ability_ == nullptr) {
84 HILOG_INFO(HILOG_MODULE_AAFWK, "JsAbility create fail");
85 return MEMORY_MALLOC_ERROR;
86 }
87 ability_->SetToken(abilityRecord->token);
88 ACELite::JsAsyncWork::SetAppQueueHandler(messageQueueId_);
89 LOS_TaskUnlock();
90 HILOG_INFO(HILOG_MODULE_AAFWK, "JsAbilityThread init done");
91 return ERR_OK;
92 }
93
ReleaseAbilityThread()94 int32_t JsAbilityThread::ReleaseAbilityThread()
95 {
96 ACELite::JsAsyncWork::SetAppQueueHandler(nullptr);
97 if (state_ != AbilityThreadState::ABILITY_THREAD_INITIALIZED) {
98 HILOG_ERROR(HILOG_MODULE_AAFWK, "JsAbilityThread release fail, the AbilityThread is not inited");
99 return PARAM_CHECK_ERROR;
100 }
101 state_ = AbilityThreadState::ABILITY_THREAD_RELEASED;
102 LOS_TaskDelete(appTaskId_);
103 appTaskId_ = 0;
104 osMessageQueueDelete(messageQueueId_);
105 messageQueueId_ = nullptr;
106 return ERR_OK;
107 }
108
GetMessageQueueId() const109 osMessageQueueId_t JsAbilityThread::GetMessageQueueId() const
110 {
111 return messageQueueId_;
112 }
113
GetAppTaskId() const114 UINT32 JsAbilityThread::GetAppTaskId() const
115 {
116 return appTaskId_;
117 }
118
AppTaskHandler(UINT32 uwArg)119 void JsAbilityThread::AppTaskHandler(UINT32 uwArg)
120 {
121 auto messageQueueId = reinterpret_cast<osMessageQueueId_t>(uwArg);
122 if (messageQueueId == nullptr) {
123 return;
124 }
125 AbilityThread *defaultAbilityThread = nullptr;
126
127 for (;;) {
128 SliteAbilityInnerMsg innerMsg;
129 uint8_t prio = 0;
130 osStatus_t ret = osMessageQueueGet(messageQueueId, &innerMsg, &prio, osWaitForever);
131 if (ret != osOK) {
132 return;
133 }
134 AbilityThread *abilityThread = innerMsg.abilityThread;
135 if (abilityThread == nullptr) {
136 if (defaultAbilityThread == nullptr) {
137 continue;
138 }
139 abilityThread = defaultAbilityThread;
140 }
141 LP_TaskBegin();
142 switch (innerMsg.msgId) {
143 case SliteAbilityMsgId::CREATE:
144 defaultAbilityThread = abilityThread;
145 abilityThread->HandleCreate(innerMsg.want);
146 abilityThread->HandleRestore(innerMsg.abilitySavedData);
147 ClearWant(innerMsg.want);
148 AdapterFree(innerMsg.want);
149 innerMsg.want = nullptr;
150 break;
151 case SliteAbilityMsgId::FOREGROUND:
152 abilityThread->HandleForeground(innerMsg.want);
153 ClearWant(innerMsg.want);
154 AdapterFree(innerMsg.want);
155 innerMsg.want = nullptr;
156 break;
157 case SliteAbilityMsgId::BACKGROUND:
158 abilityThread->HandleBackground();
159 break;
160 case SliteAbilityMsgId::DESTROY:
161 abilityThread->HandleSave(innerMsg.abilitySavedData);
162 abilityThread->HandleDestroy();
163 LP_TaskEnd();
164 return; // here exit the loop, and abort all messages afterwards
165 default:
166 if (abilityThread->ability_ != nullptr) {
167 abilityThread->ability_->HandleExtraMessage(innerMsg);
168 }
169 break;
170 }
171 LP_TaskEnd();
172 }
173 }
174 } // namespace AbilitySlite
175 } // namespace OHOS
176