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