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 #include "location_log.h"
17 #include "cj_lambda.h"
18 #include "locator_callback.h"
19
20 namespace OHOS {
21 namespace GeoLocationManager {
LocatorCallback()22 LocatorCallback::LocatorCallback()
23 {
24 fixNumber_ = 0;
25 inHdArea_ = true;
26 singleLocation_ = nullptr;
27 callbackValid_ = false;
28 locationPriority_ = 0;
29 InitLatch();
30 }
31
LocatorCallback(int64_t callbackId)32 LocatorCallback::LocatorCallback(int64_t callbackId)
33 {
34 fixNumber_ = 0;
35 inHdArea_ = true;
36 singleLocation_ = nullptr;
37 callbackValid_ = false;
38 locationPriority_ = 0;
39 InitLatch();
40 this->callbackId_ = callbackId;
41 auto cFunc = reinterpret_cast<void(*)(CJLocation location)>(callbackId);
42 callback_ = [ lambda = CJLambda::Create(cFunc)](const std::unique_ptr<Location::Location>& location) ->
43 void { lambda(NativeLocationToCJLocation(*location)); };
44 }
45
InitLatch()46 void LocatorCallback::InitLatch()
47 {
48 latch_ = new Location::CountDownLatch();
49 if (latch_ == nullptr) {
50 LBSLOGE(Location::LOCATOR_CALLBACK, "latch_ is nullptr.");
51 return;
52 }
53 latch_->SetCount(1);
54 }
55
~LocatorCallback()56 LocatorCallback::~LocatorCallback()
57 {
58 delete latch_;
59 }
60
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)61 int LocatorCallback::OnRemoteRequest(uint32_t code,
62 MessageParcel& data, MessageParcel& reply, MessageOption& option)
63 {
64 if (data.ReadInterfaceToken() != GetDescriptor()) {
65 LBSLOGE(Location::LOCATOR_CALLBACK, "invalid token.");
66 return -1;
67 }
68
69 switch (code) {
70 case Location::ILocatorCallback::RECEIVE_LOCATION_INFO_EVENT: {
71 std::unique_ptr<Location::Location> location = Location::Location::UnmarshallingMakeUnique(data);
72 LocatorCallback::OnLocationReport(location);
73 if (location->GetLocationSourceType() == Location::LocationSourceType::NETWORK_TYPE &&
74 location->GetAdditionsMap()["inHdArea"] != "") {
75 inHdArea_ = (location->GetAdditionsMap()["inHdArea"] == "true");
76 }
77 if (NeedSetSingleLocation(location)) {
78 SetSingleLocation(location);
79 }
80 if (IfReportAccuracyLocation()) {
81 CountDown();
82 }
83 break;
84 }
85 case Location::ILocatorCallback::RECEIVE_LOCATION_STATUS_EVENT: {
86 int status = data.ReadInt32();
87 OnLocatingStatusChange(status);
88 break;
89 }
90 case Location::ILocatorCallback::RECEIVE_ERROR_INFO_EVENT: {
91 int errorCode = data.ReadInt32();
92 LBSLOGI(Location::LOCATOR_STANDARD, "CallbackSutb receive ERROR_EVENT. errorCode:%{public}d", errorCode);
93 if (errorCode == Location::LOCATING_FAILED_INTERNET_ACCESS_FAILURE) {
94 inHdArea_ = false;
95 if (GetSingleLocation() != nullptr) {
96 CountDown();
97 }
98 } else {
99 OnErrorReport(errorCode);
100 }
101 break;
102 }
103 default: {
104 IPCObjectStub::OnRemoteRequest(code, data, reply, option);
105 break;
106 }
107 }
108 return 0;
109 }
110
OnLocationReport(const std::unique_ptr<Location::Location> & location)111 void LocatorCallback::OnLocationReport(const std::unique_ptr<Location::Location>& location)
112 {
113 std::unique_lock<std::mutex> guard(mutex_);
114 if (callback_ != nullptr) {
115 callback_(location);
116 }
117 }
118
OnLocatingStatusChange(const int status)119 void LocatorCallback::OnLocatingStatusChange(const int status)
120 {
121 }
122
OnErrorReport(const int errorCode)123 void LocatorCallback::OnErrorReport(const int errorCode)
124 {
125 }
126
IsSingleLocationRequest()127 bool LocatorCallback::IsSingleLocationRequest()
128 {
129 return (fixNumber_ == 1);
130 }
131
CountDown()132 void LocatorCallback::CountDown()
133 {
134 if (IsSingleLocationRequest() && latch_ != nullptr) {
135 latch_->CountDown();
136 }
137 }
138
Wait(int time)139 void LocatorCallback::Wait(int time)
140 {
141 if (IsSingleLocationRequest() && latch_ != nullptr) {
142 latch_->Wait(time);
143 }
144 }
145
GetCount()146 int LocatorCallback::GetCount()
147 {
148 if (IsSingleLocationRequest() && latch_ != nullptr) {
149 return latch_->GetCount();
150 }
151 return 0;
152 }
153
SetCount(int count)154 void LocatorCallback::SetCount(int count)
155 {
156 if (IsSingleLocationRequest() && latch_ != nullptr) {
157 return latch_->SetCount(count);
158 }
159 }
160
NeedSetSingleLocation(const std::unique_ptr<Location::Location> & location)161 bool LocatorCallback::NeedSetSingleLocation(const std::unique_ptr<Location::Location>& location)
162 {
163 if (locationPriority_ == Location::LOCATION_PRIORITY_ACCURACY &&
164 singleLocation_ != nullptr &&
165 location->GetLocationSourceType() == Location::LocationSourceType::NETWORK_TYPE) {
166 return false;
167 } else {
168 return true;
169 }
170 }
171
IfReportAccuracyLocation()172 bool LocatorCallback::IfReportAccuracyLocation()
173 {
174 if (locationPriority_ == Location::LOCATION_PRIORITY_ACCURACY &&
175 (((singleLocation_->GetLocationSourceType() == Location::LocationSourceType::GNSS_TYPE ||
176 singleLocation_->GetLocationSourceType() == Location::LocationSourceType::RTK_TYPE) && inHdArea_) ||
177 singleLocation_->GetLocationSourceType() == Location::LocationSourceType::NETWORK_TYPE)) {
178 return false;
179 } else {
180 return true;
181 }
182 }
183
SetSingleLocation(const std::unique_ptr<Location::Location> & location)184 void LocatorCallback::SetSingleLocation(const std::unique_ptr<Location::Location>& location)
185 {
186 std::unique_lock<std::mutex> guard(mutex_);
187 singleLocation_ = std::make_shared<Location::Location>(*location);
188 }
189 }
190 }
191