| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #define LOG_TAG "GnssHAL_GnssNiInterface" |
| |
| #include "GnssNi.h" |
| |
| namespace android { |
| namespace hardware { |
| namespace gnss { |
| namespace V1_0 { |
| namespace implementation { |
| |
| std::vector<std::unique_ptr<ThreadFuncArgs>> GnssNi::sThreadFuncArgsList; |
| sp<IGnssNiCallback> GnssNi::sGnssNiCbIface = nullptr; |
| bool GnssNi::sInterfaceExists = false; |
| |
| GpsNiCallbacks GnssNi::sGnssNiCb = { |
| .notify_cb = niNotifyCb, |
| .create_thread_cb = createThreadCb |
| }; |
| |
| GnssNi::GnssNi(const GpsNiInterface* gpsNiIface) : mGnssNiIface(gpsNiIface) { |
| /* Error out if an instance of the interface already exists. */ |
| LOG_ALWAYS_FATAL_IF(sInterfaceExists); |
| sInterfaceExists = true; |
| } |
| |
| GnssNi::~GnssNi() { |
| sThreadFuncArgsList.clear(); |
| sInterfaceExists = false; |
| } |
| |
| pthread_t GnssNi::createThreadCb(const char* name, void (*start)(void*), void* arg) { |
| return createPthread(name, start, arg, &sThreadFuncArgsList); |
| } |
| |
| void GnssNi::niNotifyCb(GpsNiNotification* notification) { |
| if (sGnssNiCbIface == nullptr) { |
| ALOGE("%s: GNSS NI Callback Interface configured incorrectly", __func__); |
| return; |
| } |
| |
| if (notification == nullptr) { |
| ALOGE("%s: Invalid GpsNotification callback from GNSS HAL", __func__); |
| return; |
| } |
| |
| IGnssNiCallback::GnssNiNotification notificationGnss = { |
| .notificationId = notification->notification_id, |
| .niType = static_cast<IGnssNiCallback::GnssNiType>(notification->ni_type), |
| .notifyFlags = notification->notify_flags, |
| .timeoutSec = static_cast<uint32_t>(notification->timeout), |
| .defaultResponse = |
| static_cast<IGnssNiCallback::GnssUserResponseType>(notification->default_response), |
| .requestorId = notification->requestor_id, |
| .notificationMessage = notification->text, |
| .requestorIdEncoding = |
| static_cast<IGnssNiCallback::GnssNiEncodingType>(notification->requestor_id_encoding), |
| .notificationIdEncoding = |
| static_cast<IGnssNiCallback::GnssNiEncodingType>(notification->text_encoding) |
| }; |
| |
| auto ret = sGnssNiCbIface->niNotifyCb(notificationGnss); |
| if (!ret.isOk()) { |
| ALOGE("%s: Unable to invoke callback", __func__); |
| } |
| } |
| |
| // Methods from ::android::hardware::gnss::V1_0::IGnssNi follow. |
| Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback) { |
| if (mGnssNiIface == nullptr) { |
| ALOGE("%s: GnssNi interface is unavailable", __func__); |
| return Void(); |
| } |
| |
| sGnssNiCbIface = callback; |
| |
| mGnssNiIface->init(&sGnssNiCb); |
| return Void(); |
| } |
| |
| Return<void> GnssNi::respond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse) { |
| if (mGnssNiIface == nullptr) { |
| ALOGE("%s: GnssNi interface is unavailable", __func__); |
| } else { |
| mGnssNiIface->respond(notifId, static_cast<GpsUserResponseType>(userResponse)); |
| } |
| return Void(); |
| } |
| |
| } // namespace implementation |
| } // namespace V1_0 |
| } // namespace gnss |
| } // namespace hardware |
| } // namespace android |