1 /*
2 * Copyright (c) 2021 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 "system_ability.h"
17
18 #include <cinttypes>
19
20 #include "datetime_ex.h"
21 #include "errors.h"
22 #include "hitrace_meter.h"
23 #include "if_system_ability_manager.h"
24 #include "hisysevent_adapter.h"
25 #include "iservice_registry.h"
26 #include "local_ability_manager.h"
27 #include "nlohmann/json.hpp"
28 #include "safwk_log.h"
29 #include "string_ex.h"
30 #include "samgr_xcollie.h"
31
32 namespace OHOS {
33
SystemAbility(bool runOnCreate)34 SystemAbility::SystemAbility(bool runOnCreate)
35 {
36 isRunning_ = false;
37 abilityState_ = SystemAbilityState::NOT_LOADED;
38 isRunOnCreate_ = runOnCreate;
39 isDistributed_ = false;
40 dumpLevel_ = 0;
41 // timeout for waiting dependency ready, which configed in json, with DEFAULT_DEPENDENCY_TIMEOUT(6s) by default
42 dependTimeout_ = DEFAULT_DEPENDENCY_TIMEOUT;
43 capability_ = u"";
44 }
45
SystemAbility(int32_t systemAbilityId,bool runOnCreate)46 SystemAbility::SystemAbility(int32_t systemAbilityId, bool runOnCreate) : SystemAbility(runOnCreate)
47 {
48 saId_ = systemAbilityId;
49 }
50
~SystemAbility()51 SystemAbility::~SystemAbility()
52 {
53 HILOGI(TAG, "SA:%{public}d destroyed", saId_);
54 }
55
MakeAndRegisterAbility(SystemAbility * systemAbility)56 bool SystemAbility::MakeAndRegisterAbility(SystemAbility* systemAbility)
57 {
58 HILOGD(TAG, "registering system ability...");
59 return LocalAbilityManager::GetInstance().AddAbility(systemAbility);
60 }
61
AddSystemAbilityListener(int32_t systemAbilityId)62 bool SystemAbility::AddSystemAbilityListener(int32_t systemAbilityId)
63 {
64 HILOGD(TAG, "SA:%{public}d, listenerSA:%{public}d", systemAbilityId, saId_);
65 return LocalAbilityManager::GetInstance().AddSystemAbilityListener(systemAbilityId, saId_);
66 }
67
RemoveSystemAbilityListener(int32_t systemAbilityId)68 bool SystemAbility::RemoveSystemAbilityListener(int32_t systemAbilityId)
69 {
70 HILOGD(TAG, "SA:%{public}d, listenerSA:%{public}d", systemAbilityId, saId_);
71 return LocalAbilityManager::GetInstance().RemoveSystemAbilityListener(systemAbilityId, saId_);
72 }
73
Publish(sptr<IRemoteObject> systemAbility)74 bool SystemAbility::Publish(sptr<IRemoteObject> systemAbility)
75 {
76 if (systemAbility == nullptr) {
77 HILOGE(TAG, "systemAbility is nullptr");
78 return false;
79 }
80 LOGD("Publish SA:%{public}d", saId_);
81 // Avoid automatic destruction of system ability caused by failure of publishing ability
82 publishObj_ = systemAbility;
83 int64_t begin = GetTickCount();
84 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
85 if (samgrProxy == nullptr) {
86 HILOGE(TAG, "failed to get samgrProxy");
87 return false;
88 }
89
90 ISystemAbilityManager::SAExtraProp saExtra(GetDistributed(), GetDumpLevel(), capability_, permission_);
91 std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
92 int32_t result = samgrProxy->AddSystemAbility(saId_, publishObj_, saExtra);
93 KHILOGI(TAG, "SA:%{public}d result:%{public}d,spend:%{public}" PRId64 "ms",
94 saId_, result, (GetTickCount() - begin));
95 if (result == ERR_OK) {
96 abilityState_ = SystemAbilityState::ACTIVE;
97 return true;
98 }
99 return false;
100 }
101
CancelIdle()102 bool SystemAbility::CancelIdle()
103 {
104 {
105 std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
106 if (abilityState_ != SystemAbilityState::IDLE) {
107 LOGD("cannot CancelIdle SA:%{public}d,sta is %{public}d", saId_, abilityState_);
108 return true;
109 }
110 }
111 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
112 if (samgrProxy == nullptr) {
113 HILOGE(TAG, "failed to get samgrProxy");
114 return false;
115 }
116 LOGI("CancelIdle-SA:%{public}d", saId_);
117 int32_t result = samgrProxy->CancelUnloadSystemAbility(saId_);
118 return result == ERR_OK;
119 }
120
StopAbility(int32_t systemAbilityId)121 void SystemAbility::StopAbility(int32_t systemAbilityId)
122 {
123 HILOGD(TAG, "SA:%{public}d", systemAbilityId);
124
125 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
126 if (samgrProxy == nullptr) {
127 HILOGE(TAG, "failed to get samgrProxy");
128 return;
129 }
130 int64_t begin = GetTickCount();
131 int32_t ret = samgrProxy->RemoveSystemAbility(systemAbilityId);
132 KHILOGI(TAG, "%{public}s to rm SA:%{public}d, spend:%{public}" PRId64 " ms",
133 (ret == ERR_OK) ? "success" : "failed", systemAbilityId, (GetTickCount() - begin));
134 }
135
GetOnDemandReasonExtraData(SystemAbilityOnDemandReason & onDemandStartReason)136 void SystemAbility::GetOnDemandReasonExtraData(SystemAbilityOnDemandReason& onDemandStartReason)
137 {
138 if (!onDemandStartReason.HasExtraData()) {
139 return;
140 }
141 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
142 if (samgrProxy == nullptr) {
143 HILOGE(TAG, "failed to get samgrProxy");
144 return;
145 }
146 LOGI("get extra id: %{public}d", static_cast<int32_t>(onDemandStartReason.GetExtraDataId()));
147 MessageParcel extraDataParcel;
148 int32_t ret = samgrProxy->GetOnDemandReasonExtraData(onDemandStartReason.GetExtraDataId(), extraDataParcel);
149 if (ret != ERR_OK) {
150 HILOGE(TAG, "get extra data failed");
151 return;
152 }
153 auto extraData = extraDataParcel.ReadParcelable<OnDemandReasonExtraData>();
154 if (extraData == nullptr) {
155 HILOGE(TAG, "read extra data failed");
156 return;
157 }
158 onDemandStartReason.SetExtraData(*extraData);
159 HILOGD(TAG, "get extra data: %{public}d, %{public}s", onDemandStartReason.GetExtraData().GetCode(),
160 onDemandStartReason.GetExtraData().GetData().c_str());
161 delete extraData;
162 }
163
Start()164 void SystemAbility::Start()
165 {
166 // Ensure that the lifecycle is sequentially called by SAMGR
167 std::lock_guard<std::mutex> lock(onStartLock_);
168 HILOGD(TAG, "starting system ability...");
169 {
170 std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
171 if (abilityState_ != SystemAbilityState::NOT_LOADED) {
172 LOGW("cannot Start SA:%{public}d,sta is %{public}d", saId_, abilityState_);
173 return;
174 }
175 }
176 nlohmann::json startReason = LocalAbilityManager::GetInstance().GetStartReason(saId_);
177 SystemAbilityOnDemandReason onDemandStartReason =
178 LocalAbilityManager::GetInstance().JsonToOnDemandReason(startReason);
179 GetOnDemandReasonExtraData(onDemandStartReason);
180 LOGI("Start-SA:%{public}d", saId_);
181 HITRACE_METER_NAME(HITRACE_TAG_SAMGR, ToString(saId_) + "_OnStart");
182 int64_t begin = GetTickCount();
183
184 OnStart(onDemandStartReason);
185
186 int64_t duration = GetTickCount() - begin;
187 KHILOGI(TAG, "OnStart-SA:%{public}d finished, spend:%{public}" PRId64 " ms",
188 saId_, duration);
189 ReportSaLoadDuration(saId_, SA_LOAD_ON_START, duration);
190 std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
191 isRunning_ = true;
192 }
193
Idle(SystemAbilityOnDemandReason & idleReason,int32_t & delayTime)194 void SystemAbility::Idle(SystemAbilityOnDemandReason& idleReason,
195 int32_t& delayTime)
196 {
197 {
198 std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
199 if (abilityState_ != SystemAbilityState::ACTIVE) {
200 LOGW("cannot Idle SA:%{public}d,sta is %{public}d", saId_, abilityState_);
201 return;
202 }
203 }
204 GetOnDemandReasonExtraData(idleReason);
205 LOGI("Idle-SA:%{public}d", saId_);
206 int64_t begin = GetTickCount();
207 {
208 SamgrXCollie samgrXCollie("safwk--onIdle_" + ToString(saId_));
209 delayTime = OnIdle(idleReason);
210 }
211 LOGI("OnIdle-SA:%{public}d end,spend:%{public}" PRId64 "ms",
212 saId_, (GetTickCount() - begin));
213 std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
214 if (delayTime == 0) {
215 abilityState_ = SystemAbilityState::IDLE;
216 }
217 }
218
Active(SystemAbilityOnDemandReason & activeReason)219 void SystemAbility::Active(SystemAbilityOnDemandReason& activeReason)
220 {
221 {
222 std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
223 if (abilityState_ != SystemAbilityState::IDLE) {
224 LOGW("cannot Active SA:%{public}d,sta is %{public}d", saId_, abilityState_);
225 return;
226 }
227 }
228 GetOnDemandReasonExtraData(activeReason);
229 LOGI("Active-SA:%{public}d", saId_);
230 int64_t begin = GetTickCount();
231 {
232 SamgrXCollie samgrXCollie("safwk--onActive_" + ToString(saId_));
233 OnActive(activeReason);
234 }
235 LOGI("OnActive-SA:%{public}d end,spend:%{public}" PRId64 "ms",
236 saId_, (GetTickCount() - begin));
237 std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
238 abilityState_ = SystemAbilityState::ACTIVE;
239 }
240
Stop()241 void SystemAbility::Stop()
242 {
243 HILOGD(TAG, "stopping system ability...");
244 {
245 std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
246 if (abilityState_ == SystemAbilityState::NOT_LOADED) {
247 LOGW("cannot Stop SA:%{public}d,sta is %{public}d", saId_, abilityState_);
248 return;
249 }
250 }
251 nlohmann::json stopReason = LocalAbilityManager::GetInstance().GetStopReason(saId_);
252 SystemAbilityOnDemandReason onDemandStopReason =
253 LocalAbilityManager::GetInstance().JsonToOnDemandReason(stopReason);
254 GetOnDemandReasonExtraData(onDemandStopReason);
255
256 LOGI("Stop-SA:%{public}d", saId_);
257 int64_t begin = GetTickCount();
258 {
259 SamgrXCollie samgrXCollie("safwk--onStop_" + ToString(saId_));
260 OnStop(onDemandStopReason);
261 }
262 int64_t duration = GetTickCount() - begin;
263 KHILOGI(TAG, "OnStop-SA:%{public}d finished,spend:%{public}" PRId64 "ms",
264 saId_, duration);
265 ReportSaUnLoadDuration(saId_, SA_UNLOAD_ON_STOP, duration);
266
267 std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
268 abilityState_ = SystemAbilityState::NOT_LOADED;
269 isRunning_ = false;
270 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
271 if (samgrProxy == nullptr) {
272 HILOGE(TAG, "failed to get samgrProxy");
273 return;
274 }
275 begin = GetTickCount();
276 int32_t ret = samgrProxy->RemoveSystemAbility(saId_);
277 KHILOGI(TAG, "%{public}s to rm SA:%{public}d,spend:%{public}" PRId64 "ms",
278 (ret == ERR_OK) ? "suc" : "fail", saId_, (GetTickCount() - begin));
279 }
280
SADump()281 void SystemAbility::SADump()
282 {
283 OnDump();
284 }
285
GetSystemAbilitId() const286 int32_t SystemAbility::GetSystemAbilitId() const
287 {
288 return saId_;
289 }
290
SetLibPath(const std::string & libPath)291 void SystemAbility::SetLibPath(const std::string& libPath)
292 {
293 libPath_ = libPath;
294 }
295
GetLibPath() const296 const std::string& SystemAbility::GetLibPath() const
297 {
298 return libPath_;
299 }
300
SetDependSa(const std::vector<std::int32_t> & dependSa)301 void SystemAbility::SetDependSa(const std::vector<std::int32_t>& dependSa)
302 {
303 dependSa_ = dependSa;
304 }
305
GetDependSa() const306 const std::vector<std::int32_t>& SystemAbility::GetDependSa() const
307 {
308 return dependSa_;
309 }
310
SetRunOnCreate(bool isRunOnCreate)311 void SystemAbility::SetRunOnCreate(bool isRunOnCreate)
312 {
313 isRunOnCreate_ = isRunOnCreate;
314 }
315
IsRunOnCreate() const316 bool SystemAbility::IsRunOnCreate() const
317 {
318 return isRunOnCreate_;
319 }
320
SetDistributed(bool isDistributed)321 void SystemAbility::SetDistributed(bool isDistributed)
322 {
323 isDistributed_ = isDistributed;
324 }
325
GetDistributed() const326 bool SystemAbility::GetDistributed() const
327 {
328 return isDistributed_;
329 }
330
GetRunningStatus() const331 bool SystemAbility::GetRunningStatus() const
332 {
333 return isRunning_;
334 }
335
GetAbilityState()336 SystemAbilityState SystemAbility::GetAbilityState()
337 {
338 std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
339 return abilityState_;
340 }
341
SetDumpLevel(uint32_t dumpLevel)342 void SystemAbility::SetDumpLevel(uint32_t dumpLevel)
343 {
344 dumpLevel_ = dumpLevel;
345 }
346
GetDumpLevel() const347 uint32_t SystemAbility::GetDumpLevel() const
348 {
349 return dumpLevel_;
350 }
351
SetDependTimeout(int32_t dependTimeout)352 void SystemAbility::SetDependTimeout(int32_t dependTimeout)
353 {
354 if (dependTimeout >= MIN_DEPENDENCY_TIMEOUT && dependTimeout <= MAX_DEPENDENCY_TIMEOUT) {
355 dependTimeout_ = dependTimeout;
356 }
357 LOGD("SetDependTimeout new:%{public}d,old:%{public}d", dependTimeout, dependTimeout_);
358 }
359
GetDependTimeout() const360 int32_t SystemAbility::GetDependTimeout() const
361 {
362 return dependTimeout_;
363 }
364
365 // The details should be implemented by subclass
OnDump()366 void SystemAbility::OnDump()
367 {
368 }
369
370 // The details should be implemented by subclass
OnStart()371 void SystemAbility::OnStart()
372 {
373 }
374
375 // The details should be implemented by subclass
OnStart(const SystemAbilityOnDemandReason & startReason)376 void SystemAbility::OnStart(const SystemAbilityOnDemandReason& startReason)
377 {
378 OnStart();
379 }
380
OnIdle(const SystemAbilityOnDemandReason & idleReason)381 int32_t SystemAbility::OnIdle(const SystemAbilityOnDemandReason& idleReason)
382 {
383 LOGD("OnIdle SA, idle reason %{public}d, %{public}s, %{public}s",
384 idleReason.GetId(), idleReason.GetName().c_str(), idleReason.GetValue().c_str());
385 return 0;
386 }
387
OnActive(const SystemAbilityOnDemandReason & activeReason)388 void SystemAbility::OnActive(const SystemAbilityOnDemandReason& activeReason)
389 {
390 LOGD("OnActive SA, active reason %{public}d, %{public}s, %{public}s",
391 activeReason.GetId(), activeReason.GetName().c_str(), activeReason.GetValue().c_str());
392 }
393
394 // The details should be implemented by subclass
OnStop()395 void SystemAbility::OnStop()
396 {
397 }
398
399 // The details should be implemented by subclass
OnStop(const SystemAbilityOnDemandReason & stopReason)400 void SystemAbility::OnStop(const SystemAbilityOnDemandReason& stopReason)
401 {
402 OnStop();
403 }
404
405 // The details should be implemented by subclass
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)406 void SystemAbility::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
407 {
408 }
409
410 // The details should be implemented by subclass
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)411 void SystemAbility::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
412 {
413 }
414
415 // The details should be implemented by subclass
OnSvcCmd(int32_t fd,const std::vector<std::u16string> & args)416 int32_t SystemAbility::OnSvcCmd(int32_t fd, const std::vector<std::u16string>& args)
417 {
418 return 0;
419 }
420
GetSystemAbility(int32_t systemAbilityId)421 sptr<IRemoteObject> SystemAbility::GetSystemAbility(int32_t systemAbilityId)
422 {
423 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
424 if (samgrProxy == nullptr) {
425 HILOGE(TAG, "failed to get samgrProxy");
426 return nullptr;
427 }
428
429 return samgrProxy->GetSystemAbility(systemAbilityId);
430 }
431
SetCapability(const std::u16string & capability)432 void SystemAbility::SetCapability(const std::u16string& capability)
433 {
434 capability_ = capability;
435 }
436
GetCapability() const437 const std::u16string& SystemAbility::GetCapability() const
438 {
439 return capability_;
440 }
441
SetPermission(const std::u16string & permission)442 void SystemAbility::SetPermission(const std::u16string& permission)
443 {
444 permission_ = permission;
445 }
446
447 // The details should be implemented by subclass
OnDeviceLevelChanged(int32_t type,int32_t level,std::string & action)448 void SystemAbility::OnDeviceLevelChanged(int32_t type, int32_t level, std::string& action)
449 {
450 }
451
OnExtension(const std::string & extension,MessageParcel & data,MessageParcel & reply)452 int32_t SystemAbility::OnExtension(const std::string& extension, MessageParcel& data, MessageParcel& reply)
453 {
454 return 0;
455 }
456 }
457