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 }