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