1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "Gnss"
18 
19 #include "Gnss.h"
20 
21 #include <log/log.h>
22 #include <utils/SystemClock.h>
23 
24 #include "AGnss.h"
25 #include "AGnssRil.h"
26 #include "GnssBatching.h"
27 #include "GnssConfiguration.h"
28 #include "GnssMeasurement.h"
29 #include "GnssMeasurementCorrections.h"
30 #include "GnssVisibilityControl.h"
31 #include "Utils.h"
32 
33 using ::android::hardware::Status;
34 using ::android::hardware::gnss::common::Utils;
35 using ::android::hardware::gnss::measurement_corrections::V1_0::implementation::
36         GnssMeasurementCorrections;
37 using ::android::hardware::gnss::visibility_control::V1_0::implementation::GnssVisibilityControl;
38 
39 namespace android {
40 namespace hardware {
41 namespace gnss {
42 namespace V2_0 {
43 namespace implementation {
44 
45 using GnssSvFlags = IGnssCallback::GnssSvFlags;
46 
47 sp<V2_0::IGnssCallback> Gnss::sGnssCallback_2_0 = nullptr;
48 sp<V1_1::IGnssCallback> Gnss::sGnssCallback_1_1 = nullptr;
49 
50 namespace {
51 
getMockLocationV2_0()52 V2_0::GnssLocation getMockLocationV2_0() {
53     const ElapsedRealtime timestamp = {
54             .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
55                      ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
56             .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
57             // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
58             // In an actual implementation provide an estimate of the synchronization uncertainty
59             // or don't set the field.
60             .timeUncertaintyNs = 1000000};
61 
62     V2_0::GnssLocation location = {.v1_0 = Utils::getMockLocation(), .elapsedRealtime = timestamp};
63     return location;
64 }
65 
66 }  // namespace
67 
Gnss()68 Gnss::Gnss() : mMinIntervalMs(1000) {}
69 
~Gnss()70 Gnss::~Gnss() {
71     stop();
72 }
73 
74 // Methods from V1_0::IGnss follow.
setCallback(const sp<V1_0::IGnssCallback> &)75 Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>&) {
76     // TODO(b/124012850): Implement function.
77     return bool{};
78 }
79 
start()80 Return<bool> Gnss::start() {
81     if (mIsActive) {
82         ALOGW("Gnss has started. Restarting...");
83         stop();
84     }
85 
86     mIsActive = true;
87     mThread = std::thread([this]() {
88         while (mIsActive == true) {
89             const auto location = getMockLocationV2_0();
90             this->reportLocation(location);
91 
92             std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
93         }
94     });
95     return true;
96 }
97 
stop()98 Return<bool> Gnss::stop() {
99     mIsActive = false;
100     if (mThread.joinable()) {
101         mThread.join();
102     }
103     return true;
104 }
105 
cleanup()106 Return<void> Gnss::cleanup() {
107     // TODO(b/124012850): Implement function.
108     return Void();
109 }
110 
injectTime(int64_t,int64_t,int32_t)111 Return<bool> Gnss::injectTime(int64_t, int64_t, int32_t) {
112     // TODO(b/124012850): Implement function.
113     return bool{};
114 }
115 
injectLocation(double,double,float)116 Return<bool> Gnss::injectLocation(double, double, float) {
117     // TODO(b/124012850): Implement function.
118     return bool{};
119 }
120 
deleteAidingData(V1_0::IGnss::GnssAidingData)121 Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData) {
122     // TODO(b/124012850): Implement function.
123     return Void();
124 }
125 
setPositionMode(V1_0::IGnss::GnssPositionMode,V1_0::IGnss::GnssPositionRecurrence,uint32_t,uint32_t,uint32_t)126 Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode,
127                                    V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t,
128                                    uint32_t) {
129     return true;
130 }
131 
getExtensionAGnssRil()132 Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
133     // TODO(b/124012850): Implement function.
134     return sp<V1_0::IAGnssRil>{};
135 }
136 
getExtensionGnssGeofencing()137 Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
138     // TODO(b/124012850): Implement function.
139     return sp<V1_0::IGnssGeofencing>{};
140 }
141 
getExtensionAGnss()142 Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss() {
143     // TODO(b/124012850): Implement function.
144     return sp<V1_0::IAGnss>{};
145 }
146 
getExtensionGnssNi()147 Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
148     // The IGnssNi.hal interface is deprecated in 2.0.
149     return nullptr;
150 }
151 
getExtensionGnssMeasurement()152 Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
153     // Not supported
154     return nullptr;
155 }
156 
getExtensionGnssNavigationMessage()157 Return<sp<V1_0::IGnssNavigationMessage>> Gnss::getExtensionGnssNavigationMessage() {
158     // TODO(b/124012850): Implement function.
159     return sp<V1_0::IGnssNavigationMessage>{};
160 }
161 
getExtensionXtra()162 Return<sp<V1_0::IGnssXtra>> Gnss::getExtensionXtra() {
163     // TODO(b/124012850): Implement function.
164     return sp<V1_0::IGnssXtra>{};
165 }
166 
getExtensionGnssConfiguration()167 Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
168     // TODO(b/124012850): Implement function.
169     return sp<V1_0::IGnssConfiguration>{};
170 }
171 
getExtensionGnssDebug()172 Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
173     // TODO(b/124012850): Implement function.
174     return sp<V1_0::IGnssDebug>{};
175 }
176 
getExtensionGnssBatching()177 Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
178     // TODO(b/124012850): Implement function.
179     return sp<V1_0::IGnssBatching>{};
180 }
181 
182 // Methods from V1_1::IGnss follow.
setCallback_1_1(const sp<V1_1::IGnssCallback> & callback)183 Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
184     ALOGD("Gnss::setCallback_1_1");
185     if (callback == nullptr) {
186         ALOGE("%s: Null callback ignored", __func__);
187         return false;
188     }
189 
190     sGnssCallback_1_1 = callback;
191 
192     uint32_t capabilities = (uint32_t)V1_0::IGnssCallback::Capabilities::MEASUREMENTS;
193     auto ret = sGnssCallback_1_1->gnssSetCapabilitesCb(capabilities);
194     if (!ret.isOk()) {
195         ALOGE("%s: Unable to invoke callback", __func__);
196     }
197 
198     V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2019};
199 
200     ret = sGnssCallback_1_1->gnssSetSystemInfoCb(gnssInfo);
201     if (!ret.isOk()) {
202         ALOGE("%s: Unable to invoke callback", __func__);
203     }
204 
205     auto gnssName = "Google Mock GNSS Implementation v2.0";
206     ret = sGnssCallback_1_1->gnssNameCb(gnssName);
207     if (!ret.isOk()) {
208         ALOGE("%s: Unable to invoke callback", __func__);
209     }
210 
211     return true;
212 }
213 
setPositionMode_1_1(V1_0::IGnss::GnssPositionMode,V1_0::IGnss::GnssPositionRecurrence,uint32_t,uint32_t,uint32_t,bool)214 Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode,
215                                        V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t,
216                                        uint32_t, bool) {
217     return true;
218 }
219 
getExtensionGnssConfiguration_1_1()220 Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
221     // TODO(b/124012850): Implement function.
222     return sp<V1_1::IGnssConfiguration>{};
223 }
224 
getExtensionGnssMeasurement_1_1()225 Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
226     ALOGD("Gnss::getExtensionGnssMeasurement_1_1");
227     return new GnssMeasurement();
228 }
229 
injectBestLocation(const V1_0::GnssLocation &)230 Return<bool> Gnss::injectBestLocation(const V1_0::GnssLocation&) {
231     // TODO(b/124012850): Implement function.
232     return bool{};
233 }
234 
235 // Methods from V2_0::IGnss follow.
getExtensionGnssConfiguration_2_0()236 Return<sp<V2_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_0() {
237     return new GnssConfiguration{};
238 }
239 
getExtensionGnssDebug_2_0()240 Return<sp<V2_0::IGnssDebug>> Gnss::getExtensionGnssDebug_2_0() {
241     // TODO(b/124012850): Implement function.
242     return sp<V2_0::IGnssDebug>{};
243 }
244 
getExtensionAGnss_2_0()245 Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
246     return new AGnss{};
247 }
248 
getExtensionAGnssRil_2_0()249 Return<sp<V2_0::IAGnssRil>> Gnss::getExtensionAGnssRil_2_0() {
250     return new AGnssRil{};
251 }
252 
getExtensionGnssMeasurement_2_0()253 Return<sp<V2_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_0() {
254     ALOGD("Gnss::getExtensionGnssMeasurement_2_0");
255     return new GnssMeasurement();
256 }
257 
258 Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
getExtensionMeasurementCorrections()259 Gnss::getExtensionMeasurementCorrections() {
260     ALOGD("Gnss::getExtensionMeasurementCorrections");
261     return new GnssMeasurementCorrections();
262 }
263 
getExtensionVisibilityControl()264 Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> Gnss::getExtensionVisibilityControl() {
265     ALOGD("Gnss::getExtensionVisibilityControl");
266     return new GnssVisibilityControl();
267 }
268 
getExtensionGnssBatching_2_0()269 Return<sp<V2_0::IGnssBatching>> Gnss::getExtensionGnssBatching_2_0() {
270     return new GnssBatching();
271 }
272 
setCallback_2_0(const sp<V2_0::IGnssCallback> & callback)273 Return<bool> Gnss::setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) {
274     ALOGD("Gnss::setCallback_2_0");
275     if (callback == nullptr) {
276         ALOGE("%s: Null callback ignored", __func__);
277         return false;
278     }
279 
280     sGnssCallback_2_0 = callback;
281 
282     using Capabilities = V2_0::IGnssCallback::Capabilities;
283     const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
284                               Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST;
285     auto ret = sGnssCallback_2_0->gnssSetCapabilitiesCb_2_0(capabilities);
286     if (!ret.isOk()) {
287         ALOGE("%s: Unable to invoke callback", __func__);
288     }
289 
290     V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2019};
291 
292     ret = sGnssCallback_2_0->gnssSetSystemInfoCb(gnssInfo);
293     if (!ret.isOk()) {
294         ALOGE("%s: Unable to invoke callback", __func__);
295     }
296 
297     auto gnssName = "Google Mock GNSS Implementation v2.0";
298     ret = sGnssCallback_2_0->gnssNameCb(gnssName);
299     if (!ret.isOk()) {
300         ALOGE("%s: Unable to invoke callback", __func__);
301     }
302 
303     return true;
304 }
305 
reportLocation(const V2_0::GnssLocation & location) const306 Return<void> Gnss::reportLocation(const V2_0::GnssLocation& location) const {
307     std::unique_lock<std::mutex> lock(mMutex);
308     if (sGnssCallback_2_0 == nullptr) {
309         ALOGE("%s: sGnssCallback 2.0 is null.", __func__);
310         return Void();
311     }
312     sGnssCallback_2_0->gnssLocationCb_2_0(location);
313     return Void();
314 }
315 
injectBestLocation_2_0(const V2_0::GnssLocation &)316 Return<bool> Gnss::injectBestLocation_2_0(const V2_0::GnssLocation&) {
317     // TODO(b/124012850): Implement function.
318     return bool{};
319 }
320 
321 }  // namespace implementation
322 }  // namespace V2_0
323 }  // namespace gnss
324 }  // namespace hardware
325 }  // namespace android
326