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
16 #include "ability.h"
17
18 #include <ability_kit_command.h>
19 #include <ability_state.h>
20 #include <log.h>
21 #include <unistd.h>
22
23 #include "ability_info.h"
24 #include "ability_loader.h"
25 #ifdef ABILITY_WINDOW_SUPPORT
26 #include "ability_slice_manager.h"
27 #include "ability_window.h"
28 #endif
29 #include "adapter.h"
30 #include "liteipc_adapter.h"
31
32 namespace OHOS {
OnStart(const Want & want)33 void Ability::OnStart(const Want &want)
34 {
35 HILOG_INFO(HILOG_MODULE_APP, "Ability OnStart");
36 if (abilityState_ != STATE_INITIAL) {
37 HILOG_ERROR(HILOG_MODULE_APP, "Start ability error, state: %{public}d", abilityState_);
38 exit(-1);
39 }
40
41 #ifdef ABILITY_WINDOW_SUPPORT
42 DeliverAbilityLifecycle(START, &want);
43 if (abilityWindow_ != nullptr) {
44 abilityWindow_->OnPostAbilityStart();
45 }
46 #endif
47 abilityState_ = STATE_INACTIVE;
48 }
49
OnInactive()50 void Ability::OnInactive()
51 {
52 HILOG_INFO(HILOG_MODULE_APP, "Ability OnInactive");
53 if (abilityState_ != STATE_ACTIVE) {
54 HILOG_ERROR(HILOG_MODULE_APP, "Inactive ability error, state: %{public}d", abilityState_);
55 exit(-1);
56 }
57
58 #ifdef ABILITY_WINDOW_SUPPORT
59 DeliverAbilityLifecycle(INACTIVE);
60 #endif
61 abilityState_ = STATE_INACTIVE;
62 }
63
OnActive(const Want & want)64 void Ability::OnActive(const Want &want)
65 {
66 HILOG_INFO(HILOG_MODULE_APP, "Ability OnActive");
67 if ((abilityState_ != STATE_INACTIVE) && (abilityState_ != STATE_BACKGROUND)) {
68 HILOG_ERROR(HILOG_MODULE_APP, "Active ability error, state: %{public}d", abilityState_);
69 exit(-1);
70 }
71
72 #ifdef ABILITY_WINDOW_SUPPORT
73 DeliverAbilityLifecycle(ACTIVE, &want);
74 if ((abilityWindow_ != nullptr) && (abilityState_ == STATE_BACKGROUND)) {
75 abilityWindow_->OnPostAbilityActive();
76 }
77 #endif
78 abilityState_ = STATE_ACTIVE;
79 }
80
OnBackground()81 void Ability::OnBackground()
82 {
83 HILOG_INFO(HILOG_MODULE_APP, "Ability OnBackground");
84 if (abilityState_ != STATE_INACTIVE) {
85 HILOG_ERROR(HILOG_MODULE_APP, "Background ability error, state: %{public}d", abilityState_);
86 exit(-1);
87 }
88
89 #ifdef ABILITY_WINDOW_SUPPORT
90 DeliverAbilityLifecycle(BACKGROUND);
91 if (abilityWindow_ != nullptr) {
92 abilityWindow_->OnPostAbilityBackground();
93 }
94 #endif
95 abilityState_ = STATE_BACKGROUND;
96 }
97
OnStop()98 void Ability::OnStop()
99 {
100 HILOG_INFO(HILOG_MODULE_APP, "Ability OnStop");
101 if (abilityState_ != STATE_BACKGROUND) {
102 HILOG_ERROR(HILOG_MODULE_APP, "Stop ability error, state: %{public}d", abilityState_);
103 exit(-1);
104 }
105
106 #ifdef ABILITY_WINDOW_SUPPORT
107 DeliverAbilityLifecycle(STOP);
108 if (abilityWindow_ != nullptr) {
109 abilityWindow_->OnPostAbilityStop();
110 delete abilityWindow_;
111 }
112 delete abilitySliceManager_;
113 abilitySliceManager_ = nullptr;
114 abilityWindow_ = nullptr;
115 #endif
116 abilityState_ = STATE_INITIAL;
117 }
118
OnConnect(const Want & want)119 const SvcIdentity *Ability::OnConnect(const Want &want)
120 {
121 HILOG_INFO(HILOG_MODULE_APP, "Ability Connect");
122 sid_ = static_cast<SvcIdentity *>(AdapterMalloc(sizeof(SvcIdentity)));
123 if (sid_ == nullptr) {
124 HILOG_ERROR(HILOG_MODULE_APP, "malloc memory error, sid_ is null");
125 return nullptr;
126 }
127 int32_t ret = RegisterIpcCallback(Ability::MsgHandleInner, 0, IPC_WAIT_FOREVER, sid_, this);
128 if (ret != 0) {
129 HILOG_ERROR(HILOG_MODULE_APP, "register ipc callback error, ret is %{public}d", ret);
130 AdapterFree(sid_);
131 sid_ = nullptr;
132 return nullptr;
133 }
134 return sid_;
135 }
136
OnDisconnect(const Want & want)137 void Ability::OnDisconnect(const Want &want)
138 {
139 HILOG_INFO(HILOG_MODULE_APP, "Ability OnDisconnect");
140
141 // clear
142 UnregisterIpcCallback(*sid_);
143 AdapterFree(sid_);
144 sid_ = nullptr;
145 }
146
147 #ifdef ABILITY_WINDOW_SUPPORT
SetMainRoute(const std::string & entry)148 void Ability::SetMainRoute(const std::string &entry)
149 {
150 if (abilitySliceManager_ == nullptr) {
151 HILOG_ERROR(HILOG_MODULE_APP, "AbilitySliceManager is null, fail to set main route");
152 exit(-1);
153 }
154
155 abilitySliceManager_->SetMainRoute(entry);
156 }
157
SetUIContent(RootView * rootView)158 void Ability::SetUIContent(RootView *rootView)
159 {
160 if (abilityWindow_ == nullptr) {
161 HILOG_ERROR(HILOG_MODULE_APP, "AbilityWindow is null, fail to SetUIContent");
162 exit(-1);
163 }
164
165 abilityWindow_->SetRootView(rootView);
166 }
167 #endif
168
MsgHandle(uint32_t funcId,IpcIo * request,IpcIo * reply)169 void Ability::MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply)
170 {
171 }
172
Dump(const std::string & extra)173 void Ability::Dump(const std::string &extra)
174 {
175 }
176
Init(uint64_t token,int abilityType,bool isNativeApp)177 void Ability::Init(uint64_t token, int abilityType, bool isNativeApp)
178 {
179 HILOG_INFO(HILOG_MODULE_APP, "Ability Init");
180 #ifdef ABILITY_WINDOW_SUPPORT
181 if (abilityType == PAGE) {
182 if (isNativeApp) {
183 abilitySliceManager_ = new AbilitySliceManager(*this);
184 }
185 abilityWindow_ = new AbilityWindow();
186 }
187 #endif
188
189 abilityType_ = abilityType;
190 token_ = token;
191 AbilityContext::token_ = token;
192 abilityState_ = STATE_INITIAL;
193 }
194
GetState() const195 int Ability::GetState() const
196 {
197 return abilityState_;
198 }
199
GetDumpInfo() const200 std::string Ability::GetDumpInfo() const
201 {
202 std::string dumpInfo;
203 dumpInfo += "Ability Type: [" + std::to_string(abilityType_) + "]\n";
204 dumpInfo += "Ability State: [" + std::to_string(abilityState_) + "]\n";
205 #ifdef ABILITY_WINDOW_SUPPORT
206 dumpInfo += "AbilitySlice stack:\n";
207 if ((abilityType_ == PAGE) && (abilitySliceManager_ != nullptr)) {
208 // Add slice stack information
209 dumpInfo += abilitySliceManager_->GetSliceStackInfo();
210 } else {
211 dumpInfo += " none";
212 }
213 #endif
214
215 return dumpInfo;
216 }
217
218 #ifdef ABILITY_WINDOW_SUPPORT
DeliverAbilityLifecycle(Action action,const Want * want)219 void Ability::DeliverAbilityLifecycle(Action action, const Want *want)
220 {
221 if (abilitySliceManager_ == nullptr) {
222 HILOG_WARN(HILOG_MODULE_APP, "AbilitySliceManager is null, no need to dispatch lifecycle state change");
223 return;
224 }
225
226 if ((action == START || action == ACTIVE) && want == nullptr) {
227 HILOG_ERROR(HILOG_MODULE_APP, "want is null");
228 return;
229 }
230
231 switch (action) {
232 case START:
233 abilitySliceManager_->OnAbilityStart(*want);
234 break;
235 case INACTIVE:
236 abilitySliceManager_->OnAbilityInactive();
237 break;
238 case ACTIVE:
239 abilitySliceManager_->OnAbilityActive(*want);
240 break;
241 case BACKGROUND:
242 abilitySliceManager_->OnAbilityBackground();
243 break;
244 case STOP:
245 abilitySliceManager_->OnAbilityStop();
246 break;
247 default:
248 HILOG_ERROR(HILOG_MODULE_APP, "action is error");
249 break;
250 }
251 }
252 #endif
253
MsgHandleInner(const IpcContext * context,void * ipcMsg,IpcIo * data,void * arg)254 int32_t Ability::MsgHandleInner(const IpcContext* context, void *ipcMsg, IpcIo *data, void *arg)
255 {
256 auto ability = static_cast<Ability *>(arg);
257 if (ability == nullptr) {
258 HILOG_INFO(HILOG_MODULE_APP, "handle message error, ability is null");
259 FreeBuffer(nullptr, ipcMsg);
260 return LITEIPC_EINVAL;
261 }
262 uint32_t fundId = 0;
263 int32_t ret = GetCode(ipcMsg, &fundId);
264 if (ret == LITEIPC_EINVAL) {
265 FreeBuffer(nullptr, ipcMsg);
266 return LITEIPC_EINVAL;
267 }
268
269 IpcIo reply;
270 char buffer[IPC_IO_DATA_MAX];
271 IpcIoInit(&reply, buffer, IPC_IO_DATA_MAX, MAX_OBJECTS);
272
273 // call user method
274 ability->MsgHandle(fundId, data, &reply);
275
276 uint32_t flag = 0;
277 GetFlag(ipcMsg, &flag);
278 if (flag == LITEIPC_FLAG_DEFAULT) {
279 SendReply(nullptr, ipcMsg, &reply);
280 } else {
281 FreeBuffer(nullptr, ipcMsg);
282 }
283 return LITEIPC_OK;
284 }
285 } // namespace OHOS
286