1 /*
2  * Copyright (C) 2024 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 /*
17  * Copyright (C) 2024 Huawei Device Co., Ltd.
18  * Licensed under the Apache License, Version 2.0 (the "License");
19  * you may not use this file except in compliance with the License.
20  * You may obtain a copy of the License at
21  *
22  *     http://www.apache.org/licenses/LICENSE-2.0
23  *
24  * Unless required by applicable law or agreed to in writing, software
25  * distributed under the License is distributed on an "AS IS" BASIS,
26  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27  * See the License for the specific language governing permissions and
28  * limitations under the License.
29  */
30 
31 #include "oh_location.h"
32 #include "locator_c_impl.h"
33 
34 #include "locator.h"
35 
36 std::mutex g_locationCallbackVectorMutex;
37 std::vector<OHOS::sptr<OHOS::Location::LocationInfoCallbackHost>> g_locationCallbackVector;
38 auto g_locatorProxy = OHOS::Location::Locator::GetInstance();
39 
OH_Location_IsLocatingEnabled(bool * enabled)40 Location_ResultCode OH_Location_IsLocatingEnabled(bool *enabled)
41 {
42     if (enabled == nullptr) {
43         return LOCATION_INVALID_PARAM;
44     }
45     bool isEnabled = false;
46     auto errCode = g_locatorProxy->IsLocationEnabledV9(isEnabled);
47     if (errCode != OHOS::Location::ERRCODE_SUCCESS) {
48         return LocationErrCodeToLocationResultCode(errCode);
49     }
50     *enabled = isEnabled;
51     return LOCATION_SUCCESS;
52 }
53 
OH_Location_StartLocating(const Location_RequestConfig * requestConfig)54 Location_ResultCode OH_Location_StartLocating(const Location_RequestConfig* requestConfig)
55 {
56     LBSLOGI(OHOS::Location::LOCATION_CAPI, "OH_Location_StartLocating ");
57     if (requestConfig == nullptr) {
58         return LOCATION_INVALID_PARAM;
59     }
60     if (GetLocationCallBack(requestConfig) != nullptr) {
61         LBSLOGE(OHOS::Location::LOCATION_CAPI, "%{public}s callback has registered.", __func__);
62         return LOCATION_INVALID_PARAM;
63     }
64     auto locatorCallbackHost = OHOS::sptr<OHOS::Location::LocationInfoCallbackHost>(
65             new (std::nothrow) OHOS::Location::LocationInfoCallbackHost());
66     locatorCallbackHost->SetRequestConfig(requestConfig);
67     auto locatorCallback = OHOS::sptr<OHOS::Location::ILocatorCallback>(locatorCallbackHost);
68     auto requestConfigV9 = std::make_unique<OHOS::Location::RequestConfig>();
69     if (requestConfig->scenario_ == OHOS::Location::SCENE_UNSET) {
70         requestConfigV9->SetScenario(LOCATION_USE_SCENE_DAILY_LIFE_SERVICE);
71     } else {
72         requestConfigV9->SetScenario(requestConfig->scenario_);
73     }
74     requestConfigV9->SetTimeInterval(requestConfig->timeInterval_);
75     AddLocationCallBack(locatorCallbackHost);
76     auto errCode = g_locatorProxy->StartLocatingV9(requestConfigV9, locatorCallback);
77     if (errCode != OHOS::Location::ERRCODE_SUCCESS) {
78         RemoveLocationCallBack(requestConfig);
79         return LocationErrCodeToLocationResultCode(errCode);
80     }
81     return LOCATION_SUCCESS;
82 }
83 
OH_Location_StopLocating(const Location_RequestConfig * requestConfig)84 Location_ResultCode OH_Location_StopLocating(const Location_RequestConfig* requestConfig)
85 {
86     LBSLOGI(OHOS::Location::LOCATION_CAPI, "OH_Location_StopLocating");
87     if (requestConfig == nullptr) {
88         return LOCATION_INVALID_PARAM;
89     }
90     auto locatorCallbackHost = GetLocationCallBack(requestConfig);
91     if (locatorCallbackHost == nullptr) {
92         LBSLOGE(OHOS::Location::LOCATION_CAPI, "%{public}s locatorCallbackHost is nullptr.", __func__);
93         return LOCATION_INVALID_PARAM;
94     }
95     auto locatorCallback = OHOS::sptr<OHOS::Location::ILocatorCallback>(locatorCallbackHost);
96     auto errCode = g_locatorProxy->StopLocatingV9(locatorCallback);
97     if (errCode != OHOS::Location::ERRCODE_SUCCESS) {
98         return LocationErrCodeToLocationResultCode(errCode);
99     }
100     RemoveLocationCallBack(requestConfig);
101     return LOCATION_SUCCESS;
102 }
103 
OH_LocationInfo_GetBasicInfo(Location_Info * location)104 Location_BasicInfo OH_LocationInfo_GetBasicInfo(Location_Info* location)
105 {
106     Location_BasicInfo location_Basic;
107     memset_s(&location_Basic, sizeof(Location_BasicInfo), 0, sizeof(Location_BasicInfo));
108     if (location == nullptr) {
109         return location_Basic;
110     }
111     location_Basic.latitude = location->latitude;
112     location_Basic.longitude = location->longitude;
113     location_Basic.altitude = location->altitude;
114     location_Basic.accuracy = location->accuracy;
115     location_Basic.speed = location->speed;
116     location_Basic.direction = location->direction;
117     location_Basic.timeForFix = location->timeForFix;
118     location_Basic.timeSinceBoot = location->timeSinceBoot;
119     location_Basic.altitudeAccuracy = location->altitudeAccuracy;
120     location_Basic.speedAccuracy = location->speedAccuracy;
121     location_Basic.directionAccuracy = location->directionAccuracy;
122     location_Basic.uncertaintyOfTimeSinceBoot = location->uncertaintyOfTimeSinceBoot;
123     location_Basic.locationSourceType = location->locationSourceType;
124     return location_Basic;
125 }
126 
OH_LocationInfo_GetAdditionalInfo(Location_Info * location,char * additionalInfo,uint32_t length)127 Location_ResultCode OH_LocationInfo_GetAdditionalInfo(Location_Info* location, char* additionalInfo, uint32_t length)
128 {
129     if (location == nullptr || additionalInfo == nullptr) {
130         return LOCATION_INVALID_PARAM;
131     }
132     if (length < strlen(location->additions)) {
133         return LOCATION_INVALID_PARAM;
134     }
135     memset_s(additionalInfo, length, 0, length);
136     auto ret = strcpy_s(additionalInfo, length - 1, location->additions);
137     if (ret != 0) {
138         LBSLOGE(OHOS::Location::LOCATION_CAPI, "strcpy_s failed, ret: %{public}d", ret);
139         // addition is empty, no need return
140     }
141     return LOCATION_SUCCESS;
142 }
143 
OH_Location_CreateRequestConfig(void)144 Location_RequestConfig* OH_Location_CreateRequestConfig(void)
145 {
146     return new (std::nothrow) Location_RequestConfig();
147 }
148 
OH_Location_DestroyRequestConfig(Location_RequestConfig * requestConfig)149 void OH_Location_DestroyRequestConfig(Location_RequestConfig* requestConfig)
150 {
151     if (requestConfig == nullptr) {
152         LBSLOGE(OHOS::Location::LOCATION_CAPI, "Parameter error.");
153         return;
154     }
155     delete requestConfig;
156     requestConfig = nullptr;
157 }
158 
OH_LocationRequestConfig_SetUseScene(Location_RequestConfig * requestConfig,Location_UseScene useScene)159 void OH_LocationRequestConfig_SetUseScene(Location_RequestConfig* requestConfig,
160     Location_UseScene useScene)
161 {
162     if (requestConfig == nullptr) {
163         LBSLOGE(OHOS::Location::LOCATION_CAPI, "requestConfig is nullptr");
164         return;
165     }
166     if (useScene > LOCATION_USE_SCENE_DAILY_LIFE_SERVICE ||
167         useScene < LOCATION_USE_SCENE_NAVIGATION) {
168         LBSLOGE(OHOS::Location::LOCATION_CAPI, "userScenario is invalid");
169         return;
170     }
171     requestConfig->scenario_ = useScene;
172 }
173 
OH_LocationRequestConfig_SetPowerConsumptionScene(Location_RequestConfig * requestConfig,Location_PowerConsumptionScene powerConsumptionScene)174 void OH_LocationRequestConfig_SetPowerConsumptionScene(Location_RequestConfig* requestConfig,
175     Location_PowerConsumptionScene powerConsumptionScene)
176 {
177     if (requestConfig == nullptr) {
178         LBSLOGE(OHOS::Location::LOCATION_CAPI, "requestConfig is nullptr");
179         return;
180     }
181     if (powerConsumptionScene > LOCATION_NO_POWER_CONSUMPTION ||
182         powerConsumptionScene < LOCATION_HIGH_POWER_CONSUMPTION) {
183         LBSLOGE(OHOS::Location::LOCATION_CAPI, "powerConsumptionScene is invalid");
184         return;
185     }
186     if (requestConfig->scenario_ == OHOS::Location::SCENE_UNSET ||
187         (requestConfig->scenario_ >= LOCATION_HIGH_POWER_CONSUMPTION &&
188         requestConfig->scenario_ <= LOCATION_NO_POWER_CONSUMPTION)) {
189         requestConfig->scenario_ = powerConsumptionScene;
190     }
191     return;
192 }
193 
OH_LocationRequestConfig_SetInterval(Location_RequestConfig * requestConfig,int interval)194 void OH_LocationRequestConfig_SetInterval(Location_RequestConfig* requestConfig,
195     int interval)
196 {
197     if (requestConfig == nullptr) {
198         LBSLOGE(OHOS::Location::LOCATION_CAPI, "requestConfig is nullptr");
199         return;
200     }
201     if (interval < 1) {
202         LBSLOGE(OHOS::Location::LOCATION_CAPI, "timeInterval is invalid");
203         return;
204     }
205 
206     requestConfig->timeInterval_ = interval;
207     return;
208 }
209 
OH_LocationRequestConfig_SetCallback(Location_RequestConfig * requestConfig,Location_InfoCallback callback,void * userData)210 void OH_LocationRequestConfig_SetCallback(Location_RequestConfig* requestConfig,
211     Location_InfoCallback callback, void* userData)
212 {
213     if (requestConfig == nullptr || userData == nullptr || callback == nullptr) {
214         LBSLOGE(OHOS::Location::LOCATION_CAPI, "callback or userData is nullptr");
215         return;
216     }
217     requestConfig->userData_ = userData;
218     requestConfig->callback_ = callback;
219 }
220 
AddLocationCallBack(OHOS::sptr<OHOS::Location::LocationInfoCallbackHost> & callback)221 void AddLocationCallBack(OHOS::sptr<OHOS::Location::LocationInfoCallbackHost>& callback)
222 {
223     std::unique_lock<std::mutex> lock(g_locationCallbackVectorMutex);
224     g_locationCallbackVector.push_back(callback);
225     LBSLOGD(OHOS::Location::LOCATION_CAPI, "after AddLocationCallBack, callback size %{public}s",
226         std::to_string(g_locationCallbackVector.size()).c_str());
227 }
228 
RemoveLocationCallBack(const Location_RequestConfig * requestConfig)229 void RemoveLocationCallBack(const Location_RequestConfig* requestConfig)
230 {
231     std::unique_lock<std::mutex> lock(g_locationCallbackVectorMutex);
232     if (g_locationCallbackVector.size() <= 0) {
233         LBSLOGE(OHOS::Location::LOCATION_CAPI, "locationcallbacksize <= 0");
234         return;
235     }
236     size_t i = 0;
237     for (; i < g_locationCallbackVector.size(); i++) {
238         if (requestConfig == g_locationCallbackVector[i]->GetRequestConfig()) {
239             break;
240         }
241     }
242     if (i >= g_locationCallbackVector.size()) {
243         LBSLOGD(OHOS::Location::LOCATION_CAPI, "location callback is not in vector");
244         return;
245     }
246     g_locationCallbackVector.erase(g_locationCallbackVector.begin() + i);
247     LBSLOGD(OHOS::Location::LOCATION_CAPI, "after RemoveLocationCallBack, callback size %{public}s",
248         std::to_string(g_locationCallbackVector.size()).c_str());
249 }
250 
GetLocationCallBack(const Location_RequestConfig * requestConfig)251 OHOS::sptr<OHOS::Location::LocationInfoCallbackHost> GetLocationCallBack(const Location_RequestConfig* requestConfig)
252 {
253     std::unique_lock<std::mutex> lock(g_locationCallbackVectorMutex);
254     if (g_locationCallbackVector.size() <= 0) {
255         LBSLOGE(OHOS::Location::LOCATION_CAPI, "locationcallbacksize <= 0");
256         return nullptr;
257     }
258     size_t i = 0;
259     for (; i < g_locationCallbackVector.size(); i++) {
260         if (requestConfig == g_locationCallbackVector[i]->GetRequestConfig()) {
261             return g_locationCallbackVector[i];
262         }
263     }
264     return nullptr;
265 }
266 
LocationErrCodeToLocationResultCode(OHOS::Location::LocationErrCode errCode)267 Location_ResultCode LocationErrCodeToLocationResultCode(OHOS::Location::LocationErrCode errCode)
268 {
269     switch (errCode) {
270         case OHOS::Location::ERRCODE_SUCCESS:
271             return LOCATION_SUCCESS;
272         case OHOS::Location::ERRCODE_PERMISSION_DENIED:
273             return LOCATION_PERMISSION_DENIED;
274         case OHOS::Location::ERRCODE_INVALID_PARAM:
275             return LOCATION_INVALID_PARAM;
276         case OHOS::Location::ERRCODE_NOT_SUPPORTED:
277             return LOCATION_NOT_SUPPORTED;
278         case OHOS::Location::ERRCODE_SERVICE_UNAVAILABLE:
279             return LOCATION_SERVICE_UNAVAILABLE;
280         case OHOS::Location::ERRCODE_SWITCH_OFF:
281             return LOCATION_SWITCH_OFF;
282         default:
283             return LOCATION_SERVICE_UNAVAILABLE;
284     }
285 }