1 /* 2 * Copyright (C) 2016 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 "GnssHAL_GnssNiInterface" 18 19 #include "GnssNi.h" 20 21 namespace android { 22 namespace hardware { 23 namespace gnss { 24 namespace V1_0 { 25 namespace implementation { 26 27 std::vector<std::unique_ptr<ThreadFuncArgs>> GnssNi::sThreadFuncArgsList; 28 sp<IGnssNiCallback> GnssNi::sGnssNiCbIface = nullptr; 29 bool GnssNi::sInterfaceExists = false; 30 31 GpsNiCallbacks GnssNi::sGnssNiCb = { 32 .notify_cb = niNotifyCb, 33 .create_thread_cb = createThreadCb 34 }; 35 36 GnssNi::GnssNi(const GpsNiInterface* gpsNiIface) : mGnssNiIface(gpsNiIface) { 37 /* Error out if an instance of the interface already exists. */ 38 LOG_ALWAYS_FATAL_IF(sInterfaceExists); 39 sInterfaceExists = true; 40 } 41 42 GnssNi::~GnssNi() { 43 sThreadFuncArgsList.clear(); 44 sInterfaceExists = false; 45 } 46 47 pthread_t GnssNi::createThreadCb(const char* name, void (*start)(void*), void* arg) { 48 return createPthread(name, start, arg, &sThreadFuncArgsList); 49 } 50 51 void GnssNi::niNotifyCb(GpsNiNotification* notification) { 52 if (sGnssNiCbIface == nullptr) { 53 ALOGE("%s: GNSS NI Callback Interface configured incorrectly", __func__); 54 return; 55 } 56 57 if (notification == nullptr) { 58 ALOGE("%s: Invalid GpsNotification callback from GNSS HAL", __func__); 59 return; 60 } 61 62 IGnssNiCallback::GnssNiNotification notificationGnss = { 63 .notificationId = notification->notification_id, 64 .niType = static_cast<IGnssNiCallback::GnssNiType>(notification->ni_type), 65 .notifyFlags = notification->notify_flags, 66 .timeoutSec = static_cast<uint32_t>(notification->timeout), 67 .defaultResponse = 68 static_cast<IGnssNiCallback::GnssUserResponseType>(notification->default_response), 69 .requestorId = notification->requestor_id, 70 .notificationMessage = notification->text, 71 .requestorIdEncoding = 72 static_cast<IGnssNiCallback::GnssNiEncodingType>(notification->requestor_id_encoding), 73 .notificationIdEncoding = 74 static_cast<IGnssNiCallback::GnssNiEncodingType>(notification->text_encoding) 75 }; 76 77 auto ret = sGnssNiCbIface->niNotifyCb(notificationGnss); 78 if (!ret.isOk()) { 79 ALOGE("%s: Unable to invoke callback", __func__); 80 } 81 } 82 83 // Methods from ::android::hardware::gnss::V1_0::IGnssNi follow. 84 Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback) { 85 if (mGnssNiIface == nullptr) { 86 ALOGE("%s: GnssNi interface is unavailable", __func__); 87 return Void(); 88 } 89 90 sGnssNiCbIface = callback; 91 92 mGnssNiIface->init(&sGnssNiCb); 93 return Void(); 94 } 95 96 Return<void> GnssNi::respond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse) { 97 if (mGnssNiIface == nullptr) { 98 ALOGE("%s: GnssNi interface is unavailable", __func__); 99 } else { 100 mGnssNiIface->respond(notifId, static_cast<GpsUserResponseType>(userResponse)); 101 } 102 return Void(); 103 } 104 105 } // namespace implementation 106 } // namespace V1_0 107 } // namespace gnss 108 } // namespace hardware 109 } // namespace android 110