xref: /aosp_15_r20/hardware/interfaces/gnss/aidl/default/GnssNavigationMessageInterface.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker  * Copyright (C) 2021 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker  *
4*4d7e907cSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker  *
8*4d7e907cSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker  *
10*4d7e907cSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker  * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker  */
16*4d7e907cSAndroid Build Coastguard Worker 
17*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "GnssNavigationMessageAidl"
18*4d7e907cSAndroid Build Coastguard Worker 
19*4d7e907cSAndroid Build Coastguard Worker #include "GnssNavigationMessageInterface.h"
20*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/hardware/gnss/BnGnss.h>
21*4d7e907cSAndroid Build Coastguard Worker #include <log/log.h>
22*4d7e907cSAndroid Build Coastguard Worker #include "Utils.h"
23*4d7e907cSAndroid Build Coastguard Worker 
24*4d7e907cSAndroid Build Coastguard Worker namespace aidl::android::hardware::gnss {
25*4d7e907cSAndroid Build Coastguard Worker 
26*4d7e907cSAndroid Build Coastguard Worker using namespace ::android::hardware::gnss;
27*4d7e907cSAndroid Build Coastguard Worker using GnssNavigationMessage = IGnssNavigationMessageCallback::GnssNavigationMessage;
28*4d7e907cSAndroid Build Coastguard Worker using GnssNavigationMessageType = GnssNavigationMessage::GnssNavigationMessageType;
29*4d7e907cSAndroid Build Coastguard Worker 
30*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<IGnssNavigationMessageCallback> GnssNavigationMessageInterface::sCallback = nullptr;
31*4d7e907cSAndroid Build Coastguard Worker 
GnssNavigationMessageInterface()32*4d7e907cSAndroid Build Coastguard Worker GnssNavigationMessageInterface::GnssNavigationMessageInterface() : mMinIntervalMillis(1000) {
33*4d7e907cSAndroid Build Coastguard Worker     mThreads.reserve(2);
34*4d7e907cSAndroid Build Coastguard Worker }
35*4d7e907cSAndroid Build Coastguard Worker 
~GnssNavigationMessageInterface()36*4d7e907cSAndroid Build Coastguard Worker GnssNavigationMessageInterface::~GnssNavigationMessageInterface() {
37*4d7e907cSAndroid Build Coastguard Worker     waitForStoppingThreads();
38*4d7e907cSAndroid Build Coastguard Worker }
39*4d7e907cSAndroid Build Coastguard Worker 
setCallback(const std::shared_ptr<IGnssNavigationMessageCallback> & callback)40*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus GnssNavigationMessageInterface::setCallback(
41*4d7e907cSAndroid Build Coastguard Worker         const std::shared_ptr<IGnssNavigationMessageCallback>& callback) {
42*4d7e907cSAndroid Build Coastguard Worker     ALOGD("setCallback");
43*4d7e907cSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mMutex);
44*4d7e907cSAndroid Build Coastguard Worker     sCallback = callback;
45*4d7e907cSAndroid Build Coastguard Worker     start();
46*4d7e907cSAndroid Build Coastguard Worker     return ndk::ScopedAStatus::ok();
47*4d7e907cSAndroid Build Coastguard Worker }
48*4d7e907cSAndroid Build Coastguard Worker 
close()49*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus GnssNavigationMessageInterface::close() {
50*4d7e907cSAndroid Build Coastguard Worker     ALOGD("close");
51*4d7e907cSAndroid Build Coastguard Worker     if (mIsActive) {
52*4d7e907cSAndroid Build Coastguard Worker         stop();
53*4d7e907cSAndroid Build Coastguard Worker     }
54*4d7e907cSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mMutex);
55*4d7e907cSAndroid Build Coastguard Worker     sCallback = nullptr;
56*4d7e907cSAndroid Build Coastguard Worker     return ndk::ScopedAStatus::ok();
57*4d7e907cSAndroid Build Coastguard Worker }
58*4d7e907cSAndroid Build Coastguard Worker 
start()59*4d7e907cSAndroid Build Coastguard Worker void GnssNavigationMessageInterface::start() {
60*4d7e907cSAndroid Build Coastguard Worker     ALOGD("start");
61*4d7e907cSAndroid Build Coastguard Worker 
62*4d7e907cSAndroid Build Coastguard Worker     if (mIsActive) {
63*4d7e907cSAndroid Build Coastguard Worker         ALOGD("restarting since nav msg has started");
64*4d7e907cSAndroid Build Coastguard Worker         stop();
65*4d7e907cSAndroid Build Coastguard Worker     }
66*4d7e907cSAndroid Build Coastguard Worker 
67*4d7e907cSAndroid Build Coastguard Worker     mIsActive = true;
68*4d7e907cSAndroid Build Coastguard Worker     mThreads.emplace_back(std::thread([this]() {
69*4d7e907cSAndroid Build Coastguard Worker         waitForStoppingThreads();
70*4d7e907cSAndroid Build Coastguard Worker         mThreadBlocker.reset();
71*4d7e907cSAndroid Build Coastguard Worker         do {
72*4d7e907cSAndroid Build Coastguard Worker             if (!mIsActive) {
73*4d7e907cSAndroid Build Coastguard Worker                 break;
74*4d7e907cSAndroid Build Coastguard Worker             }
75*4d7e907cSAndroid Build Coastguard Worker             GnssNavigationMessage message = {
76*4d7e907cSAndroid Build Coastguard Worker                     .svid = 19,
77*4d7e907cSAndroid Build Coastguard Worker                     .type = GnssNavigationMessageType::GPS_L1CA,
78*4d7e907cSAndroid Build Coastguard Worker                     .status = GnssNavigationMessage::STATUS_PARITY_PASSED,
79*4d7e907cSAndroid Build Coastguard Worker                     .messageId = 2,
80*4d7e907cSAndroid Build Coastguard Worker                     .submessageId = 3,
81*4d7e907cSAndroid Build Coastguard Worker                     .data = std::vector<uint8_t>(40, 0xF9),
82*4d7e907cSAndroid Build Coastguard Worker             };
83*4d7e907cSAndroid Build Coastguard Worker             this->reportMessage(message);
84*4d7e907cSAndroid Build Coastguard Worker         } while (mIsActive &&
85*4d7e907cSAndroid Build Coastguard Worker                  mThreadBlocker.wait_for(std::chrono::milliseconds(mMinIntervalMillis)));
86*4d7e907cSAndroid Build Coastguard Worker     }));
87*4d7e907cSAndroid Build Coastguard Worker }
88*4d7e907cSAndroid Build Coastguard Worker 
stop()89*4d7e907cSAndroid Build Coastguard Worker void GnssNavigationMessageInterface::stop() {
90*4d7e907cSAndroid Build Coastguard Worker     ALOGD("stop");
91*4d7e907cSAndroid Build Coastguard Worker     mIsActive = false;
92*4d7e907cSAndroid Build Coastguard Worker     mThreadBlocker.notify();
93*4d7e907cSAndroid Build Coastguard Worker     for (auto iter = mThreads.begin(); iter != mThreads.end();) {
94*4d7e907cSAndroid Build Coastguard Worker         if (iter->joinable()) {
95*4d7e907cSAndroid Build Coastguard Worker             // Store the thread object by value
96*4d7e907cSAndroid Build Coastguard Worker             std::thread threadToMove = std::move(*iter);
97*4d7e907cSAndroid Build Coastguard Worker 
98*4d7e907cSAndroid Build Coastguard Worker             mFutures.push_back(std::async(std::launch::async,
99*4d7e907cSAndroid Build Coastguard Worker                                           [threadToMove = std::move(threadToMove)]() mutable {
100*4d7e907cSAndroid Build Coastguard Worker                                               ALOGD("joining thread");
101*4d7e907cSAndroid Build Coastguard Worker                                               threadToMove.join();
102*4d7e907cSAndroid Build Coastguard Worker                                           }));
103*4d7e907cSAndroid Build Coastguard Worker         }
104*4d7e907cSAndroid Build Coastguard Worker         iter = mThreads.erase(iter);
105*4d7e907cSAndroid Build Coastguard Worker     }
106*4d7e907cSAndroid Build Coastguard Worker }
107*4d7e907cSAndroid Build Coastguard Worker 
reportMessage(const GnssNavigationMessage & message)108*4d7e907cSAndroid Build Coastguard Worker void GnssNavigationMessageInterface::reportMessage(const GnssNavigationMessage& message) {
109*4d7e907cSAndroid Build Coastguard Worker     ALOGD("reportMessage()");
110*4d7e907cSAndroid Build Coastguard Worker     std::shared_ptr<IGnssNavigationMessageCallback> callbackCopy;
111*4d7e907cSAndroid Build Coastguard Worker     {
112*4d7e907cSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> lock(mMutex);
113*4d7e907cSAndroid Build Coastguard Worker         if (sCallback == nullptr) {
114*4d7e907cSAndroid Build Coastguard Worker             ALOGE("%s: GnssNavigationMessageInterface::sCallback is null.", __func__);
115*4d7e907cSAndroid Build Coastguard Worker             return;
116*4d7e907cSAndroid Build Coastguard Worker         }
117*4d7e907cSAndroid Build Coastguard Worker         callbackCopy = sCallback;
118*4d7e907cSAndroid Build Coastguard Worker     }
119*4d7e907cSAndroid Build Coastguard Worker     callbackCopy->gnssNavigationMessageCb(message);
120*4d7e907cSAndroid Build Coastguard Worker }
121*4d7e907cSAndroid Build Coastguard Worker 
waitForStoppingThreads()122*4d7e907cSAndroid Build Coastguard Worker void GnssNavigationMessageInterface::waitForStoppingThreads() {
123*4d7e907cSAndroid Build Coastguard Worker     for (auto& future : mFutures) {
124*4d7e907cSAndroid Build Coastguard Worker         ALOGD("Stopping previous thread.");
125*4d7e907cSAndroid Build Coastguard Worker         future.wait();
126*4d7e907cSAndroid Build Coastguard Worker         ALOGD("Done stopping thread.");
127*4d7e907cSAndroid Build Coastguard Worker     }
128*4d7e907cSAndroid Build Coastguard Worker     mFutures.clear();
129*4d7e907cSAndroid Build Coastguard Worker }
130*4d7e907cSAndroid Build Coastguard Worker 
131*4d7e907cSAndroid Build Coastguard Worker }  // namespace aidl::android::hardware::gnss
132