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