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 21namespace android { 22namespace hardware { 23namespace gnss { 24namespace V1_0 { 25namespace implementation { 26 27std::vector<std::unique_ptr<ThreadFuncArgs>> GnssNi::sThreadFuncArgsList; 28sp<IGnssNiCallback> GnssNi::sGnssNiCbIface = nullptr; 29bool GnssNi::sInterfaceExists = false; 30 31GpsNiCallbacks GnssNi::sGnssNiCb = { 32 .notify_cb = niNotifyCb, 33 .create_thread_cb = createThreadCb 34}; 35 36GnssNi::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 42GnssNi::~GnssNi() { 43 sThreadFuncArgsList.clear(); 44 sInterfaceExists = false; 45} 46 47pthread_t GnssNi::createThreadCb(const char* name, void (*start)(void*), void* arg) { 48 return createPthread(name, start, arg, &sThreadFuncArgsList); 49} 50 51void 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. 84Return<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 96Return<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