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 "native_ability_thread.h"
17
18 #include <cstring>
19 #include "aafwk_event_error_code.h"
20 #include "ability_errors.h"
21 #include "ability_inner_message.h"
22 #include "ability_record_manager.h"
23 #include "adapter.h"
24 #include "ability_thread.h"
25 #include "abilityms_log.h"
26 #include "los_task.h"
27 #include "slite_ability_loader.h"
28
29 namespace OHOS {
30 namespace AbilitySlite {
31 static char g_NativeAppTask[] = "NativeAppTask";
32 constexpr int32_t APP_TASK_PRI = 25;
33 constexpr int32_t QUEUE_LENGTH = 32;
34
35 osMessageQueueId_t NativeAbilityThread::nativeQueueId_ = nullptr;
36 UINT32 NativeAbilityThread::nativeTaskId_ = UINT32_MAX;
37 SliteAbility *NativeAbilityThread::nativeAbility_ = nullptr;
38
39 NativeAbilityThread::NativeAbilityThread() = default;
40
~NativeAbilityThread()41 NativeAbilityThread::~NativeAbilityThread()
42 {
43 if (ability_ == nullptr) {
44 return;
45 }
46 #ifdef _MINI_MULTI_TASKS_
47 delete ability_;
48 ability_ = nullptr;
49 #else
50 if ((ability_->bundleName_ == nullptr) || (strcmp(ability_->bundleName_, LAUNCHER_BUNDLE_NAME) != 0)) {
51 delete ability_;
52 ability_ = nullptr;
53 }
54 #endif
55 }
56
InitAbilityThread(const AbilityRecord * abilityRecord)57 int32_t NativeAbilityThread::InitAbilityThread(const AbilityRecord *abilityRecord)
58 {
59 if (abilityRecord == nullptr) {
60 HILOG_ERROR(HILOG_MODULE_AAFWK, "NativeAbilityThread init fail, abilityRecord is null");
61 return PARAM_NULL_ERROR;
62 }
63 if (abilityRecord->appName == nullptr) {
64 HILOG_ERROR(HILOG_MODULE_AAFWK, "NativeAbilityThread init fail, appName is null");
65 return PARAM_NULL_ERROR;
66 }
67 if (state_ != AbilityThreadState::ABILITY_THREAD_UNINITIALIZED) {
68 HILOG_ERROR(HILOG_MODULE_AAFWK, "NativeAbilityThread init fail, the AbilityThread is already inited");
69 return PARAM_CHECK_ERROR;
70 }
71
72 if (nativeQueueId_ == nullptr) {
73 nativeQueueId_ = osMessageQueueNew(QUEUE_LENGTH, sizeof(SliteAbilityInnerMsg), nullptr);
74 }
75 if (nativeQueueId_ == nullptr) {
76 HILOG_ERROR(HILOG_MODULE_AAFWK, "NativeAbilityThread init fail: messageQueueId is null");
77 return MEMORY_MALLOC_ERROR;
78 }
79
80 HILOG_INFO(HILOG_MODULE_AAFWK, "CreateAppTask.");
81 if (nativeTaskId_ == UINT32_MAX) {
82 TSK_INIT_PARAM_S stTskInitParam = { 0 };
83 LOS_TaskLock();
84 stTskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC) (NativeAbilityThread::NativeAppTaskHandler);
85 stTskInitParam.uwStackSize = NATIVE_TASK_STACK_SIZE;
86 stTskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST - APP_TASK_PRI;
87 stTskInitParam.pcName = g_NativeAppTask;
88 stTskInitParam.uwResved = 0;
89 stTskInitParam.uwArg = reinterpret_cast<UINT32>((uintptr_t) nativeQueueId_);
90 uint32_t ret = LOS_TaskCreate(&nativeTaskId_, &stTskInitParam);
91 if (ret != LOS_OK) {
92 HILOG_ERROR(HILOG_MODULE_AAFWK, "NativeAbilityThread init fail: LOS_TaskCreate ret %{public}d", ret);
93 osMessageQueueDelete(nativeQueueId_);
94 LOS_TaskUnlock();
95 return CREATE_APPTASK_ERROR;
96 }
97 }
98
99 state_ = AbilityThreadState::ABILITY_THREAD_INITIALIZED;
100 #ifdef _MINI_MULTI_TASKS_
101 ability_ = SliteAbilityLoader::GetInstance().CreateAbility(SliteAbilityType::NATIVE_ABILITY,
102 abilityRecord->appName);
103 #else
104 if (strcmp(abilityRecord->appName, LAUNCHER_BUNDLE_NAME) == 0) {
105 if (nativeAbility_ == nullptr) {
106 nativeAbility_ = SliteAbilityLoader::GetInstance().CreateAbility(SliteAbilityType::NATIVE_ABILITY,
107 abilityRecord->appName);
108 }
109 ability_ = nativeAbility_;
110 } else {
111 ability_ = SliteAbilityLoader::GetInstance().CreateAbility(SliteAbilityType::NATIVE_ABILITY,
112 abilityRecord->appName);
113 }
114 #endif
115 if (ability_ == nullptr) {
116 HILOG_INFO(HILOG_MODULE_AAFWK, "NativeAbility create fail");
117 LOS_TaskUnlock();
118 return MEMORY_MALLOC_ERROR;
119 }
120 ability_->SetToken(abilityRecord->token);
121 LOS_TaskUnlock();
122 HILOG_INFO(HILOG_MODULE_AAFWK, "NativeAbilityThread init done");
123 return ERR_OK;
124 }
125
ReleaseAbilityThread()126 int32_t NativeAbilityThread::ReleaseAbilityThread()
127 {
128 if (state_ != AbilityThreadState::ABILITY_THREAD_INITIALIZED) {
129 HILOG_ERROR(HILOG_MODULE_AAFWK, "NativeAbilityThread release fail, the AbilityThread is not inited");
130 return PARAM_CHECK_ERROR;
131 }
132 return ERR_OK;
133 }
134
GetMessageQueueId() const135 osMessageQueueId_t NativeAbilityThread::GetMessageQueueId() const
136 {
137 return nativeQueueId_;
138 }
139
GetAppTaskId() const140 UINT32 NativeAbilityThread::GetAppTaskId() const
141 {
142 return nativeTaskId_;
143 }
144
Reset()145 void NativeAbilityThread::Reset()
146 {
147 if (nativeQueueId_ != nullptr) {
148 osMessageQueueDelete(nativeQueueId_);
149 }
150 nativeQueueId_ = nullptr;
151 nativeTaskId_ = 0;
152 nativeAbility_ = nullptr;
153 }
154
NativeAppTaskHandler(UINT32 uwArg)155 void NativeAbilityThread::NativeAppTaskHandler(UINT32 uwArg)
156 {
157 auto messageQueueId = reinterpret_cast<osMessageQueueId_t>(uwArg);
158 if (messageQueueId == nullptr) {
159 return;
160 }
161 AbilityThread *defaultAbilityThread = nullptr;
162
163 for (;;) {
164 SliteAbilityInnerMsg innerMsg;
165 uint8_t prio = 0;
166 osStatus_t ret = osMessageQueueGet(messageQueueId, &innerMsg, &prio, osWaitForever);
167 if (ret != osOK) {
168 return;
169 }
170 AbilityThread *abilityThread = innerMsg.abilityThread;
171 if (abilityThread == nullptr) {
172 if (defaultAbilityThread == nullptr) {
173 continue;
174 }
175 abilityThread = defaultAbilityThread;
176 }
177 LP_TaskBegin();
178 switch (innerMsg.msgId) {
179 case SliteAbilityMsgId::CREATE:
180 defaultAbilityThread = abilityThread;
181 abilityThread->HandleCreate(innerMsg.want);
182 abilityThread->HandleRestore(innerMsg.abilitySavedData);
183 ClearWant(innerMsg.want);
184 AdapterFree(innerMsg.want);
185 innerMsg.want = nullptr;
186 break;
187 case SliteAbilityMsgId::FOREGROUND:
188 abilityThread->HandleForeground(innerMsg.want);
189 ClearWant(innerMsg.want);
190 AdapterFree(innerMsg.want);
191 innerMsg.want = nullptr;
192 break;
193 case SliteAbilityMsgId::BACKGROUND:
194 abilityThread->HandleBackground();
195 break;
196 case SliteAbilityMsgId::DESTROY:
197 abilityThread->HandleSave(innerMsg.abilitySavedData);
198 abilityThread->HandleDestroy();
199 break; // this task will be kept alive
200 default:
201 if (abilityThread->ability_ != nullptr) {
202 abilityThread->ability_->HandleExtraMessage(innerMsg);
203 }
204 break;
205 }
206 LP_TaskEnd();
207 }
208 }
209 } // namespace AbilitySlite
210 } // namespace OHOS
211