1 /*
2 * Copyright (C) 2021 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 "GnssAntennaInfoAidl"
18
19 #include "GnssAntennaInfo.h"
20 #include <aidl/android/hardware/gnss/BnGnss.h>
21 #include <log/log.h>
22 #include "Utils.h"
23
24 namespace aidl::android::hardware::gnss {
25
26 using namespace ::android::hardware::gnss;
27 using Row = IGnssAntennaInfoCallback::Row;
28 using Coord = IGnssAntennaInfoCallback::Coord;
29
30 std::shared_ptr<IGnssAntennaInfoCallback> GnssAntennaInfo::sCallback = nullptr;
31
GnssAntennaInfo()32 GnssAntennaInfo::GnssAntennaInfo() : mMinIntervalMs(1000) {}
33
~GnssAntennaInfo()34 GnssAntennaInfo::~GnssAntennaInfo() {
35 stop();
36 }
37
38 // Methods from ::android::hardware::gnss::V2_1::IGnssAntennaInfo follow.
setCallback(const std::shared_ptr<IGnssAntennaInfoCallback> & callback)39 ndk::ScopedAStatus GnssAntennaInfo::setCallback(
40 const std::shared_ptr<IGnssAntennaInfoCallback>& callback) {
41 ALOGD("setCallback");
42 std::unique_lock<std::mutex> lock(mMutex);
43 sCallback = callback;
44
45 if (mIsActive) {
46 ALOGW("GnssAntennaInfo callback already set. Resetting the callback...");
47 stop();
48 }
49 start();
50
51 return ndk::ScopedAStatus::ok();
52 }
53
close()54 ndk::ScopedAStatus GnssAntennaInfo::close() {
55 ALOGD("close");
56 stop();
57 std::unique_lock<std::mutex> lock(mMutex);
58 sCallback = nullptr;
59 return ndk::ScopedAStatus::ok();
60 }
61
start()62 void GnssAntennaInfo::start() {
63 ALOGD("start");
64 mIsActive = true;
65 mThread = std::thread([this]() {
66 while (mIsActive == true) {
67 if (sCallback != nullptr) {
68 IGnssAntennaInfoCallback::GnssAntennaInfo mockAntennaInfo_1 = {
69 .carrierFrequencyHz = 1575420000,
70 .phaseCenterOffsetCoordinateMillimeters = Coord{.x = 1,
71 .xUncertainty = 0.1,
72 .y = 2,
73 .yUncertainty = 0.1,
74 .z = 3,
75 .zUncertainty = 0.1},
76 .phaseCenterVariationCorrectionMillimeters =
77 {
78 Row{std::vector<double>{1, -1, 5, -2, 3, -1}},
79 Row{std::vector<double>{-2, 3, 2, 0, 1, 2}},
80 Row{std::vector<double>{1, 3, 2, -1, -3, 5}},
81 },
82 .phaseCenterVariationCorrectionUncertaintyMillimeters =
83 {
84 Row{std::vector<double>{0.1, 0.2, 0.4, 0.1, 0.2, 0.3}},
85 Row{std::vector<double>{0.3, 0.2, 0.3, 0.6, 0.1, 0.1}},
86 Row{std::vector<double>{0.1, 0.1, 0.4, 0.2, 0.5, 0.3}},
87 },
88 .signalGainCorrectionDbi =
89 {
90 Row{std::vector<double>{2, -3, 1, -3, 0, -4}},
91 Row{std::vector<double>{1, 0, -4, 1, 3, -2}},
92 Row{std::vector<double>{3, -2, 0, -2, 3, 0}},
93 },
94 .signalGainCorrectionUncertaintyDbi =
95 {
96 Row{std::vector<double>{0.3, 0.1, 0.2, 0.6, 0.1, 0.3}},
97 Row{std::vector<double>{0.1, 0.1, 0.5, 0.2, 0.3, 0.1}},
98 Row{std::vector<double>{0.2, 0.4, 0.2, 0.1, 0.1, 0.2}},
99 },
100 };
101
102 IGnssAntennaInfoCallback::GnssAntennaInfo mockAntennaInfo_2 = {
103 .carrierFrequencyHz = 1176450000,
104 .phaseCenterOffsetCoordinateMillimeters = Coord{.x = 5,
105 .xUncertainty = 0.1,
106 .y = 6,
107 .yUncertainty = 0.1,
108 .z = 7,
109 .zUncertainty = 0.1},
110 };
111
112 std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo> mockAntennaInfos = {
113 mockAntennaInfo_1,
114 mockAntennaInfo_2,
115 };
116 this->reportAntennaInfo(mockAntennaInfos);
117 }
118
119 /** For mock implementation this is good. On real device, we should only report
120 antennaInfo at start and when there is a configuration change. **/
121 std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
122 }
123 });
124 }
125
stop()126 void GnssAntennaInfo::stop() {
127 ALOGD("stop");
128 mIsActive = false;
129 if (mThread.joinable()) {
130 mThread.join();
131 }
132 }
133
reportAntennaInfo(const std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo> & antennaInfo) const134 void GnssAntennaInfo::reportAntennaInfo(
135 const std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo>& antennaInfo) const {
136 std::unique_lock<std::mutex> lock(mMutex);
137
138 if (sCallback == nullptr) {
139 ALOGE("%s: No non-null callback", __func__);
140 return;
141 }
142
143 auto ret = sCallback->gnssAntennaInfoCb(antennaInfo);
144 if (!ret.isOk()) {
145 ALOGE("%s: Unable to invoke callback", __func__);
146 }
147 }
148
149 } // namespace aidl::android::hardware::gnss
150