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 "location_sa_load_manager.h"
17  
18  #include "if_system_ability_manager.h"
19  #include "iservice_registry.h"
20  #include "system_ability_definition.h"
21  
22  #include "common_utils.h"
23  #include "location_log.h"
24  #include "common_hisysevent.h"
25  #include "location_log_event_ids.h"
26  
27  namespace OHOS {
28  namespace Location {
GetInstance()29  LocationSaLoadManager* LocationSaLoadManager::GetInstance()
30  {
31      static LocationSaLoadManager data;
32      return &data;
33  }
34  
LocationSaLoadManager()35  LocationSaLoadManager::LocationSaLoadManager()
36  {
37  }
38  
~LocationSaLoadManager()39  LocationSaLoadManager::~LocationSaLoadManager()
40  {
41  }
42  
LoadLocationSa(int32_t systemAbilityId)43  LocationErrCode LocationSaLoadManager::LoadLocationSa(int32_t systemAbilityId)
44  {
45      LBSLOGD(LOCATOR, "%{public}s enter, systemAbilityId = [%{public}d] loading", __func__, systemAbilityId);
46      InitLoadState();
47      sptr<ISystemAbilityManager> samgr =
48          SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
49      if (samgr == nullptr) {
50          LBSLOGE(LOCATOR, "%{public}s: get system ability manager failed!", __func__);
51          return ERRCODE_SERVICE_UNAVAILABLE;
52      }
53  
54      auto locationSaLoadCallback = sptr<LocationSaLoadCallback>(new LocationSaLoadCallback());
55      int32_t ret = samgr->LoadSystemAbility(systemAbilityId, locationSaLoadCallback);
56      if (ret != ERR_OK) {
57          LBSLOGE(LOCATOR, "%{public}s: Failed to load system ability, SA Id = [%{public}d], ret = [%{public}d].",
58              __func__, systemAbilityId, ret);
59          return ERRCODE_SERVICE_UNAVAILABLE;
60      }
61      return WaitLoadStateChange(systemAbilityId);
62  }
63  
InitLoadState()64  void LocationSaLoadManager::InitLoadState()
65  {
66      std::unique_lock<std::mutex> lock(locatorMutex_);
67      state_ = false;
68  }
69  
WaitLoadStateChange(int32_t systemAbilityId)70  LocationErrCode LocationSaLoadManager::WaitLoadStateChange(int32_t systemAbilityId)
71  {
72      std::unique_lock<std::mutex> lock(locatorMutex_);
73      auto wait = locatorCon_.wait_for(lock, std::chrono::milliseconds(LOCATION_LOADSA_TIMEOUT_MS), [this] {
74          return state_ == true;
75      });
76      if (!wait) {
77          LBSLOGE(LOCATOR_STANDARD, "locator sa [%{public}d] start time out.", systemAbilityId);
78          return ERRCODE_SERVICE_UNAVAILABLE;
79      }
80      return ERRCODE_SUCCESS;
81  }
82  
UnloadLocationSa(int32_t systemAbilityId)83  LocationErrCode LocationSaLoadManager::UnloadLocationSa(int32_t systemAbilityId)
84  {
85      LBSLOGD(LOCATOR, "%{public}s enter, systemAbilityId = [%{public}d] unloading", __func__, systemAbilityId);
86      sptr<ISystemAbilityManager> samgr =
87          SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
88      if (samgr == nullptr) {
89          LBSLOGE(LOCATOR, "%{public}s: get system ability manager failed!", __func__);
90          return ERRCODE_SERVICE_UNAVAILABLE;
91      }
92      int32_t ret = samgr->UnloadSystemAbility(systemAbilityId);
93      if (ret != ERR_OK) {
94          LBSLOGE(LOCATOR, "%{public}s: Failed to unload system ability, SA Id = [%{public}d], ret = [%{public}d].",
95              __func__, systemAbilityId, ret);
96          return ERRCODE_SERVICE_UNAVAILABLE;
97      }
98      return ERRCODE_SUCCESS;
99  }
100  
LoadSystemAbilitySuccess()101  void LocationSaLoadManager::LoadSystemAbilitySuccess()
102  {
103      std::unique_lock<std::mutex> lock(locatorMutex_);
104      state_ = true;
105      locatorCon_.notify_one();
106  }
107  
LoadSystemAbilityFail()108  void LocationSaLoadManager::LoadSystemAbilityFail()
109  {
110      std::unique_lock<std::mutex> lock(locatorMutex_);
111      state_ = false;
112      locatorCon_.notify_one();
113  }
114  
115  
CheckIfSystemAbilityAvailable(int32_t systemAbilityId)116  bool LocationSaLoadManager::CheckIfSystemAbilityAvailable(int32_t systemAbilityId)
117  {
118      sptr<ISystemAbilityManager> samgr =
119          SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
120      if (samgr == nullptr) {
121          LBSLOGE(COMMON_UTILS, "%{public}s: get system ability manager failed!", __func__);
122          return false;
123      }
124      return (samgr->CheckSystemAbility(systemAbilityId) != nullptr);
125  }
126  
InitLocationSa(int32_t systemAbilityId)127  bool LocationSaLoadManager::InitLocationSa(int32_t systemAbilityId)
128  {
129      if (LocationSaLoadManager::CheckIfSystemAbilityAvailable(systemAbilityId)) {
130          LBSLOGD(COMMON_UTILS, "sa has been loaded");
131          return true;
132      }
133      auto instance = LocationSaLoadManager::GetInstance();
134      if (instance == nullptr || instance->LoadLocationSa(systemAbilityId) != ERRCODE_SUCCESS) {
135          LBSLOGE(LOCATOR, "sa load failed.");
136          return false;
137      }
138      return true;
139  }
140  
UnInitLocationSa(int32_t systemAbilityId)141  bool LocationSaLoadManager::UnInitLocationSa(int32_t systemAbilityId)
142  {
143      if (!LocationSaLoadManager::CheckIfSystemAbilityAvailable(systemAbilityId)) {
144          LBSLOGD(LOCATOR, "sa has been unloaded");
145          return true;
146      }
147      auto instance = LocationSaLoadManager::GetInstance();
148      if (instance == nullptr || instance->UnloadLocationSa(systemAbilityId) != ERRCODE_SUCCESS) {
149          LBSLOGE(LOCATOR, "sa unload failed.");
150          return false;
151      }
152      return true;
153  }
154  
OnLoadSystemAbilitySuccess(int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)155  void LocationSaLoadCallback::OnLoadSystemAbilitySuccess(
156      int32_t systemAbilityId, const sptr<IRemoteObject> &remoteObject)
157  {
158      LBSLOGD(LOCATOR, "LocationSaLoadManager Load SA success, systemAbilityId = [%{public}d]", systemAbilityId);
159      auto instance = LocationSaLoadManager::GetInstance();
160      if (instance == nullptr) {
161          LBSLOGE(LOCATOR, "LocationSaLoadManager GetInstance return null");
162          return;
163      }
164      instance->LoadSystemAbilitySuccess();
165  }
166  
OnLoadSystemAbilityFail(int32_t systemAbilityId)167  void LocationSaLoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId)
168  {
169      LBSLOGD(LOCATOR, "LocationSaLoadManager Load SA failed, systemAbilityId = [%{public}d]", systemAbilityId);
170      auto instance = LocationSaLoadManager::GetInstance();
171      if (instance == nullptr) {
172          LBSLOGE(LOCATOR, "LocationSaLoadManager GetInstance return null");
173          return;
174      }
175      instance->LoadSystemAbilityFail();
176  }
177  }; // namespace Location
178  }; // namespace OHOS
179