blob: 4abe707d4a5ffe78391882c087ccf0645c12350a [file] [log] [blame]
Yu-Han Yang73f16ad2018-02-24 10:05:32 -08001#define LOG_TAG "Gnss"
2
Yu-Han Yanga2f77322018-03-06 10:12:55 -08003#include <android/hardware/gnss/1.0/types.h>
Yu-Han Yang73f16ad2018-02-24 10:05:32 -08004#include <log/log.h>
Yu-Han Yang584ad322018-03-01 16:10:27 -08005
6#include "Gnss.h"
Yu-Han Yanga2f77322018-03-06 10:12:55 -08007#include "GnssDebug.h"
Yu-Han Yang73f16ad2018-02-24 10:05:32 -08008#include "GnssMeasurement.h"
Yu-Han Yanga5098612019-02-08 16:22:07 -08009#include "Utils.h"
Yu-Han Yang73f16ad2018-02-24 10:05:32 -080010
11namespace android {
12namespace hardware {
13namespace gnss {
14namespace V1_1 {
15namespace implementation {
16
Yu-Han Yanga5098612019-02-08 16:22:07 -080017using ::android::hardware::gnss::common::Utils;
Yu-Han Yanga2f77322018-03-06 10:12:55 -080018using GnssSvFlags = IGnssCallback::GnssSvFlags;
19
Yu-Han Yang584ad322018-03-01 16:10:27 -080020const uint32_t MIN_INTERVAL_MILLIS = 100;
21sp<::android::hardware::gnss::V1_1::IGnssCallback> Gnss::sGnssCallback = nullptr;
22
Yu-Han Yanga2f77322018-03-06 10:12:55 -080023Gnss::Gnss() : mMinIntervalMs(1000), mGnssConfiguration{new GnssConfiguration()} {}
Yu-Han Yang584ad322018-03-01 16:10:27 -080024
25Gnss::~Gnss() {
26 stop();
27}
28
Yu-Han Yang73f16ad2018-02-24 10:05:32 -080029// Methods from ::android::hardware::gnss::V1_0::IGnss follow.
30Return<bool> Gnss::setCallback(const sp<::android::hardware::gnss::V1_0::IGnssCallback>&) {
Yu-Han Yang584ad322018-03-01 16:10:27 -080031 // Mock handles only new callback (see setCallback1_1) coming from Android P+
32 return false;
Yu-Han Yang73f16ad2018-02-24 10:05:32 -080033}
34
35Return<bool> Gnss::start() {
Yu-Han Yang584ad322018-03-01 16:10:27 -080036 if (mIsActive) {
37 ALOGW("Gnss has started. Restarting...");
38 stop();
39 }
40
41 mIsActive = true;
42 mThread = std::thread([this]() {
43 while (mIsActive == true) {
Yu-Han Yanga2f77322018-03-06 10:12:55 -080044 auto svStatus = this->getMockSvStatus();
45 this->reportSvStatus(svStatus);
46
Yu-Han Yanga5098612019-02-08 16:22:07 -080047 auto location = Utils::getMockLocation();
Yu-Han Yang584ad322018-03-01 16:10:27 -080048 this->reportLocation(location);
49
50 std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
51 }
52 });
53
54 return true;
Yu-Han Yang73f16ad2018-02-24 10:05:32 -080055}
56
57Return<bool> Gnss::stop() {
Yu-Han Yang584ad322018-03-01 16:10:27 -080058 mIsActive = false;
59 if (mThread.joinable()) {
60 mThread.join();
61 }
62 return true;
Yu-Han Yang73f16ad2018-02-24 10:05:32 -080063}
64
65Return<void> Gnss::cleanup() {
66 // TODO implement
67 return Void();
68}
69
70Return<bool> Gnss::injectTime(int64_t, int64_t, int32_t) {
71 // TODO implement
72 return bool{};
73}
74
75Return<bool> Gnss::injectLocation(double, double, float) {
76 // TODO implement
77 return bool{};
78}
79
80Return<void> Gnss::deleteAidingData(::android::hardware::gnss::V1_0::IGnss::GnssAidingData) {
Yu-Han Yang73f16ad2018-02-24 10:05:32 -080081 return Void();
82}
83
84Return<bool> Gnss::setPositionMode(::android::hardware::gnss::V1_0::IGnss::GnssPositionMode,
85 ::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence,
86 uint32_t, uint32_t, uint32_t) {
87 // TODO implement
88 return bool{};
89}
90
91Return<sp<::android::hardware::gnss::V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
92 // TODO implement
93 return ::android::sp<::android::hardware::gnss::V1_0::IAGnssRil>{};
94}
95
96Return<sp<::android::hardware::gnss::V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
97 // TODO implement
98 return ::android::sp<::android::hardware::gnss::V1_0::IGnssGeofencing>{};
99}
100
101Return<sp<::android::hardware::gnss::V1_0::IAGnss>> Gnss::getExtensionAGnss() {
102 // TODO implement
103 return ::android::sp<::android::hardware::gnss::V1_0::IAGnss>{};
104}
105
106Return<sp<::android::hardware::gnss::V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
107 // TODO implement
108 return ::android::sp<::android::hardware::gnss::V1_0::IGnssNi>{};
109}
110
111Return<sp<::android::hardware::gnss::V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
112 // TODO implement
113 return new GnssMeasurement();
114}
115
116Return<sp<::android::hardware::gnss::V1_0::IGnssNavigationMessage>>
117Gnss::getExtensionGnssNavigationMessage() {
118 // TODO implement
119 return ::android::sp<::android::hardware::gnss::V1_0::IGnssNavigationMessage>{};
120}
121
122Return<sp<::android::hardware::gnss::V1_0::IGnssXtra>> Gnss::getExtensionXtra() {
123 // TODO implement
124 return ::android::sp<::android::hardware::gnss::V1_0::IGnssXtra>{};
125}
126
127Return<sp<::android::hardware::gnss::V1_0::IGnssConfiguration>>
128Gnss::getExtensionGnssConfiguration() {
129 // TODO implement
130 return new GnssConfiguration();
131}
132
133Return<sp<::android::hardware::gnss::V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
Yu-Han Yanga2f77322018-03-06 10:12:55 -0800134 return new GnssDebug();
Yu-Han Yang73f16ad2018-02-24 10:05:32 -0800135}
136
137Return<sp<::android::hardware::gnss::V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
138 // TODO implement
139 return ::android::sp<::android::hardware::gnss::V1_0::IGnssBatching>{};
140}
141
142// Methods from ::android::hardware::gnss::V1_1::IGnss follow.
Yu-Han Yang584ad322018-03-01 16:10:27 -0800143Return<bool> Gnss::setCallback_1_1(
144 const sp<::android::hardware::gnss::V1_1::IGnssCallback>& callback) {
145 if (callback == nullptr) {
146 ALOGE("%s: Null callback ignored", __func__);
147 return false;
148 }
149
150 sGnssCallback = callback;
151
152 uint32_t capabilities = 0x0;
153 auto ret = sGnssCallback->gnssSetCapabilitesCb(capabilities);
154 if (!ret.isOk()) {
155 ALOGE("%s: Unable to invoke callback", __func__);
156 }
157
158 IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018};
159
160 ret = sGnssCallback->gnssSetSystemInfoCb(gnssInfo);
161 if (!ret.isOk()) {
162 ALOGE("%s: Unable to invoke callback", __func__);
163 }
164
165 auto gnssName = "Google Mock GNSS Implementation v1.1";
166 ret = sGnssCallback->gnssNameCb(gnssName);
167 if (!ret.isOk()) {
168 ALOGE("%s: Unable to invoke callback", __func__);
169 }
170
171 return true;
Yu-Han Yang73f16ad2018-02-24 10:05:32 -0800172}
173
174Return<bool> Gnss::setPositionMode_1_1(
175 ::android::hardware::gnss::V1_0::IGnss::GnssPositionMode,
Yu-Han Yang584ad322018-03-01 16:10:27 -0800176 ::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence, uint32_t minIntervalMs,
177 uint32_t, uint32_t, bool) {
178 mMinIntervalMs = (minIntervalMs < MIN_INTERVAL_MILLIS) ? MIN_INTERVAL_MILLIS : minIntervalMs;
179 return true;
Yu-Han Yang73f16ad2018-02-24 10:05:32 -0800180}
181
182Return<sp<::android::hardware::gnss::V1_1::IGnssConfiguration>>
183Gnss::getExtensionGnssConfiguration_1_1() {
Yu-Han Yanga2f77322018-03-06 10:12:55 -0800184 return mGnssConfiguration;
Yu-Han Yang73f16ad2018-02-24 10:05:32 -0800185}
186
187Return<sp<::android::hardware::gnss::V1_1::IGnssMeasurement>>
188Gnss::getExtensionGnssMeasurement_1_1() {
189 // TODO implement
190 return new GnssMeasurement();
191}
192
Yu-Han Yanga2f77322018-03-06 10:12:55 -0800193Return<bool> Gnss::injectBestLocation(const GnssLocation&) {
194 return true;
Yu-Han Yang73f16ad2018-02-24 10:05:32 -0800195}
196
Yu-Han Yanga2f77322018-03-06 10:12:55 -0800197Return<GnssSvStatus> Gnss::getMockSvStatus() const {
198 std::unique_lock<std::recursive_mutex> lock(mGnssConfiguration->getMutex());
199 GnssSvInfo mockGnssSvInfoList[] = {
Yu-Han Yanga5098612019-02-08 16:22:07 -0800200 Utils::getSvInfo(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5),
201 Utils::getSvInfo(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5),
202 Utils::getSvInfo(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0),
203 Utils::getSvInfo(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0),
204 Utils::getSvInfo(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0),
205 Utils::getSvInfo(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0),
206 Utils::getSvInfo(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0),
207 Utils::getSvInfo(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0)};
Yu-Han Yanga2f77322018-03-06 10:12:55 -0800208
209 GnssSvStatus svStatus = {.numSvs = sizeof(mockGnssSvInfoList) / sizeof(GnssSvInfo)};
210 for (uint32_t i = 0; i < svStatus.numSvs; i++) {
211 if (mGnssConfiguration->isBlacklisted(mockGnssSvInfoList[i])) {
212 /**
213 * Note well, this is a simple, mock emulation of not using a satellite by changing the
214 * used bit. Simply blanking the used bit, as is done here, is *not* an acceptable
215 * actual device implementation - actual devices *must not* use the satellite in the
216 * position calculation, as specified in IGnssConfiguration.hal.
217 */
218 mockGnssSvInfoList[i].svFlag &=
219 ~static_cast<uint8_t>(IGnssCallback::GnssSvFlags::USED_IN_FIX);
220 }
221 svStatus.gnssSvList[i] = mockGnssSvInfoList[i];
222 }
223
224 return svStatus;
225}
226
227Return<void> Gnss::reportLocation(const GnssLocation& location) const {
Yu-Han Yang584ad322018-03-01 16:10:27 -0800228 std::unique_lock<std::mutex> lock(mMutex);
229 if (sGnssCallback == nullptr) {
230 ALOGE("%s: sGnssCallback is null.", __func__);
231 return Void();
232 }
233 sGnssCallback->gnssLocationCb(location);
234 return Void();
235}
Yu-Han Yang73f16ad2018-02-24 10:05:32 -0800236
Yu-Han Yanga2f77322018-03-06 10:12:55 -0800237Return<void> Gnss::reportSvStatus(const GnssSvStatus& svStatus) const {
238 std::unique_lock<std::mutex> lock(mMutex);
239 if (sGnssCallback == nullptr) {
240 ALOGE("%s: sGnssCallback is null.", __func__);
241 return Void();
242 }
243 sGnssCallback->gnssSvStatusCb(svStatus);
244 return Void();
245}
246
Yu-Han Yang73f16ad2018-02-24 10:05:32 -0800247} // namespace implementation
248} // namespace V1_1
249} // namespace gnss
250} // namespace hardware
251} // namespace android