Home | History | Annotate | Download | only in android
      1 /*
      2  * Copyright (c) 2017, The Linux Foundation. All rights reserved.
      3  * Not a Contribution
      4  */
      5 /*
      6  * Copyright (C) 2016 The Android Open Source Project
      7  *
      8  * Licensed under the Apache License, Version 2.0 (the "License");
      9  * you may not use this file except in compliance with the License.
     10  * You may obtain a copy of the License at
     11  *
     12  *      http://www.apache.org/licenses/LICENSE-2.0
     13  *
     14  * Unless required by applicable law or agreed to in writing, software
     15  * distributed under the License is distributed on an "AS IS" BASIS,
     16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     17  * See the License for the specific language governing permissions and
     18  * limitations under the License.
     19  */
     20 
     21 #define LOG_TAG "LocSvc_GnssInterface"
     22 
     23 #include <log_util.h>
     24 #include <dlfcn.h>
     25 #include "Gnss.h"
     26 typedef void* (getLocationInterface)();
     27 
     28 namespace android {
     29 namespace hardware {
     30 namespace gnss {
     31 namespace V1_0 {
     32 namespace implementation {
     33 
     34 void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
     35     LOC_LOGE("%s] service died. cookie: %llu, who: %p",
     36             __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
     37     if (mGnss != nullptr) {
     38         mGnss->stop();
     39         mGnss->cleanup();
     40     }
     41 }
     42 
     43 Gnss::Gnss() {
     44     ENTRY_LOG_CALLFLOW();
     45     // clear pending GnssConfig
     46     memset(&mPendingConfig, 0, sizeof(GnssConfig));
     47 
     48     mGnssDeathRecipient = new GnssDeathRecipient(this);
     49 }
     50 
     51 Gnss::~Gnss() {
     52     ENTRY_LOG_CALLFLOW();
     53     if (mApi != nullptr) {
     54         delete mApi;
     55         mApi = nullptr;
     56     }
     57 }
     58 
     59 GnssAPIClient* Gnss::getApi() {
     60     if (mApi == nullptr && (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr)) {
     61         mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
     62         if (mApi == nullptr) {
     63             LOC_LOGE("%s] faild to create GnssAPIClient", __FUNCTION__);
     64             return mApi;
     65         }
     66 
     67         if (mPendingConfig.size == sizeof(GnssConfig)) {
     68             // we have pending GnssConfig
     69             mApi->gnssConfigurationUpdate(mPendingConfig);
     70             // clear size to invalid mPendingConfig
     71             mPendingConfig.size = 0;
     72             if (mPendingConfig.assistanceServer.hostName != nullptr) {
     73                 free((void*)mPendingConfig.assistanceServer.hostName);
     74             }
     75         }
     76     }
     77     if (mApi == nullptr) {
     78         LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__);
     79     }
     80     return mApi;
     81 }
     82 
     83 GnssInterface* Gnss::getGnssInterface() {
     84     static bool getGnssInterfaceFailed = false;
     85     if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
     86         LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__);
     87         getLocationInterface* getter = NULL;
     88         const char *error = NULL;
     89         dlerror();
     90         void *handle = dlopen("libgnss.so", RTLD_NOW);
     91         if (NULL == handle || (error = dlerror()) != NULL)  {
     92             LOC_LOGW("dlopen for libgnss.so failed, error = %s", error);
     93         } else {
     94             getter = (getLocationInterface*)dlsym(handle, "getGnssInterface");
     95             if ((error = dlerror()) != NULL)  {
     96                 LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error);
     97                 getter = NULL;
     98             }
     99         }
    100 
    101         if (NULL == getter) {
    102             getGnssInterfaceFailed = true;
    103         } else {
    104             mGnssInterface = (GnssInterface*)(*getter)();
    105         }
    106     }
    107     return mGnssInterface;
    108 }
    109 
    110 Return<bool> Gnss::setCallback(const sp<IGnssCallback>& callback)  {
    111     ENTRY_LOG_CALLFLOW();
    112     if (mGnssCbIface != nullptr) {
    113         mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
    114     }
    115     mGnssCbIface = callback;
    116     if (mGnssCbIface != nullptr) {
    117         mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
    118     }
    119 
    120     GnssAPIClient* api = getApi();
    121     if (api != nullptr) {
    122         api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
    123         api->locAPIEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
    124         api->requestCapabilities();
    125     }
    126     return true;
    127 }
    128 
    129 Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
    130     ENTRY_LOG_CALLFLOW();
    131     mGnssNiCbIface = callback;
    132     GnssAPIClient* api = getApi();
    133     if (api != nullptr) {
    134         api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
    135     }
    136     return true;
    137 }
    138 
    139 Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
    140     ENTRY_LOG_CALLFLOW();
    141     GnssAPIClient* api = getApi();
    142     if (api) {
    143         api->locAPIGnssUpdateConfig(gnssConfig);
    144     } else if (gnssConfig.flags != 0) {
    145         // api is not ready yet, update mPendingConfig with gnssConfig
    146         mPendingConfig.size = sizeof(GnssConfig);
    147 
    148         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
    149             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
    150             mPendingConfig.gpsLock = gnssConfig.gpsLock;
    151         }
    152         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
    153             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
    154             mPendingConfig.suplVersion = gnssConfig.suplVersion;
    155         }
    156         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
    157             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
    158             mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
    159             mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type;
    160             if (mPendingConfig.assistanceServer.hostName != nullptr) {
    161                 free((void*)mPendingConfig.assistanceServer.hostName);
    162                 mPendingConfig.assistanceServer.hostName =
    163                     strdup(gnssConfig.assistanceServer.hostName);
    164             }
    165             mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port;
    166         }
    167         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
    168             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
    169             mPendingConfig.lppProfile = gnssConfig.lppProfile;
    170         }
    171         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
    172             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
    173             mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask;
    174         }
    175         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
    176             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
    177             mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask;
    178         }
    179         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
    180             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
    181             mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask;
    182         }
    183         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
    184             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
    185             mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl;
    186         }
    187         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
    188             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
    189             mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices;
    190         }
    191         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
    192             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
    193             mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
    194         }
    195     }
    196     return true;
    197 }
    198 
    199 Return<bool> Gnss::start()  {
    200     ENTRY_LOG_CALLFLOW();
    201     bool retVal = false;
    202     GnssAPIClient* api = getApi();
    203     if (api) {
    204         retVal = api->gnssStart();
    205     }
    206     return retVal;
    207 }
    208 
    209 Return<bool> Gnss::stop()  {
    210     ENTRY_LOG_CALLFLOW();
    211     bool retVal = false;
    212     GnssAPIClient* api = getApi();
    213     if (api) {
    214         retVal = api->gnssStop();
    215     }
    216     return retVal;
    217 }
    218 
    219 Return<void> Gnss::cleanup()  {
    220     ENTRY_LOG_CALLFLOW();
    221 
    222     if (mApi != nullptr) {
    223         mApi->locAPIDisable();
    224     }
    225 
    226     return Void();
    227 }
    228 
    229 Return<bool> Gnss::injectLocation(double latitudeDegrees,
    230                                   double longitudeDegrees,
    231                                   float accuracyMeters)  {
    232     ENTRY_LOG_CALLFLOW();
    233     GnssInterface* gnssInterface = getGnssInterface();
    234     if (nullptr != gnssInterface) {
    235         gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
    236         return true;
    237     } else {
    238         return false;
    239     }
    240 }
    241 
    242 Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
    243                               int32_t uncertaintyMs) {
    244     ENTRY_LOG_CALLFLOW();
    245     GnssInterface* gnssInterface = getGnssInterface();
    246     if (nullptr != gnssInterface) {
    247         gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs);
    248         return true;
    249     } else {
    250         return false;
    251     }
    252 }
    253 
    254 Return<void> Gnss::deleteAidingData(IGnss::GnssAidingData aidingDataFlags)  {
    255     ENTRY_LOG_CALLFLOW();
    256     GnssAPIClient* api = getApi();
    257     if (api) {
    258         api->gnssDeleteAidingData(aidingDataFlags);
    259     }
    260     return Void();
    261 }
    262 
    263 Return<bool> Gnss::setPositionMode(IGnss::GnssPositionMode mode,
    264                                    IGnss::GnssPositionRecurrence recurrence,
    265                                    uint32_t minIntervalMs,
    266                                    uint32_t preferredAccuracyMeters,
    267                                    uint32_t preferredTimeMs)  {
    268     ENTRY_LOG_CALLFLOW();
    269     bool retVal = false;
    270     GnssAPIClient* api = getApi();
    271     if (api) {
    272         retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
    273                 preferredAccuracyMeters, preferredTimeMs);
    274     }
    275     return retVal;
    276 }
    277 
    278 Return<sp<IAGnss>> Gnss::getExtensionAGnss()  {
    279     ENTRY_LOG_CALLFLOW();
    280     mAGnssIface = new AGnss(this);
    281     return mAGnssIface;
    282 }
    283 
    284 Return<sp<IGnssNi>> Gnss::getExtensionGnssNi()  {
    285     ENTRY_LOG_CALLFLOW();
    286     mGnssNi = new GnssNi(this);
    287     return mGnssNi;
    288 }
    289 
    290 Return<sp<IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
    291     ENTRY_LOG_CALLFLOW();
    292     mGnssMeasurement = new GnssMeasurement();
    293     return mGnssMeasurement;
    294 }
    295 
    296 Return<sp<IGnssConfiguration>> Gnss::getExtensionGnssConfiguration()  {
    297     ENTRY_LOG_CALLFLOW();
    298     mGnssConfig = new GnssConfiguration(this);
    299     return mGnssConfig;
    300 }
    301 
    302 Return<sp<IGnssGeofencing>> Gnss::getExtensionGnssGeofencing()  {
    303     ENTRY_LOG_CALLFLOW();
    304     mGnssGeofencingIface = new GnssGeofencing();
    305     return mGnssGeofencingIface;
    306 }
    307 
    308 Return<sp<IGnssBatching>> Gnss::getExtensionGnssBatching()  {
    309     mGnssBatching = new GnssBatching();
    310     return mGnssBatching;
    311 }
    312 
    313 Return<sp<IGnssDebug>> Gnss::getExtensionGnssDebug() {
    314     ENTRY_LOG_CALLFLOW();
    315     mGnssDebug = new GnssDebug(this);
    316     return mGnssDebug;
    317 }
    318 
    319 Return<sp<IAGnssRil>> Gnss::getExtensionAGnssRil() {
    320     mGnssRil = new AGnssRil(this);
    321     return mGnssRil;
    322 }
    323 
    324 IGnss* HIDL_FETCH_IGnss(const char* hal) {
    325     ENTRY_LOG_CALLFLOW();
    326     IGnss* iface = nullptr;
    327     iface = new Gnss();
    328     if (iface == nullptr) {
    329         LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
    330     }
    331     return iface;
    332 }
    333 
    334 }  // namespace implementation
    335 }  // namespace V1_0
    336 }  // namespace gnss
    337 }  // namespace hardware
    338 }  // namespace android
    339