• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     int64_t begin = GetTickCount();
182     {
183         std::string onStartTag = ToString(saId_) + "_OnStart";
184         HitraceScopedEx samgrHitrace(HITRACE_LEVEL_INFO, HITRACE_TAG_SAMGR, onStartTag.c_str());
185         OnStart(onDemandStartReason);
186     }
187     int64_t duration = GetTickCount() - begin;
188     KHILOGI(TAG, "OnStart-SA:%{public}d finished, spend:%{public}" PRId64 " ms",
189         saId_, duration);
190     ReportSaLoadDuration(saId_, SA_LOAD_ON_START, duration);
191     std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
192     isRunning_ = true;
193 }
194 
Idle(SystemAbilityOnDemandReason & idleReason,int32_t & delayTime)195 void SystemAbility::Idle(SystemAbilityOnDemandReason& idleReason,
196     int32_t& delayTime)
197 {
198     {
199         std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
200         if (abilityState_ != SystemAbilityState::ACTIVE) {
201             LOGW("cannot Idle SA:%{public}d,sta is %{public}d", saId_, abilityState_);
202             return;
203         }
204     }
205     GetOnDemandReasonExtraData(idleReason);
206     LOGI("Idle-SA:%{public}d", saId_);
207     int64_t begin = GetTickCount();
208     {
209         SamgrXCollie samgrXCollie("safwk--onIdle_" + ToString(saId_));
210         delayTime = OnIdle(idleReason);
211     }
212     LOGI("OnIdle-SA:%{public}d end,spend:%{public}" PRId64 "ms",
213         saId_, (GetTickCount() - begin));
214     std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
215     if (delayTime == 0) {
216         abilityState_ = SystemAbilityState::IDLE;
217     }
218 }
219 
Active(SystemAbilityOnDemandReason & activeReason)220 void SystemAbility::Active(SystemAbilityOnDemandReason& activeReason)
221 {
222     {
223         std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
224         if (abilityState_ != SystemAbilityState::IDLE) {
225             LOGW("cannot Active SA:%{public}d,sta is %{public}d", saId_, abilityState_);
226             return;
227         }
228     }
229     GetOnDemandReasonExtraData(activeReason);
230     LOGI("Active-SA:%{public}d", saId_);
231     int64_t begin = GetTickCount();
232     {
233         SamgrXCollie samgrXCollie("safwk--onActive_" + ToString(saId_));
234         OnActive(activeReason);
235     }
236     LOGI("OnActive-SA:%{public}d end,spend:%{public}" PRId64 "ms",
237         saId_, (GetTickCount() - begin));
238     std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
239     abilityState_ = SystemAbilityState::ACTIVE;
240 }
241 
Stop()242 void SystemAbility::Stop()
243 {
244     HILOGD(TAG, "stopping system ability...");
245     {
246         std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
247         if (abilityState_ == SystemAbilityState::NOT_LOADED) {
248             LOGW("cannot Stop SA:%{public}d,sta is %{public}d", saId_, abilityState_);
249             return;
250         }
251     }
252     nlohmann::json stopReason = LocalAbilityManager::GetInstance().GetStopReason(saId_);
253     SystemAbilityOnDemandReason onDemandStopReason =
254         LocalAbilityManager::GetInstance().JsonToOnDemandReason(stopReason);
255     GetOnDemandReasonExtraData(onDemandStopReason);
256 
257     LOGI("Stop-SA:%{public}d", saId_);
258     int64_t begin = GetTickCount();
259     {
260         SamgrXCollie samgrXCollie("safwk--onStop_" + ToString(saId_));
261         OnStop(onDemandStopReason);
262     }
263     int64_t duration = GetTickCount() - begin;
264     KHILOGI(TAG, "OnStop-SA:%{public}d finished,spend:%{public}" PRId64 "ms",
265         saId_, duration);
266     ReportSaUnLoadDuration(saId_, SA_UNLOAD_ON_STOP, duration);
267 
268     std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
269     abilityState_ = SystemAbilityState::NOT_LOADED;
270     isRunning_ = false;
271     sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
272     if (samgrProxy == nullptr) {
273         HILOGE(TAG, "failed to get samgrProxy");
274         return;
275     }
276     begin = GetTickCount();
277     int32_t ret = samgrProxy->RemoveSystemAbility(saId_);
278     KHILOGI(TAG, "%{public}s to rm SA:%{public}d,spend:%{public}" PRId64 "ms",
279         (ret == ERR_OK) ? "suc" : "fail", saId_, (GetTickCount() - begin));
280 }
281 
SADump()282 void SystemAbility::SADump()
283 {
284     OnDump();
285 }
286 
GetSystemAbilitId() const287 int32_t SystemAbility::GetSystemAbilitId() const
288 {
289     return saId_;
290 }
291 
SetLibPath(const std::string & libPath)292 void SystemAbility::SetLibPath(const std::string& libPath)
293 {
294     libPath_ = libPath;
295 }
296 
GetLibPath() const297 const std::string& SystemAbility::GetLibPath() const
298 {
299     return libPath_;
300 }
301 
SetDependSa(const std::vector<std::int32_t> & dependSa)302 void SystemAbility::SetDependSa(const std::vector<std::int32_t>& dependSa)
303 {
304     dependSa_ = dependSa;
305 }
306 
GetDependSa() const307 const std::vector<std::int32_t>& SystemAbility::GetDependSa() const
308 {
309     return dependSa_;
310 }
311 
SetRunOnCreate(bool isRunOnCreate)312 void SystemAbility::SetRunOnCreate(bool isRunOnCreate)
313 {
314     isRunOnCreate_ = isRunOnCreate;
315 }
316 
IsRunOnCreate() const317 bool SystemAbility::IsRunOnCreate() const
318 {
319     return isRunOnCreate_;
320 }
321 
SetDistributed(bool isDistributed)322 void SystemAbility::SetDistributed(bool isDistributed)
323 {
324     isDistributed_ = isDistributed;
325 }
326 
GetDistributed() const327 bool SystemAbility::GetDistributed() const
328 {
329     return isDistributed_;
330 }
331 
GetRunningStatus() const332 bool SystemAbility::GetRunningStatus() const
333 {
334     return isRunning_;
335 }
336 
GetAbilityState()337 SystemAbilityState SystemAbility::GetAbilityState()
338 {
339     std::lock_guard<std::recursive_mutex> autoLock(abilityLock);
340     return abilityState_;
341 }
342 
SetDumpLevel(uint32_t dumpLevel)343 void SystemAbility::SetDumpLevel(uint32_t dumpLevel)
344 {
345     dumpLevel_ = dumpLevel;
346 }
347 
GetDumpLevel() const348 uint32_t SystemAbility::GetDumpLevel() const
349 {
350     return dumpLevel_;
351 }
352 
SetDependTimeout(int32_t dependTimeout)353 void SystemAbility::SetDependTimeout(int32_t dependTimeout)
354 {
355     if (dependTimeout >= MIN_DEPENDENCY_TIMEOUT && dependTimeout <= MAX_DEPENDENCY_TIMEOUT) {
356         dependTimeout_ = dependTimeout;
357     }
358     LOGD("SetDependTimeout new:%{public}d,old:%{public}d", dependTimeout, dependTimeout_);
359 }
360 
GetDependTimeout() const361 int32_t SystemAbility::GetDependTimeout() const
362 {
363     return dependTimeout_;
364 }
365 
366 // The details should be implemented by subclass
OnDump()367 void SystemAbility::OnDump()
368 {
369 }
370 
371 // The details should be implemented by subclass
OnStart()372 void SystemAbility::OnStart()
373 {
374 }
375 
376 // The details should be implemented by subclass
OnStart(const SystemAbilityOnDemandReason & startReason)377 void SystemAbility::OnStart(const SystemAbilityOnDemandReason& startReason)
378 {
379     OnStart();
380 }
381 
OnIdle(const SystemAbilityOnDemandReason & idleReason)382 int32_t SystemAbility::OnIdle(const SystemAbilityOnDemandReason& idleReason)
383 {
384     LOGD("OnIdle SA, idle reason %{public}d, %{public}s, %{public}s",
385         idleReason.GetId(), idleReason.GetName().c_str(), idleReason.GetValue().c_str());
386     return 0;
387 }
388 
OnActive(const SystemAbilityOnDemandReason & activeReason)389 void SystemAbility::OnActive(const SystemAbilityOnDemandReason& activeReason)
390 {
391     LOGD("OnActive SA, active reason %{public}d, %{public}s, %{public}s",
392         activeReason.GetId(), activeReason.GetName().c_str(), activeReason.GetValue().c_str());
393 }
394 
395 // The details should be implemented by subclass
OnStop()396 void SystemAbility::OnStop()
397 {
398 }
399 
400 // The details should be implemented by subclass
OnStop(const SystemAbilityOnDemandReason & stopReason)401 void SystemAbility::OnStop(const SystemAbilityOnDemandReason& stopReason)
402 {
403     OnStop();
404 }
405 
406 // The details should be implemented by subclass
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)407 void SystemAbility::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
408 {
409 }
410 
411 // The details should be implemented by subclass
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)412 void SystemAbility::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
413 {
414 }
415 
416 // The details should be implemented by subclass
OnSvcCmd(int32_t fd,const std::vector<std::u16string> & args)417 int32_t SystemAbility::OnSvcCmd(int32_t fd, const std::vector<std::u16string>& args)
418 {
419     HILOGI(TAG, "SystemAbility OnSvcCmd start.");
420     return -1;
421 }
422 
GetSystemAbility(int32_t systemAbilityId)423 sptr<IRemoteObject> SystemAbility::GetSystemAbility(int32_t systemAbilityId)
424 {
425     sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
426     if (samgrProxy == nullptr) {
427         HILOGE(TAG, "failed to get samgrProxy");
428         return nullptr;
429     }
430 
431     return samgrProxy->GetSystemAbility(systemAbilityId);
432 }
433 
SetCapability(const std::u16string & capability)434 void SystemAbility::SetCapability(const std::u16string& capability)
435 {
436     capability_ = capability;
437 }
438 
GetCapability() const439 const std::u16string& SystemAbility::GetCapability() const
440 {
441     return capability_;
442 }
443 
SetPermission(const std::u16string & permission)444 void SystemAbility::SetPermission(const std::u16string& permission)
445 {
446     permission_ = permission;
447 }
448 
449 // The details should be implemented by subclass
OnDeviceLevelChanged(int32_t type,int32_t level,std::string & action)450 void SystemAbility::OnDeviceLevelChanged(int32_t type, int32_t level, std::string& action)
451 {
452 }
453 
OnExtension(const std::string & extension,MessageParcel & data,MessageParcel & reply)454 int32_t SystemAbility::OnExtension(const std::string& extension, MessageParcel& data, MessageParcel& reply)
455 {
456     return 0;
457 }
458 
GetAbilityRemoteObject()459 sptr<IRemoteObject> SystemAbility::GetAbilityRemoteObject()
460 {
461     return publishObj_;
462 }
463 }
464