• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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