From 73df7e0e6f3ff8b11717c51b47f38a2b0bfb1244 Mon Sep 17 00:00:00 2001 From: Katz Yamada Date: Fri, 2 Mar 2018 17:02:28 -0800 Subject: [PATCH 01/11] fix: Default values in GNSS Debug Data Change default values for accuracies and uncertainties in GNSS Debug Data to non- zero constant values. Bug: 72753638 Change-Id: I075b364ed81c8a466b062ab4d5381c3d4ece1ea6 CRs-Fixed: 2185247 --- android/GnssDebug.cpp | 41 ++++++++++++++++++++++++++++++++++++----- gnss/GnssAdapter.cpp | 5 ++++- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/android/GnssDebug.cpp b/android/GnssDebug.cpp index 3d2b8bda..33d7aa52 100644 --- a/android/GnssDebug.cpp +++ b/android/GnssDebug.cpp @@ -30,8 +30,14 @@ namespace implementation { using ::android::hardware::hidl_vec; -#define GNSS_DEBUG_UNKNOWN_UTC_TIME (1483228800000ULL) // 1/1/2017 00:00 GMT -#define GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC (1.57783680E17) // 5 years in ns +#define GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS (20000000) +#define GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS (20000) +#define GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC (500) +#define GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG (180) + +#define GNSS_DEBUG_UNKNOWN_UTC_TIME (1483228800000LL) // 1/1/2017 00:00 GMT +#define GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC (1.57783680E17) // 5 years in ns +#define GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC (2.0e5) // ppm GnssDebug::GnssDebug(Gnss* gnss) : mGnss(gnss) { @@ -89,6 +95,23 @@ Return GnssDebug::getDebugData(getDebugData_cb _hidl_cb) data.position.valid = false; } + if (data.position.horizontalAccuracyMeters <= 0 || + data.position.horizontalAccuracyMeters > GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS) { + data.position.horizontalAccuracyMeters = GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS; + } + if (data.position.verticalAccuracyMeters <= 0 || + data.position.verticalAccuracyMeters > GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS) { + data.position.verticalAccuracyMeters = GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS; + } + if (data.position.speedAccuracyMetersPerSecond <= 0 || + data.position.speedAccuracyMetersPerSecond > GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC) { + data.position.speedAccuracyMetersPerSecond = GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC; + } + if (data.position.bearingAccuracyDegrees <= 0 || + data.position.bearingAccuracyDegrees > GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG) { + data.position.bearingAccuracyDegrees = GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG; + } + // time block if (reports.mTime.mValid) { data.time.timeEstimate = reports.mTime.timeEstimate; @@ -96,10 +119,18 @@ Return GnssDebug::getDebugData(getDebugData_cb _hidl_cb) data.time.frequencyUncertaintyNsPerSec = reports.mTime.frequencyUncertaintyNsPerSec; } - else { + + if (data.time.timeEstimate <= 0 || + data.time.timeEstimate > GNSS_DEBUG_UNKNOWN_UTC_TIME) { data.time.timeEstimate = GNSS_DEBUG_UNKNOWN_UTC_TIME; - data.time.timeUncertaintyNs = (float)(GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC); - data.time.frequencyUncertaintyNsPerSec = 0; + } + if (data.time.timeUncertaintyNs <= 0 || + data.time.timeUncertaintyNs > (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC) { + data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC; + } + if (data.time.frequencyUncertaintyNsPerSec <= 0 || + data.time.frequencyUncertaintyNsPerSec > (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC) { + data.time.frequencyUncertaintyNsPerSec = (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC; } // satellite data block diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp index 098c8aa0..5a1eb256 100644 --- a/gnss/GnssAdapter.cpp +++ b/gnss/GnssAdapter.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -3043,6 +3043,9 @@ bool GnssAdapter::getDebugReport(GnssDebugReport& r) r.mLocation.mLocation.longitude = (double)(reports.mBestPosition.back().mBestLon) * RAD2DEG; r.mLocation.mLocation.altitude = reports.mBestPosition.back().mBestAlt; + r.mLocation.mLocation.accuracy = + (double)(reports.mBestPosition.back().mBestHepe); + r.mLocation.mUtcReported = reports.mBestPosition.back().mUtcReported; } else { From 37d34d0dc88f8f05cc6efbdfebe76b2e189175fb Mon Sep 17 00:00:00 2001 From: Dante Russo Date: Thu, 5 Apr 2018 17:54:50 -0700 Subject: [PATCH 02/11] Assure event mask is set properly to get positions The event mask can be retrieved in the context of client thread as zero and then queued up to go to msg task thread. By the time the msg is actually handled in msg task thread, the actual event mask at LOC API layer may have already changed, but this mask would then be overridden by zero. This can cause no modem events to ever come, including position reports. The fix is to not retrieve the event mask in the client thread, but instead wait for msg to be handled in msg task thread before retrieving it. Change-Id: I48562d028bbfa187732686c060b5cdd62c6d5a89 CRs-fixed: 2219519 --- core/LocApiBase.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/core/LocApiBase.cpp b/core/LocApiBase.cpp index 8aef94b3..96148726 100644 --- a/core/LocApiBase.cpp +++ b/core/LocApiBase.cpp @@ -107,19 +107,16 @@ struct LocSsrMsg : public LocMsg { struct LocOpenMsg : public LocMsg { LocApiBase* mLocApi; - LOC_API_ADAPTER_EVENT_MASK_T mMask; - inline LocOpenMsg(LocApiBase* locApi, - LOC_API_ADAPTER_EVENT_MASK_T mask) : - LocMsg(), mLocApi(locApi), mMask(mask) + inline LocOpenMsg(LocApiBase* locApi) : + LocMsg(), mLocApi(locApi) { locallog(); } inline virtual void proc() const { - mLocApi->open(mMask); + mLocApi->open(mLocApi->getEvtMask()); } inline void locallog() const { - LOC_LOGV("%s:%d]: LocOpen Mask: %x\n", - __func__, __LINE__, mMask); + LOC_LOGv("LocOpen Mask: %" PRIx64 "\n", mLocApi->getEvtMask()); } inline virtual void log() const { locallog(); @@ -163,8 +160,7 @@ void LocApiBase::addAdapter(LocAdapterBase* adapter) for (int i = 0; i < MAX_ADAPTERS && mLocAdapters[i] != adapter; i++) { if (mLocAdapters[i] == NULL) { mLocAdapters[i] = adapter; - mMsgTask->sendMsg(new LocOpenMsg(this, - mMask | adapter->getEvtMask())); + mMsgTask->sendMsg(new LocOpenMsg(this)); break; } } @@ -200,7 +196,7 @@ void LocApiBase::removeAdapter(LocAdapterBase* adapter) close(); } else { // else we need to remove the bit - mMsgTask->sendMsg(new LocOpenMsg(this, getEvtMask())); + mMsgTask->sendMsg(new LocOpenMsg(this)); } } } From f93ec50a05ecee0faee6721f8ac5f1e984f4eca2 Mon Sep 17 00:00:00 2001 From: Katz Yamada Date: Tue, 17 Apr 2018 11:11:26 -0700 Subject: [PATCH 03/11] fix: Incorrect path to ehub socket directory Change-Id: I58b41c4a8de8b51c8a6effe989182ea5942cff6e CRs-Fixed: 2196048 --- utils/gps_extended_c.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/gps_extended_c.h b/utils/gps_extended_c.h index b7b1c09c..21eb5d55 100644 --- a/utils/gps_extended_c.h +++ b/utils/gps_extended_c.h @@ -1495,7 +1495,7 @@ typedef void (*LocAgpsCloseResultCb)(bool isSuccess, AGpsExtType agpsType, void* #define LOC_IPC_XTRA "/dev/socket/location/xtra/socket_xtra" #define SOCKET_DIR_LOCATION "/dev/socket/location/" -#define SOCKET_DIR_EHUB "/dev/socket/location/ehub" +#define SOCKET_DIR_EHUB "/dev/socket/location/ehub/" #define SOCKET_TO_LOCATION_HAL_DAEMON "/dev/socket/location/hal_daemon" #define SOCKET_DIR_TO_CLIENT "/dev/socket/loc_client/" From f8bd86f0124cb38152702ac186a77ef54757cc17 Mon Sep 17 00:00:00 2001 From: Katz Yamada Date: Thu, 3 May 2018 11:41:51 -0700 Subject: [PATCH 04/11] fix: Add intermediate fixes in gnss debug report Include intermediate location fix info in gnss debug report that is cached in SystemStatus in addition to final fixes, so that the gnss debug report should always hold the latest information. Change-Id: I60aef92cf6d143a1b4f4b510ca2113887d051dcc CRs-Fixed: 2230415 --- gnss/GnssAdapter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp index 0c0d8d00..fd406ac8 100644 --- a/gnss/GnssAdapter.cpp +++ b/gnss/GnssAdapter.cpp @@ -2179,7 +2179,8 @@ GnssAdapter::reportPositionEvent(const UlpLocation& ulpLocation, inline virtual void proc() const { // extract bug report info - this returns true if consumed by systemstatus SystemStatus* s = mAdapter.getSystemStatus(); - if ((nullptr != s) && (LOC_SESS_SUCCESS == mStatus)){ + if ((nullptr != s) && + ((LOC_SESS_SUCCESS == mStatus) || (LOC_SESS_INTERMEDIATE == mStatus))){ s->eventPosition(mUlpLocation, mLocationExtended); } mAdapter.reportPosition(mUlpLocation, mLocationExtended, mStatus, mTechMask); From 39837685982e73f6ea0be762eaa686577265e053 Mon Sep 17 00:00:00 2001 From: Kevin Tang Date: Fri, 23 Mar 2018 23:00:16 -0700 Subject: [PATCH 05/11] renamed DataItemIndex and ClientIndex files and moved them into utils. Change-Id: I138471168bf58d2cf09c6a435088edea29a567d0 CRs-Fixed: 2218519 --- core/data-items/common/ClientIndex.h => utils/LocListMap.h | 0 .../common/DataItemIndex.h => utils/LocUnorderedSetMap.h | 0 utils/Makefile.am | 3 ++- 3 files changed, 2 insertions(+), 1 deletion(-) rename core/data-items/common/ClientIndex.h => utils/LocListMap.h (100%) rename core/data-items/common/DataItemIndex.h => utils/LocUnorderedSetMap.h (100%) diff --git a/core/data-items/common/ClientIndex.h b/utils/LocListMap.h similarity index 100% rename from core/data-items/common/ClientIndex.h rename to utils/LocListMap.h diff --git a/core/data-items/common/DataItemIndex.h b/utils/LocUnorderedSetMap.h similarity index 100% rename from core/data-items/common/DataItemIndex.h rename to utils/LocUnorderedSetMap.h diff --git a/utils/Makefile.am b/utils/Makefile.am index 3801fdd4..33afc1be 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -28,7 +28,8 @@ libgps_utils_la_h_sources = \ gps_extended_c.h \ gps_extended.h \ loc_gps.h \ - log_util.h + log_util.h \ + LocUnorderedSetMap.h libgps_utils_la_c_sources = \ linked_list.c \ From 0c73d4037677e1cb191001020ca3ddab46174706 Mon Sep 17 00:00:00 2001 From: Kevin Tang Date: Fri, 23 Mar 2018 22:57:51 -0700 Subject: [PATCH 06/11] changed SystemStatusOsObserver to allow clients to subscribe before subscription obj arrives, and also simplified ClientIndex and DataItemIndex implementation significantly. Change-Id: I092f344e688fa698aa98795b8a8f0c1ba8fcd9e4 CRs-Fixed: 2218519 --- core/Android.mk | 3 - core/Makefile.am | 3 - core/SystemStatus.cpp | 4 +- core/SystemStatusOsObserver.cpp | 623 ++++++++++------------- core/SystemStatusOsObserver.h | 94 ++-- core/data-items/common/ClientIndex.cpp | 172 ------- core/data-items/common/DataItemIndex.cpp | 203 -------- core/data-items/common/IClientIndex.h | 83 --- core/data-items/common/IDataItemIndex.h | 94 ---- core/data-items/common/IndexFactory.cpp | 64 --- core/data-items/common/IndexFactory.h | 48 -- utils/LocListMap.h | 70 --- utils/LocUnorderedSetMap.h | 166 +++++- 13 files changed, 473 insertions(+), 1154 deletions(-) delete mode 100644 core/data-items/common/ClientIndex.cpp delete mode 100644 core/data-items/common/DataItemIndex.cpp delete mode 100644 core/data-items/common/IClientIndex.h delete mode 100644 core/data-items/common/IDataItemIndex.h delete mode 100644 core/data-items/common/IndexFactory.cpp delete mode 100644 core/data-items/common/IndexFactory.h delete mode 100644 utils/LocListMap.h diff --git a/core/Android.mk b/core/Android.mk index 1374b6c0..82660d5e 100644 --- a/core/Android.mk +++ b/core/Android.mk @@ -31,9 +31,6 @@ LOCAL_SRC_FILES += \ LocDualContext.cpp \ loc_core_log.cpp \ data-items/DataItemsFactoryProxy.cpp \ - data-items/common/ClientIndex.cpp \ - data-items/common/DataItemIndex.cpp \ - data-items/common/IndexFactory.cpp \ SystemStatusOsObserver.cpp \ SystemStatus.cpp diff --git a/core/Makefile.am b/core/Makefile.am index 78ae76b0..cf8d9ff3 100644 --- a/core/Makefile.am +++ b/core/Makefile.am @@ -38,9 +38,6 @@ libloc_core_la_c_sources = \ LocDualContext.cpp \ loc_core_log.cpp \ data-items/DataItemsFactoryProxy.cpp \ - data-items/common/ClientIndex.cpp \ - data-items/common/DataItemIndex.cpp \ - data-items/common/IndexFactory.cpp \ SystemStatusOsObserver.cpp \ SystemStatus.cpp diff --git a/core/SystemStatus.cpp b/core/SystemStatus.cpp index 6eb99683..e12d9f32 100644 --- a/core/SystemStatus.cpp +++ b/core/SystemStatus.cpp @@ -1694,9 +1694,7 @@ bool SystemStatus::eventConnectionStatus(bool connected, int8_t type) // send networkinof dataitem to systemstatus observer clients SystemStatusNetworkInfo s(type, "", "", false, connected, false); - list dl(0); - dl.push_back(&s); - mSysStatusObsvr.notify(dl); + mSysStatusObsvr.notify({&s}); } return true; } diff --git a/core/SystemStatusOsObserver.cpp b/core/SystemStatusOsObserver.cpp index 2fdd19f1..0f6d2289 100644 --- a/core/SystemStatusOsObserver.cpp +++ b/core/SystemStatusOsObserver.cpp @@ -32,28 +32,20 @@ #include #include #include -#include -#include -#include #include namespace loc_core { -SystemStatusOsObserver::SystemStatusOsObserver( - SystemStatus* systemstatus, const MsgTask* msgTask) : - mSystemStatus(systemstatus), - mAddress("SystemStatusOsObserver"), -#ifdef USE_GLIB - mBackHaulConnectReqCount(0), -#endif - mClientIndex(IndexFactory :: createClientIndex()), - mDataItemIndex(IndexFactory :: createDataItemIndex()) -{ - mContext.mMsgTask = msgTask; +template +COUT SystemStatusOsObserver::containerTransfer(CINT& inContainer) { + COUT outContainer(0); + for (auto item : inContainer) { + outContainer.insert(outContainer.begin(), item); + } + return outContainer; } -SystemStatusOsObserver::~SystemStatusOsObserver() -{ +SystemStatusOsObserver::~SystemStatusOsObserver() { // Close data-item library handle DataItemsFactoryProxy::closeDataItemLibraryHandle(); @@ -65,290 +57,238 @@ SystemStatusOsObserver::~SystemStatusOsObserver() } mDataItemCache.clear(); - delete mClientIndex; - delete mDataItemIndex; } void SystemStatusOsObserver::setSubscriptionObj(IDataItemSubscription* subscriptionObj) { - mContext.mSubscriptionObj = subscriptionObj; + struct SetSubsObj : public LocMsg { + ObserverContext& mContext; + IDataItemSubscription* mSubsObj; + inline SetSubsObj(ObserverContext& context, IDataItemSubscription* subscriptionObj) : + mContext(context), mSubsObj(subscriptionObj) {} + void proc() const { + mContext.mSubscriptionObj = mSubsObj; - LOC_LOGD("Request cache size - Subscribe:%zu RequestData:%zu", - mSubscribeReqCache.size(), mReqDataCache.size()); - - // we have received the subscription object. process cached requests - // process - subscribe request cache - for (auto each : mSubscribeReqCache) { - subscribe(each.second, each.first); - } - // process - requestData request cache - for (auto each : mReqDataCache) { - requestData(each.second, each.first); - } -} - -// Helper to cache requests subscribe and requestData till subscription obj is obtained -void SystemStatusOsObserver::cacheObserverRequest(ObserverReqCache& reqCache, - const list& l, IDataItemObserver* client) -{ - ObserverReqCache::iterator dicIter = reqCache.find(client); - if (dicIter != reqCache.end()) { - // found - list difference(0); - set_difference(l.begin(), l.end(), - dicIter->second.begin(), dicIter->second.end(), - inserter(difference, difference.begin())); - if (!difference.empty()) { - difference.sort(); - dicIter->second.merge(difference); - dicIter->second.unique(); + if (!mContext.mSSObserver->mDataItemToClients.empty()) { + list dis( + containerTransfer, list>( + mContext.mSSObserver->mDataItemToClients.getKeys())); + mContext.mSubscriptionObj->subscribe(dis, mContext.mSSObserver); + mContext.mSubscriptionObj->requestData(dis, mContext.mSSObserver); + } } - } - else { - // not found - reqCache[client] = l; + }; + + if (nullptr == subscriptionObj) { + LOC_LOGw("subscriptionObj is NULL"); + } else { + mContext.mMsgTask->sendMsg(new SetSubsObj(mContext, subscriptionObj)); } } /****************************************************************************** IDataItemSubscription Overrides ******************************************************************************/ -void SystemStatusOsObserver::subscribe( - const list& l, IDataItemObserver* client) +void SystemStatusOsObserver::subscribe(const list& l, IDataItemObserver* client, + bool toRequestData) { - if (nullptr == mContext.mSubscriptionObj) { - LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__); - cacheObserverRequest(mSubscribeReqCache, l, client); - return; - } - struct HandleSubscribeReq : public LocMsg { - HandleSubscribeReq(SystemStatusOsObserver* parent, - const list& l, IDataItemObserver* client) : - mParent(parent), mClient(client), mDataItemList(l) {} - virtual ~HandleSubscribeReq() {} + inline HandleSubscribeReq(SystemStatusOsObserver* parent, + list& l, IDataItemObserver* client, bool requestData) : + mParent(parent), mClient(client), + mDataItemSet(containerTransfer, unordered_set>(l)), + mToRequestData(requestData) {} + void proc() const { + unordered_set dataItemsToSubscribe(0); + mParent->mDataItemToClients.add(mDataItemSet, {mClient}, &dataItemsToSubscribe); + mParent->mClientToDataItems.add(mClient, mDataItemSet); - if (mDataItemList.empty()) { - LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); - return; - } + mParent->sendCachedDataItems(mDataItemSet, mClient); - // Handle First Response - list pendingFirstResponseList(0); - mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList); - - // Do not send first response for only pendingFirstResponseList, - // instead send for all the data items (present in the cache) that - // have been subscribed for each time. - mParent->sendFirstResponse(mDataItemList, mClient); - - list yetToSubscribeDataItemsList(0); - mParent->mDataItemIndex->add(mClient, mDataItemList, yetToSubscribeDataItemsList); - - // Send subscription list to framework - if (!yetToSubscribeDataItemsList.empty()) { - mParent->mContext.mSubscriptionObj->subscribe(yetToSubscribeDataItemsList, mParent); + // Send subscription set to framework + if (nullptr != mParent->mContext.mSubscriptionObj && !dataItemsToSubscribe.empty()) { LOC_LOGD("Subscribe Request sent to framework for the following"); - mParent->logMe(yetToSubscribeDataItemsList); + mParent->logMe(dataItemsToSubscribe); + + if (mToRequestData) { + mParent->mContext.mSubscriptionObj->requestData( + containerTransfer, list>( + std::move(dataItemsToSubscribe)), + mParent); + } else { + mParent->mContext.mSubscriptionObj->subscribe( + containerTransfer, list>( + std::move(dataItemsToSubscribe)), + mParent); + } } } - SystemStatusOsObserver* mParent; + mutable SystemStatusOsObserver* mParent; IDataItemObserver* mClient; - const list mDataItemList; + const unordered_set mDataItemSet; + bool mToRequestData; }; - mContext.mMsgTask->sendMsg(new (nothrow) HandleSubscribeReq(this, l, client)); + + if (l.empty() || nullptr == client) { + LOC_LOGw("Data item set is empty or client is nullptr"); + } else { + mContext.mMsgTask->sendMsg( + new HandleSubscribeReq(this, (list&)l, client, toRequestData)); + } } void SystemStatusOsObserver::updateSubscription( const list& l, IDataItemObserver* client) { - if (nullptr == mContext.mSubscriptionObj) { - LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); - return; - } - struct HandleUpdateSubscriptionReq : public LocMsg { HandleUpdateSubscriptionReq(SystemStatusOsObserver* parent, - const list& l, IDataItemObserver* client) : - mParent(parent), mClient(client), mDataItemList(l) {} - virtual ~HandleUpdateSubscriptionReq() {} + list& l, IDataItemObserver* client) : + mParent(parent), mClient(client), + mDataItemSet(containerTransfer, unordered_set>(l)) {} + void proc() const { - if (mDataItemList.empty()) { - LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); - return; - } - - list currentlySubscribedList(0); - mParent->mClientIndex->getSubscribedList(mClient, currentlySubscribedList); - - list removeDataItemList(0); - set_difference(currentlySubscribedList.begin(), currentlySubscribedList.end(), - mDataItemList.begin(), mDataItemList.end(), - inserter(removeDataItemList,removeDataItemList.begin())); - - // Handle First Response - list pendingFirstResponseList(0); - mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList); + unordered_set dataItemsToSubscribe(0); + unordered_set dataItemsToUnsubscribe(0); + unordered_set clients({mClient}); + // below removes clients from all entries keyed with the return of the + // mClientToDataItems.update() call. If leaving an empty set of clients as the + // result, the entire entry will be removed. dataItemsToUnsubscribe will be + // populated to keep the keys of the removed entries. + mParent->mDataItemToClients.trimOrRemove( + // this call updates map; removes + // the DataItemId's that are not new to the clietn from mDataItemSet; + // and returns a set of mDataItemSet's that are no longer used by client. + // This unused set of mDataItemSet's is passed to trimOrRemove method of + // map to remove the client from the + // corresponding entries, and gets a set of the entries that are + // removed from the map as a result. + mParent->mClientToDataItems.update(mClient, + (unordered_set&)mDataItemSet), + clients, &dataItemsToUnsubscribe, nullptr); + // below adds mClient to map, and populates + // new keys added to that map, which are DataItemIds to be subscribed. + mParent->mDataItemToClients.add(mDataItemSet, clients, &dataItemsToSubscribe); // Send First Response - mParent->sendFirstResponse(pendingFirstResponseList, mClient); + mParent->sendCachedDataItems(mDataItemSet, mClient); - list yetToSubscribeDataItemsList(0); - mParent->mDataItemIndex->add( - mClient, mDataItemList, yetToSubscribeDataItemsList); + if (nullptr != mParent->mContext.mSubscriptionObj) { + // Send subscription set to framework + if (!dataItemsToSubscribe.empty()) { + LOC_LOGD("Subscribe Request sent to framework for the following"); + mParent->logMe(dataItemsToSubscribe); - // Send subscription list to framework - if (!yetToSubscribeDataItemsList.empty()) { - mParent->mContext.mSubscriptionObj->subscribe( - yetToSubscribeDataItemsList, mParent); - LOC_LOGD("Subscribe Request sent to framework for the following"); - mParent->logMe(yetToSubscribeDataItemsList); - } + mParent->mContext.mSubscriptionObj->subscribe( + containerTransfer, list>( + std::move(dataItemsToSubscribe)), + mParent); + } - list unsubscribeList(0); - list unused(0); - mParent->mClientIndex->remove(mClient, removeDataItemList, unused); - - if (!mParent->mClientIndex->isSubscribedClient(mClient)) { - mParent->mDataItemIndex->remove( - list (1,mClient), unsubscribeList); - } - if (!unsubscribeList.empty()) { // Send unsubscribe to framework - mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent); - LOC_LOGD("Unsubscribe Request sent to framework for the following"); - mParent->logMe(unsubscribeList); + if (!dataItemsToUnsubscribe.empty()) { + LOC_LOGD("Unsubscribe Request sent to framework for the following"); + mParent->logMe(dataItemsToUnsubscribe); + + mParent->mContext.mSubscriptionObj->unsubscribe( + containerTransfer, list>( + std::move(dataItemsToUnsubscribe)), + mParent); + } } } SystemStatusOsObserver* mParent; IDataItemObserver* mClient; - const list mDataItemList; + unordered_set mDataItemSet; }; - mContext.mMsgTask->sendMsg(new (nothrow) HandleUpdateSubscriptionReq(this, l, client)); -} -void SystemStatusOsObserver::requestData( - const list& l, IDataItemObserver* client) -{ - if (nullptr == mContext.mSubscriptionObj) { - LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__); - cacheObserverRequest(mReqDataCache, l, client); - return; + if (l.empty() || nullptr == client) { + LOC_LOGw("Data item set is empty or client is nullptr"); + } else { + mContext.mMsgTask->sendMsg( + new HandleUpdateSubscriptionReq(this, (list&)l, client)); } - - struct HandleRequestData : public LocMsg { - HandleRequestData(SystemStatusOsObserver* parent, - const list& l, IDataItemObserver* client) : - mParent(parent), mClient(client), mDataItemList(l) {} - virtual ~HandleRequestData() {} - void proc() const { - if (mDataItemList.empty()) { - LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); - return; - } - - list yetToSubscribeDataItemsList(0); - mParent->mClientIndex->add( - mClient, mDataItemList, yetToSubscribeDataItemsList); - mParent->mDataItemIndex->add( - mClient, mDataItemList, yetToSubscribeDataItemsList); - - // Send subscription list to framework - if (!mDataItemList.empty()) { - mParent->mContext.mSubscriptionObj->requestData(mDataItemList, mParent); - LOC_LOGD("Subscribe Request sent to framework for the following"); - mParent->logMe(yetToSubscribeDataItemsList); - } - } - SystemStatusOsObserver* mParent; - IDataItemObserver* mClient; - const list mDataItemList; - }; - mContext.mMsgTask->sendMsg(new (nothrow) HandleRequestData(this, l, client)); } void SystemStatusOsObserver::unsubscribe( const list& l, IDataItemObserver* client) { - if (nullptr == mContext.mSubscriptionObj) { - LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); - return; - } struct HandleUnsubscribeReq : public LocMsg { HandleUnsubscribeReq(SystemStatusOsObserver* parent, - const list& l, IDataItemObserver* client) : - mParent(parent), mClient(client), mDataItemList(l) {} - virtual ~HandleUnsubscribeReq() {} + list& l, IDataItemObserver* client) : + mParent(parent), mClient(client), + mDataItemSet(containerTransfer, unordered_set>(l)) {} + void proc() const { - if (mDataItemList.empty()) { - LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); - return; - } + unordered_set dataItemsUnusedByClient(0); + unordered_set clientToRemove(0); + mParent->mClientToDataItems.trimOrRemove({mClient}, mDataItemSet, &clientToRemove, + &dataItemsUnusedByClient); + unordered_set dataItemsToUnsubscribe(0); + mParent->mDataItemToClients.trimOrRemove(dataItemsUnusedByClient, {mClient}, + &dataItemsToUnsubscribe, nullptr); - list unsubscribeList(0); - list unused(0); - mParent->mClientIndex->remove(mClient, mDataItemList, unused); - - for (auto each : mDataItemList) { - list clientListSubs(0); - list clientListOut(0); - mParent->mDataItemIndex->remove( - each, list (1,mClient), clientListOut); - // check if there are any other subscribed client for this data item id - mParent->mDataItemIndex->getListOfSubscribedClients(each, clientListSubs); - if (clientListSubs.empty()) - { - LOC_LOGD("Client list subscribed is empty for dataitem - %d", each); - unsubscribeList.push_back(each); - } - } - - if (!unsubscribeList.empty()) { - // Send unsubscribe to framework - mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent); + if (nullptr != mParent->mContext.mSubscriptionObj && !dataItemsToUnsubscribe.empty()) { LOC_LOGD("Unsubscribe Request sent to framework for the following data items"); - mParent->logMe(unsubscribeList); + mParent->logMe(dataItemsToUnsubscribe); + + // Send unsubscribe to framework + mParent->mContext.mSubscriptionObj->unsubscribe( + containerTransfer, list>( + std::move(dataItemsToUnsubscribe)), + mParent); } } SystemStatusOsObserver* mParent; IDataItemObserver* mClient; - const list mDataItemList; + unordered_set mDataItemSet; }; - mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeReq(this, l, client)); + + if (l.empty() || nullptr == client) { + LOC_LOGw("Data item set is empty or client is nullptr"); + } else { + mContext.mMsgTask->sendMsg(new HandleUnsubscribeReq(this, (list&)l, client)); + } } void SystemStatusOsObserver::unsubscribeAll(IDataItemObserver* client) { - if (nullptr == mContext.mSubscriptionObj) { - LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); - return; - } - struct HandleUnsubscribeAllReq : public LocMsg { HandleUnsubscribeAllReq(SystemStatusOsObserver* parent, IDataItemObserver* client) : mParent(parent), mClient(client) {} - virtual ~HandleUnsubscribeAllReq() {} - void proc() const { - list clients(1, mClient); - list unsubscribeList(0); - if(0 == mParent->mClientIndex->remove(mClient)) { - return; - } - mParent->mDataItemIndex->remove(clients, unsubscribeList); - if (!unsubscribeList.empty()) { - // Send unsubscribe to framework - mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent); - LOC_LOGD("Unsubscribe Request sent to framework for the following data items"); - mParent->logMe(unsubscribeList); + void proc() const { + unordered_set diByClient = mParent->mClientToDataItems.getValSet(mClient); + if (!diByClient.empty()) { + unordered_set dataItemsToUnsubscribe; + mParent->mClientToDataItems.remove(mClient); + mParent->mDataItemToClients.trimOrRemove(diByClient, {mClient}, + &dataItemsToUnsubscribe, nullptr); + + if (!dataItemsToUnsubscribe.empty() && + nullptr != mParent->mContext.mSubscriptionObj) { + + LOC_LOGD("Unsubscribe Request sent to framework for the following data items"); + mParent->logMe(dataItemsToUnsubscribe); + + // Send unsubscribe to framework + mParent->mContext.mSubscriptionObj->unsubscribe( + containerTransfer, list>( + std::move(dataItemsToUnsubscribe)), + mParent); + } } } SystemStatusOsObserver* mParent; IDataItemObserver* mClient; }; - mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeAllReq(this, client)); + + if (nullptr == client) { + LOC_LOGw("Data item set is empty or client is nullptr"); + } else { + mContext.mMsgTask->sendMsg(new HandleUnsubscribeAllReq(this, client)); + } } /****************************************************************************** @@ -356,84 +296,78 @@ void SystemStatusOsObserver::unsubscribeAll(IDataItemObserver* client) ******************************************************************************/ void SystemStatusOsObserver::notify(const list& dlist) { - list dataItemList(0); - - for (auto each : dlist) { - string dv; - each->stringify(dv); - LOC_LOGD("notify: DataItem In Value:%s", dv.c_str()); - - IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId()); - if (nullptr == di) { - LOC_LOGE("Unable to create dataitem:%d", each->getId()); - return; - } - - // Copy contents into the newly created data item - di->copy(each); - - // Request systemstatus to record this dataitem in its cache - if (mSystemStatus->eventDataItemNotify(di)) { - // add this dataitem if updated from last one - dataItemList.push_back(di); - } - } - struct HandleNotify : public LocMsg { - HandleNotify(SystemStatusOsObserver* parent, const list& l) : - mParent(parent), mDList(l) {} - virtual ~HandleNotify() { - for (auto each : mDList) { - delete each; + HandleNotify(SystemStatusOsObserver* parent, vector& v) : + mParent(parent), mDiVec(std::move(v)) {} + + inline virtual ~HandleNotify() { + for (auto item : mDiVec) { + delete item; } } + void proc() const { // Update Cache with received data items and prepare // list of data items to be sent. - list dataItemIdsToBeSent(0); - for (auto item : mDList) { - bool dataItemUpdated = false; - mParent->updateCache(item, dataItemUpdated); - if (dataItemUpdated) { - dataItemIdsToBeSent.push_back(item->getId()); + unordered_set dataItemIdsToBeSent(0); + for (auto item : mDiVec) { + if (mParent->updateCache(item)) { + dataItemIdsToBeSent.insert(item->getId()); } } // Send data item to all subscribed clients - list clientList(0); + unordered_set clientSet(0); for (auto each : dataItemIdsToBeSent) { - list clients(0); - mParent->mDataItemIndex->getListOfSubscribedClients(each, clients); - for (auto each_cient: clients) { - clientList.push_back(each_cient); + auto clients = mParent->mDataItemToClients.getValSetPtr(each); + if (nullptr != clients) { + clientSet.insert(clients->begin(), clients->end()); } } - clientList.unique(); - for (auto client : clientList) { - list dataItemIdsSubscribedByThisClient(0); - list dataItemIdsToBeSentForThisClient(0); - mParent->mClientIndex->getSubscribedList( - client, dataItemIdsSubscribedByThisClient); - dataItemIdsSubscribedByThisClient.sort(); - dataItemIdsToBeSent.sort(); + for (auto client : clientSet) { + unordered_set dataItemIdsForThisClient( + mParent->mClientToDataItems.getValSet(client)); + for (auto id : dataItemIdsForThisClient) { + if (dataItemIdsToBeSent.find(id) == dataItemIdsToBeSent.end()) { + dataItemIdsForThisClient.erase(id); + } + } - set_intersection(dataItemIdsToBeSent.begin(), - dataItemIdsToBeSent.end(), - dataItemIdsSubscribedByThisClient.begin(), - dataItemIdsSubscribedByThisClient.end(), - inserter(dataItemIdsToBeSentForThisClient, - dataItemIdsToBeSentForThisClient.begin())); - - mParent->sendCachedDataItems(dataItemIdsToBeSentForThisClient, client); - dataItemIdsSubscribedByThisClient.clear(); - dataItemIdsToBeSentForThisClient.clear(); + mParent->sendCachedDataItems(dataItemIdsForThisClient, client); } } SystemStatusOsObserver* mParent; - const list mDList; + const vector mDiVec; }; - mContext.mMsgTask->sendMsg(new (nothrow) HandleNotify(this, dataItemList)); + + if (!dlist.empty()) { + vector dataItemVec(dlist.size()); + + for (auto each : dlist) { + IF_LOC_LOGD { + string dv; + each->stringify(dv); + LOC_LOGD("notify: DataItem In Value:%s", dv.c_str()); + } + + IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId()); + if (nullptr == di) { + LOC_LOGw("Unable to create dataitem:%d", each->getId()); + continue; + } + + // Copy contents into the newly created data item + di->copy(each); + + // add this dataitem if updated from last one + dataItemVec.push_back(di); + } + + if (!dataItemVec.empty()) { + mContext.mMsgTask->sendMsg(new HandleNotify(this, dataItemVec)); + } + } } /****************************************************************************** @@ -447,7 +381,7 @@ void SystemStatusOsObserver::turnOn(DataItemId dit, int timeOut) } // Check if data item exists in mActiveRequestCount - map::iterator citer = mActiveRequestCount.find(dit); + DataItemIdToInt::iterator citer = mActiveRequestCount.find(dit); if (citer == mActiveRequestCount.end()) { // Data item not found in map // Add reference count as 1 and add dataitem to map @@ -485,7 +419,7 @@ void SystemStatusOsObserver::turnOff(DataItemId dit) } // Check if data item exists in mActiveRequestCount - map::iterator citer = mActiveRequestCount.find(dit); + DataItemIdToInt::iterator citer = mActiveRequestCount.find(dit); if (citer != mActiveRequestCount.end()) { // found citer->second--; @@ -573,84 +507,65 @@ bool SystemStatusOsObserver::disconnectBackhaul() /****************************************************************************** Helpers ******************************************************************************/ -void SystemStatusOsObserver::sendFirstResponse( - const list& l, IDataItemObserver* to) -{ - if (l.empty()) { - LOC_LOGV("list is empty. Nothing to do. Exiting"); - return; - } - - string clientName; - to->getName(clientName); - list dataItems(0); - - for (auto each : l) { - map::const_iterator citer = mDataItemCache.find(each); - if (citer != mDataItemCache.end()) { - string dv; - citer->second->stringify(dv); - LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str()); - dataItems.push_back(citer->second); - } - } - if (dataItems.empty()) { - LOC_LOGV("No items to notify. Nothing to do. Exiting"); - return; - } - to->notify(dataItems); -} - void SystemStatusOsObserver::sendCachedDataItems( - const list& l, IDataItemObserver* to) + const unordered_set& s, IDataItemObserver* to) { - string clientName; - to->getName(clientName); - list dataItems(0); + if (nullptr == to) { + LOC_LOGv("client pointer is NULL."); + } else { + string clientName; + to->getName(clientName); + list dataItems(0); - for (auto each : l) { - string dv; - IDataItemCore* di = mDataItemCache[each]; - di->stringify(dv); - LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str()); - dataItems.push_back(di); + for (auto each : s) { + auto citer = mDataItemCache.find(each); + if (citer != mDataItemCache.end()) { + string dv; + citer->second->stringify(dv); + LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str()); + dataItems.push_front(citer->second); + } + } + + if (dataItems.empty()) { + LOC_LOGv("No items to notify."); + } else { + to->notify(dataItems); + } } - to->notify(dataItems); } -void SystemStatusOsObserver::updateCache(IDataItemCore* d, bool& dataItemUpdated) +bool SystemStatusOsObserver::updateCache(IDataItemCore* d) { - if (nullptr == d) { - return; - } + bool dataItemUpdated = false; - // Check if data item exists in cache - map::iterator citer = - mDataItemCache.find(d->getId()); - if (citer == mDataItemCache.end()) { - // New data item; not found in cache - IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId()); - if (nullptr == dataitem) { - return; + // Request systemstatus to record this dataitem in its cache + // if the return is false, it means that SystemStatus is not + // handling it, so SystemStatusOsObserver also doesn't. + // So it has to be true to proceed. + if (nullptr != d && mSystemStatus->eventDataItemNotify(d)) { + auto citer = mDataItemCache.find(d->getId()); + if (citer == mDataItemCache.end()) { + // New data item; not found in cache + IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId()); + if (nullptr != dataitem) { + // Copy the contents of the data item + dataitem->copy(d); + // Insert in mDataItemCache + mDataItemCache.insert(std::make_pair(d->getId(), dataitem)); + dataItemUpdated = true; + } + } else { + // Found in cache; Update cache if necessary + citer->second->copy(d, &dataItemUpdated); } - // Copy the contents of the data item - dataitem->copy(d); - pair cpair(d->getId(), dataitem); - // Insert in mDataItemCache - mDataItemCache.insert(cpair); - dataItemUpdated = true; - } - else { - // Found in cache; Update cache if necessary - if(0 == citer->second->copy(d, &dataItemUpdated)) { - return; + if (dataItemUpdated) { + LOC_LOGV("DataItem:%d updated:%d", d->getId(), dataItemUpdated); } } - if (dataItemUpdated) { - LOC_LOGV("DataItem:%d updated:%d", d->getId(), dataItemUpdated); - } + return dataItemUpdated; } } // namespace loc_core diff --git a/core/SystemStatusOsObserver.h b/core/SystemStatusOsObserver.h index 930ddc12..fd606063 100644 --- a/core/SystemStatusOsObserver.h +++ b/core/SystemStatusOsObserver.h @@ -41,6 +41,7 @@ #include #include #include +#include namespace loc_core { @@ -48,39 +49,57 @@ namespace loc_core SystemStatusOsObserver ******************************************************************************/ using namespace std; +using namespace loc_util; // Forward Declarations class IDataItemCore; -template class IClientIndex; -template class IDataItemIndex; +class SystemStatus; +class SystemStatusOsObserver; +typedef map> ObserverReqCache; +typedef LocUnorderedSetMap ClientToDataItems; +typedef LocUnorderedSetMap DataItemToClients; +typedef unordered_map DataItemIdToCore; +typedef unordered_map DataItemIdToInt; -struct SystemContext { +struct ObserverContext { IDataItemSubscription* mSubscriptionObj; IFrameworkActionReq* mFrameworkActionReqObj; const MsgTask* mMsgTask; + SystemStatusOsObserver* mSSObserver; - inline SystemContext() : - mSubscriptionObj(NULL), - mFrameworkActionReqObj(NULL), - mMsgTask(NULL) {} + inline ObserverContext(const MsgTask* msgTask, SystemStatusOsObserver* observer) : + mSubscriptionObj(NULL), mFrameworkActionReqObj(NULL), + mMsgTask(msgTask), mSSObserver(observer) {} }; -typedef map> ObserverReqCache; - // Clients wanting to get data from OS/Framework would need to // subscribe with OSObserver using IDataItemSubscription interface. // Such clients would need to implement IDataItemObserver interface // to receive data when it becomes available. -class SystemStatus; class SystemStatusOsObserver : public IOsObserver { public: // ctor - SystemStatusOsObserver( - SystemStatus* systemstatus, const MsgTask* msgTask); + inline SystemStatusOsObserver(SystemStatus* systemstatus, const MsgTask* msgTask) : + mSystemStatus(systemstatus), mContext(msgTask, this), + mAddress("SystemStatusOsObserver"), + mClientToDataItems(MAX_DATA_ITEM_ID), mDataItemToClients(MAX_DATA_ITEM_ID) +#ifdef USE_GLIB + , mBackHaulConnectReqCount(0) +#endif + { + } + // dtor ~SystemStatusOsObserver(); + template + static COUT containerTransfer(CINT& s); + template + inline static COUT containerTransfer(CINT&& s) { + return containerTransfer(s); + } + // To set the subscription object virtual void setSubscriptionObj(IDataItemSubscription* subscriptionObj); @@ -96,38 +115,40 @@ public: } // IDataItemSubscription Overrides - virtual void subscribe(const list& l, IDataItemObserver* client); - virtual void updateSubscription(const list& l, IDataItemObserver* client); - virtual void requestData(const list& l, IDataItemObserver* client); - virtual void unsubscribe(const list& l, IDataItemObserver* client); - virtual void unsubscribeAll(IDataItemObserver* client); + inline virtual void subscribe(const list& l, IDataItemObserver* client) override { + subscribe(l, client, false); + } + virtual void updateSubscription(const list& l, IDataItemObserver* client) override; + inline virtual void requestData(const list& l, IDataItemObserver* client) override { + subscribe(l, client, true); + } + virtual void unsubscribe(const list& l, IDataItemObserver* client) override; + virtual void unsubscribeAll(IDataItemObserver* client) override; // IDataItemObserver Overrides - virtual void notify(const list& dlist); - inline virtual void getName(string& name) { + virtual void notify(const list& dlist) override; + inline virtual void getName(string& name) override { name = mAddress; } // IFrameworkActionReq Overrides - virtual void turnOn(DataItemId dit, int timeOut = 0); - virtual void turnOff(DataItemId dit); + virtual void turnOn(DataItemId dit, int timeOut = 0) override; + virtual void turnOff(DataItemId dit) override; #ifdef USE_GLIB - virtual bool connectBackhaul(); + virtual bool connectBackhaul() override; virtual bool disconnectBackhaul(); #endif private: SystemStatus* mSystemStatus; - SystemContext mContext; + ObserverContext mContext; const string mAddress; - IClientIndex* mClientIndex; - IDataItemIndex* mDataItemIndex; - map mDataItemCache; - map mActiveRequestCount; + ClientToDataItems mClientToDataItems; + DataItemToClients mDataItemToClients; + DataItemIdToCore mDataItemCache; + DataItemIdToInt mActiveRequestCount; // Cache the subscribe and requestData till subscription obj is obtained - ObserverReqCache mSubscribeReqCache; - ObserverReqCache mReqDataCache; void cacheObserverRequest(ObserverReqCache& reqCache, const list& l, IDataItemObserver* client); #ifdef USE_GLIB @@ -135,13 +156,16 @@ private: int mBackHaulConnectReqCount; #endif + void subscribe(const list& l, IDataItemObserver* client, bool toRequestData); + // Helpers - void sendFirstResponse(const list& l, IDataItemObserver* to); - void sendCachedDataItems(const list& l, IDataItemObserver* to); - void updateCache(IDataItemCore* d, bool& dataItemUpdated); - inline void logMe(const list& l) { - for (auto id : l) { - LOC_LOGD("DataItem %d", id); + void sendCachedDataItems(const unordered_set& s, IDataItemObserver* to); + bool updateCache(IDataItemCore* d); + inline void logMe(const unordered_set& l) { + IF_LOC_LOGD { + for (auto id : l) { + LOC_LOGD("DataItem %d", id); + } } } }; diff --git a/core/data-items/common/ClientIndex.cpp b/core/data-items/common/ClientIndex.cpp deleted file mode 100644 index d4bd11e5..00000000 --- a/core/data-items/common/ClientIndex.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation, nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace loc_core; - -template -inline ClientIndex :: ClientIndex () {} - -template -inline ClientIndex :: ~ClientIndex () {} - -template -bool ClientIndex :: isSubscribedClient (CT client) { - bool result = false; - ENTRY_LOG (); - typename map < CT, list > :: iterator it = - mDataItemsPerClientMap.find (client); - if (it != mDataItemsPerClientMap.end ()) { - result = true; - } - EXIT_LOG_WITH_ERROR ("%d",result); - return result; -} - -template -void ClientIndex :: getSubscribedList (CT client, list & out) { - ENTRY_LOG (); - typename map < CT, list > :: iterator it = - mDataItemsPerClientMap.find (client); - if (it != mDataItemsPerClientMap.end ()) { - out = it->second; - } - EXIT_LOG_WITH_ERROR ("%d",0); -} - -template -int ClientIndex :: remove (CT client) { - int result = 0; - ENTRY_LOG (); - mDataItemsPerClientMap.erase (client); - EXIT_LOG_WITH_ERROR ("%d",result); - return result; -} - -template -void ClientIndex :: remove (const list & r, list & out) { - ENTRY_LOG (); - typename map < CT, list > :: iterator dicIter = - mDataItemsPerClientMap.begin (); - while (dicIter != mDataItemsPerClientMap.end()) { - typename list :: const_iterator it = r.begin (); - for (; it != r.end (); ++it) { - typename list :: iterator iter = - find (dicIter->second.begin (), dicIter->second.end (), *it); - if (iter != dicIter->second.end ()) { - dicIter->second.erase (iter); - } - } - if (dicIter->second.empty ()) { - out.push_back (dicIter->first); - // Post-increment operator increases the iterator but returns the - // prevous one that will be invalidated by erase() - mDataItemsPerClientMap.erase (dicIter++); - } else { - ++dicIter; - } - } - EXIT_LOG_WITH_ERROR ("%d",0); -} - -template -void ClientIndex :: remove -( - CT client, - const list & r, - list & out -) -{ - ENTRY_LOG (); - typename map < CT, list > :: iterator dicIter = - mDataItemsPerClientMap.find (client); - if (dicIter != mDataItemsPerClientMap.end ()) { - set_intersection (dicIter->second.begin (), dicIter->second.end (), - r.begin (), r.end (), - inserter (out,out.begin ())); - if (!out.empty ()) { - typename list :: iterator it = out.begin (); - for (; it != out.end (); ++it) { - dicIter->second.erase (find (dicIter->second.begin (), - dicIter->second.end (), - *it)); - } - } - if (dicIter->second.empty ()) { - mDataItemsPerClientMap.erase (dicIter); - EXIT_LOG_WITH_ERROR ("%d",0); - } - } - EXIT_LOG_WITH_ERROR ("%d",0); -} - -template -void ClientIndex :: add -( - CT client, - const list & l, - list & out -) -{ - ENTRY_LOG (); - list difference; - typename map < CT, list > :: iterator dicIter = - mDataItemsPerClientMap.find (client); - if (dicIter != mDataItemsPerClientMap.end ()) { - set_difference (l.begin (), l.end (), - dicIter->second.begin (), dicIter->second.end (), - inserter (difference,difference.begin ())); - if (!difference.empty ()) { - difference.sort (); - out = difference; - dicIter->second.merge (difference); - dicIter->second.unique (); - } - } else { - out = l; - pair < CT, list > dicnpair (client, out); - mDataItemsPerClientMap.insert (dicnpair); - } - EXIT_LOG_WITH_ERROR ("%d",0); -} - -// Explicit instantiation must occur in same namespace where class is defined -namespace loc_core -{ - template class ClientIndex ; - template class ClientIndex ; -} diff --git a/core/data-items/common/DataItemIndex.cpp b/core/data-items/common/DataItemIndex.cpp deleted file mode 100644 index 462bf748..00000000 --- a/core/data-items/common/DataItemIndex.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation, nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace loc_core; - -template -inline DataItemIndex :: DataItemIndex () {} - -template -inline DataItemIndex :: ~DataItemIndex () {} - -template -void DataItemIndex :: getListOfSubscribedClients - ( - DIT id, - list & out -) -{ - typename map < DIT, list > :: iterator cdiIter = - mClientsPerDataItemMap.find (id); - if (cdiIter != mClientsPerDataItemMap.end ()) { - out = cdiIter->second; - } -} - - -template -int DataItemIndex :: remove (DIT id) { - int result = 0; - ENTRY_LOG (); - mClientsPerDataItemMap.erase (id); - EXIT_LOG_WITH_ERROR ("%d",result); - return result; -} - -template -void DataItemIndex :: remove (const list & r, list & out) { - ENTRY_LOG (); - typename map < DIT, list > :: iterator cdiIter = - mClientsPerDataItemMap.begin (); - while (cdiIter != mClientsPerDataItemMap.end()) { - typename list :: const_iterator it = r.begin (); - for (; it != r.end (); ++it) { - typename list :: iterator iter = - find - ( - cdiIter->second.begin (), - cdiIter->second.end (), - *it - ); - if (iter != cdiIter->second.end ()) { - cdiIter->second.erase (iter); - } - } - - if (cdiIter->second.empty ()) { - out.push_back (cdiIter->first); - // Post-increment operator increases the iterator but returns the - // prevous one that will be invalidated by erase() - mClientsPerDataItemMap.erase (cdiIter++); - } else { - ++cdiIter; - } - } - EXIT_LOG_WITH_ERROR ("%d",0); -} - -template -void DataItemIndex :: remove -( - DIT id, - const list & r, - list & out -) -{ - ENTRY_LOG (); - - typename map < DIT, list > :: iterator cdiIter = - mClientsPerDataItemMap.find (id); - if (cdiIter != mClientsPerDataItemMap.end ()) { - set_intersection (cdiIter->second.begin (), cdiIter->second.end (), - r.begin (), r.end (), - inserter (out, out.begin ())); - if (!out.empty ()) { - typename list :: iterator it = out.begin (); - for (; it != out.end (); ++it) { - cdiIter->second.erase (find (cdiIter->second.begin (), - cdiIter->second.end (), - *it)); - } - } - if (cdiIter->second.empty ()) { - mClientsPerDataItemMap.erase (cdiIter); - EXIT_LOG_WITH_ERROR ("%d",0); - } - } - EXIT_LOG_WITH_ERROR ("%d",0); -} - -template -void DataItemIndex :: add -( - DIT id, - const list & l, - list & out -) -{ - ENTRY_LOG (); - list difference; - typename map < DIT, list > :: iterator cdiIter = - mClientsPerDataItemMap.find (id); - if (cdiIter != mClientsPerDataItemMap.end ()) { - set_difference (l.begin (), l.end (), - cdiIter->second.begin (), cdiIter->second.end (), - inserter (difference, difference.begin ())); - if (!difference.empty ()) { - difference.sort (); - out = difference; - cdiIter->second.merge (difference); - } - } else { - out = l; - pair < DIT, list > cndipair (id, out); - mClientsPerDataItemMap.insert (cndipair); - } - EXIT_LOG_WITH_ERROR ("%d",0); -} - -template -void DataItemIndex :: add -( - CT client, - const list & l, - list & out -) -{ - ENTRY_LOG (); - typename map < DIT, list > :: iterator cdiIter; - typename list :: const_iterator it = l.begin (); - for (; it != l.end (); ++it) { - cdiIter = mClientsPerDataItemMap.find (*it); - if (cdiIter == mClientsPerDataItemMap.end ()) { - out.push_back (*it); - pair < DIT, list > cndiPair (*it, list (1, client)); - mClientsPerDataItemMap.insert (cndiPair); - } else { - typename list :: iterator clientIter = - find - ( - cdiIter->second.begin (), - cdiIter->second.end (), - client - ); - if (clientIter == cdiIter->second.end()) { - cdiIter->second.push_back (client); - } - } - } - EXIT_LOG_WITH_ERROR ("%d",0); -} - -// Explicit instantiation must occur in same namespace where class is defined -namespace loc_core -{ - template class DataItemIndex ; - template class DataItemIndex ; -} diff --git a/core/data-items/common/IClientIndex.h b/core/data-items/common/IClientIndex.h deleted file mode 100644 index 0272e7b9..00000000 --- a/core/data-items/common/IClientIndex.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation, nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef __ICLIENTINDEX_H__ -#define __ICLIENTINDEX_H__ - -#include - -namespace loc_core -{ - -template - -class IClientIndex { -public: - - // Checks if client is subscribed - virtual bool isSubscribedClient (CT client) = 0; - - // gets subscription list - virtual void getSubscribedList (CT client, std :: list & out) = 0; - - // removes an entry - virtual int remove (CT client) = 0; - - // removes std :: list of data items and returns a list of clients - // removed if any. - virtual void remove - ( - const std :: list & r, - std :: list & out - ) = 0; - - // removes list of data items indexed by client and returns list - // of data items removed if any. - virtual void remove - ( - CT client, - const std :: list & r, - std :: list & out - ) = 0; - - // adds/modifies entry in map and returns new data items added. - virtual void add - ( - CT client, - const std :: list & l, - std :: list & out - ) = 0; - - // dtor - virtual ~IClientIndex () {} -}; - -} // namespace loc_core - -#endif // #ifndef __ICLIENTINDEX_H__ diff --git a/core/data-items/common/IDataItemIndex.h b/core/data-items/common/IDataItemIndex.h deleted file mode 100644 index 91855826..00000000 --- a/core/data-items/common/IDataItemIndex.h +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation, nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef __IDATAITEMINDEX_H__ -#define __IDATAITEMINDEX_H__ - -#include - -namespace loc_core -{ - -template - -class IDataItemIndex { - -public: - - // gets std :: list of subscribed clients - virtual void getListOfSubscribedClients - ( - DIT id, - std :: list & out - ) = 0; - - // removes an entry from - virtual int remove (DIT id) = 0; - - // removes list of clients and returns a list of data items - // removed if any. - virtual void remove - ( - const std :: list & r, - std :: list & out - ) = 0; - - // removes list of clients indexed by data item and returns list of - // clients removed if any. - virtual void remove - ( - DIT id, - const std :: list & r, - std :: list & out - ) = 0; - - // adds/modifies entry and returns new clients added - virtual void add - ( - DIT id, - const std :: list & l, - std :: list & out - ) = 0; - - // adds/modifies entry and returns yet to subscribe list of data items - virtual void add - ( - CT client, - const std :: list & l, - std :: list & out - ) = 0; - - // dtor - virtual ~IDataItemIndex () {} -}; - -} // namespace loc_core - -#endif // #ifndef __IDATAITEMINDEX_H__ - diff --git a/core/data-items/common/IndexFactory.cpp b/core/data-items/common/IndexFactory.cpp deleted file mode 100644 index cf494752..00000000 --- a/core/data-items/common/IndexFactory.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation, nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using loc_core::IClientIndex; -using loc_core::IDataItemIndex; -using loc_core::IDataItemObserver; -using namespace loc_core; - -template -inline IClientIndex * IndexFactory :: createClientIndex -() -{ - return new (nothrow) ClientIndex (); -} - -template -inline IDataItemIndex * IndexFactory :: createDataItemIndex -() -{ - return new (nothrow) DataItemIndex (); -} - -// Explicit instantiation must occur in same namespace where class is defined -namespace loc_core -{ - template class IndexFactory ; - template class IndexFactory ; -} diff --git a/core/data-items/common/IndexFactory.h b/core/data-items/common/IndexFactory.h deleted file mode 100644 index 9a2070e9..00000000 --- a/core/data-items/common/IndexFactory.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation, nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef __INDEXFACTORY_H__ -#define __INDEXFACTORY_H__ - -#include -#include - -namespace loc_core -{ -template -class IndexFactory { - -public: - static IClientIndex * createClientIndex (); - static IDataItemIndex * createDataItemIndex (); -}; - -} // namespace loc_core - -#endif // #ifndef __INDEXFACTORY_H__ diff --git a/utils/LocListMap.h b/utils/LocListMap.h deleted file mode 100644 index feccb059..00000000 --- a/utils/LocListMap.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation, nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ -#ifndef __CLIENTINDEX_H__ -#define __CLIENTINDEX_H__ - -#include -#include -#include - -using loc_core::IClientIndex; - -namespace loc_core -{ - -template - -class ClientIndex : public IClientIndex { - -public: - - ClientIndex (); - - ~ClientIndex (); - - bool isSubscribedClient (CT client); - - void getSubscribedList (CT client, std :: list & out); - - int remove (CT client); - - void remove (const std :: list & r, std :: list & out); - - void remove (CT client, const std :: list & r, std :: list & out); - - void add (CT client, const std :: list & l, std :: list & out); - -private: - //Data members - std :: map < CT , std :: list > mDataItemsPerClientMap; -}; - -} // namespace loc_core - -#endif // #ifndef __CLIENTINDEX_H__ diff --git a/utils/LocUnorderedSetMap.h b/utils/LocUnorderedSetMap.h index d72e89eb..87481348 100644 --- a/utils/LocUnorderedSetMap.h +++ b/utils/LocUnorderedSetMap.h @@ -26,45 +26,167 @@ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ +#ifndef __LOC_UNORDERDED_SETMAP_H__ +#define __LOC_UNORDERDED_SETMAP_H__ -#ifndef __DATAITEMINDEX_H__ -#define __DATAITEMINDEX_H__ +#include +#include +#include -#include -#include -#include +using std::unordered_set; +using std::unordered_map; -using loc_core::IDataItemIndex; +namespace loc_util { -namespace loc_core -{ +// Trim from *fromSet* any elements that also exist in *rVals*. +// The optional *goneVals*, if not null, will be populated with removed elements. +template +inline static void trimSet(unordered_set& fromSet, const unordered_set& rVals, + unordered_set* goneVals) { + for (auto val : rVals) { + if (fromSet.erase(val) > 0 && nullptr != goneVals) { + goneVals->insert(val); + } + } +} -template +// this method is destructive to the input unordered_sets. +// the return set is the interset extracted out from the two input sets, *s1* and *s2*. +// *s1* and *s2* will be left with the intersect removed from them. +template +static unordered_set removeAndReturnInterset(unordered_set& s1, unordered_set& s2) { + unordered_set common(0); + for (auto b = s2.begin(); b != s2.end(); b++) { + auto a = find(s1.begin(), s1.end(), *b); + if (a != s1.end()) { + // this is a common item of both l1 and l2, remove from both + // but after we add to common + common.insert(*a); + s1.erase(a); + s2.erase(b); + } + } + return common; +} -class DataItemIndex : public IDataItemIndex { +template +class LocUnorderedSetMap { + unordered_map> mMap; + + + // Trim the VALs pointed to by *iter*, with everything that also exist in *rVals*. + // If the set becomes empty, remove the map entry. *goneVals*, if not null, records + // the trimmed VALs. + bool trimOrRemove(typename unordered_map>::iterator iter, + const unordered_set& rVals, unordered_set* goneVals) { + trimSet(iter->second, rVals, goneVals); + bool removeEntry = (iter->second.empty()); + if (removeEntry) { + mMap.erase(iter); + } + return removeEntry; + } public: + inline LocUnorderedSetMap() {} + inline LocUnorderedSetMap(size_t size) : mMap(size) {} - DataItemIndex (); + inline bool empty() { return mMap.empty(); } - ~DataItemIndex (); + // This gets the raw pointer to the VALs pointed to by *key* + // If the entry is not in the map, nullptr will be returned. + inline unordered_set* getValSetPtr(const KEY& key) { + auto entry = mMap.find(key); + return (entry != mMap.end()) ? &(entry->second) : nullptr; + } - void getListOfSubscribedClients (DIT id, std :: list & out); + // This gets a copy of VALs pointed to by *key* + // If the entry is not in the map, an empty set will be returned. + inline unordered_set getValSet(const KEY& key) { + auto entry = mMap.find(key); + return (entry != mMap.end()) ? entry->second : unordered_set(0); + } - int remove (DIT id); + // This gets all the KEYs from the map + inline unordered_set getKeys() { + unordered_set keys(0); + for (auto entry : mMap) { + keys.insert(entry.first); + } + return keys; + } - void remove (const std :: list & r, std :: list & out); + inline bool remove(const KEY& key) { + return mMap.erase(key) > 0; + } - void remove (DIT id, const std :: list & r, std :: list & out); + // This looks into all the entries keyed by *keys*. Remove any VALs from the entries + // that also exist in *rVals*. If the entry is left with an empty set, the entry will + // be removed. The optional parameters *goneKeys* and *goneVals* will record the KEYs + // (or entries) and the collapsed VALs removed from the map, respectively. + inline void trimOrRemove(unordered_set&& keys, const unordered_set& rVals, + unordered_set* goneKeys, unordered_set* goneVals) { + trimOrRemove(keys, rVals, goneKeys, goneVals); + } + inline void trimOrRemove(unordered_set& keys, const unordered_set& rVals, + unordered_set* goneKeys, unordered_set* goneVals) { + for (auto key : keys) { + auto iter = mMap.find(key); + if (iter != mMap.end() && trimOrRemove(iter, rVals, goneVals) && nullptr != goneKeys) { + goneKeys->insert(iter->first); + } + } + } - void add (DIT id, const std :: list & l, std :: list & out); + // This adds all VALs from *newVals* to the map entry keyed by *key*. Or if it + // doesn't exist yet, add the set to the map. + bool add(const KEY& key, const unordered_set& newVals) { + bool newEntryAdded = false; + if (!newVals.empty()) { + auto iter = mMap.find(key); + if (iter != mMap.end()) { + iter->second.insert(newVals.begin(), newVals.end()); + } else { + mMap[key] = newVals; + newEntryAdded = true; + } + } + return newEntryAdded; + } - void add (CT client, const std :: list & l, std :: list & out); + // This adds to each of entries in the map keyed by *keys* with the VALs in the + // *enwVals*. If there new entries added (new key in *keys*), *newKeys*, if not + // null, would be populated with those keys. + inline void add(const unordered_set& keys, const unordered_set&& newVals, + unordered_set* newKeys) { + add(keys, newVals, newKeys); + } + inline void add(const unordered_set& keys, const unordered_set& newVals, + unordered_set* newKeys) { + for (auto key : keys) { + if (add(key, newVals) && nullptr != newKeys) { + newKeys->insert(key); + } + } + } -private: - std :: map < DIT, std :: list > mClientsPerDataItemMap; + // This puts *newVals* into the map keyed by *key*, and returns the VALs that are + // in effect removed from the keyed VAL set in the map entry. + // This call would also remove those same VALs from *newVals*. + inline unordered_set update(const KEY& key, unordered_set& newVals) { + unordered_set goneVals(0); + + if (newVals.empty()) { + mMap.erase(key); + } else { + auto curVals = mMap[key]; + mMap[key] = newVals; + goneVals = removeAndReturnInterset(curVals, newVals); + } + return goneVals; + } }; -} // namespace loc_core +} // namespace loc_util -#endif // #ifndef __DATAITEMINDEX_H__ +#endif // #ifndef __LOC_UNORDERDED_SETMAP_H__ From 7bbc063ad215234850406216d4fb3632aeb404e6 Mon Sep 17 00:00:00 2001 From: Kevin Tang Date: Mon, 9 Apr 2018 14:32:28 -0700 Subject: [PATCH 07/11] Fixed a number of issues with NetworkInfoDataItemBase There are a couple of issues. NetworkInfoDataItemBase objects might be from OsAgent or GnssLocationProvider. The two sources actually have mTypes defined differently. In addtion, when there are different types of connections such as wifi / mobile, getting connected / disconnected independently, clients need to be all notified correctly. Right now, if mConnected hasn't changed, no updates are send. For exmple, if mobile is connected, later wifi gets connected too, clients won't know. SystemStatus is also updated to get updated / colated informtion. In the above example, SystemStatus's top record would record as both mobile and wifi are connected. Change-Id: I1825902247fe1d4e6363f5e24a75be7e984d0dc4 CRs-Fixed: 2221114 --- core/SystemStatus.cpp | 113 +++++++++----------- core/SystemStatus.h | 43 +++++--- core/data-items/DataItemConcreteTypesBase.h | 32 +++--- gnss/XtraSystemStatusObserver.cpp | 26 +---- gnss/XtraSystemStatusObserver.h | 10 +- 5 files changed, 107 insertions(+), 117 deletions(-) diff --git a/core/SystemStatus.cpp b/core/SystemStatus.cpp index e12d9f32..5d5c4b08 100644 --- a/core/SystemStatus.cpp +++ b/core/SystemStatus.cpp @@ -1250,8 +1250,7 @@ IOsObserver* SystemStatus::getOsObserver() } SystemStatus::SystemStatus(const MsgTask* msgTask) : - mSysStatusObsvr(this, msgTask), - mConnected(false) + mSysStatusObsvr(this, msgTask) { int result = 0; ENTRY_LOG (); @@ -1301,17 +1300,10 @@ SystemStatus::SystemStatus(const MsgTask* msgTask) : /****************************************************************************** SystemStatus - storing dataitems ******************************************************************************/ -template -bool SystemStatus::setItemBaseinReport(TYPE_REPORT& report, const TYPE_ITEMBASE& s) -{ - TYPE_SYSTEMSTATUS_ITEM sout(s); - return setIteminReport(report, sout); -} - template -bool SystemStatus::setIteminReport(TYPE_REPORT& report, const TYPE_ITEM& s) +bool SystemStatus::setIteminReport(TYPE_REPORT& report, TYPE_ITEM&& s) { - if (!report.empty() && report.back().equals(s)) { + if (!report.empty() && report.back().equals(static_cast(s.collate(report.back())))) { // there is no change - just update reported timestamp report.back().mUtcReported = s.mUtcReported; return false; @@ -1449,94 +1441,92 @@ bool SystemStatus::eventDataItemNotify(IDataItemCore* dataitem) switch(dataitem->getId()) { case AIRPLANEMODE_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mAirplaneMode, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mAirplaneMode, + SystemStatusAirplaneMode(*(static_cast(dataitem)))); break; case ENH_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mENH, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mENH, + SystemStatusENH(*(static_cast(dataitem)))); break; case GPSSTATE_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mGPSState, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mGPSState, + SystemStatusGpsState(*(static_cast(dataitem)))); break; case NLPSTATUS_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mNLPStatus, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mNLPStatus, + SystemStatusNLPStatus(*(static_cast(dataitem)))); break; case WIFIHARDWARESTATE_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mWifiHardwareState, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mWifiHardwareState, + SystemStatusWifiHardwareState(*(static_cast(dataitem)))); break; case NETWORKINFO_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mNetworkInfo, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mNetworkInfo, + SystemStatusNetworkInfo(*(static_cast(dataitem)))); break; case RILSERVICEINFO_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mRilServiceInfo, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mRilServiceInfo, + SystemStatusServiceInfo(*(static_cast(dataitem)))); break; case RILCELLINFO_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mRilCellInfo, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mRilCellInfo, + SystemStatusRilCellInfo(*(static_cast(dataitem)))); break; case SERVICESTATUS_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mServiceStatus, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mServiceStatus, + SystemStatusServiceStatus(*(static_cast(dataitem)))); break; case MODEL_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mModel, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mModel, + SystemStatusModel(*(static_cast(dataitem)))); break; case MANUFACTURER_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mManufacturer, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mManufacturer, + SystemStatusManufacturer(*(static_cast(dataitem)))); break; case ASSISTED_GPS_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mAssistedGps, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mAssistedGps, + SystemStatusAssistedGps(*(static_cast(dataitem)))); break; case SCREEN_STATE_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mScreenState, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mScreenState, + SystemStatusScreenState(*(static_cast(dataitem)))); break; case POWER_CONNECTED_STATE_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mPowerConnectState, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mPowerConnectState, + SystemStatusPowerConnectState(*(static_cast(dataitem)))); break; case TIMEZONE_CHANGE_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mTimeZoneChange, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mTimeZoneChange, + SystemStatusTimeZoneChange(*(static_cast(dataitem)))); break; case TIME_CHANGE_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mTimeChange, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mTimeChange, + SystemStatusTimeChange(*(static_cast(dataitem)))); break; case WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID: - ret = setItemBaseinReport( - mCache.mWifiSupplicantStatus, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mWifiSupplicantStatus, + SystemStatusWifiSupplicantStatus(*(static_cast(dataitem)))); break; case SHUTDOWN_STATE_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mShutdownState, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mShutdownState, + SystemStatusShutdownState(*(static_cast(dataitem)))); break; case TAC_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mTac, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mTac, + SystemStatusTac(*(static_cast(dataitem)))); break; case MCCMNC_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mMccMnc, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mMccMnc, + SystemStatusMccMnc(*(static_cast(dataitem)))); break; case BTLE_SCAN_DATA_ITEM_ID: - ret = setItemBaseinReport(mCache.mBtDeviceScanDetail, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mBtDeviceScanDetail, + SystemStatusBtDeviceScanDetail(*(static_cast(dataitem)))); break; case BT_SCAN_DATA_ITEM_ID: - ret = setItemBaseinReport( - mCache.mBtLeDeviceScanDetail, - *(static_cast(dataitem))); + ret = setIteminReport(mCache.mBtLeDeviceScanDetail, + SystemStatusBtleDeviceScanDetail(*(static_cast(dataitem)))); break; default: break; @@ -1689,13 +1679,10 @@ bool SystemStatus::setDefaultGnssEngineStates(void) ******************************************************************************/ bool SystemStatus::eventConnectionStatus(bool connected, int8_t type) { - if (connected != mConnected) { - mConnected = connected; + // send networkinof dataitem to systemstatus observer clients + SystemStatusNetworkInfo s(type, "", "", false, connected, false); + mSysStatusObsvr.notify({&s}); - // send networkinof dataitem to systemstatus observer clients - SystemStatusNetworkInfo s(type, "", "", false, connected, false); - mSysStatusObsvr.notify({&s}); - } return true; } diff --git a/core/SystemStatus.h b/core/SystemStatus.h index 9500264d..1c3adc84 100644 --- a/core/SystemStatus.h +++ b/core/SystemStatus.h @@ -77,8 +77,11 @@ public: mUtcTime.tv_nsec = tv.tv_nsec; mUtcReported = mUtcTime; }; - virtual ~SystemStatusItemBase() { }; - virtual void dump(void) { }; + virtual ~SystemStatusItemBase() {}; + inline virtual SystemStatusItemBase& collate(SystemStatusItemBase&) { + return *this; + } + virtual void dump(void) {}; }; class SystemStatusLocation : public SystemStatusItemBase @@ -93,7 +96,7 @@ public: const GpsLocationExtended& locationEx) : mValid(true), mLocation(location), - mLocationEx(locationEx) { } + mLocationEx(locationEx) {} bool equals(const SystemStatusLocation& peer); void dump(void); }; @@ -457,6 +460,7 @@ public: class SystemStatusNetworkInfo : public SystemStatusItemBase, public NetworkInfoDataItemBase { + NetworkInfoDataItemBase* mSrcObjPtr; public: inline SystemStatusNetworkInfo( int32_t type=0, @@ -466,18 +470,21 @@ public: bool connected=false, bool roaming=false) : NetworkInfoDataItemBase( + (NetworkType)type, type, typeName, subTypeName, available, connected, - roaming) {} + roaming), + mSrcObjPtr(nullptr) {} inline SystemStatusNetworkInfo(const NetworkInfoDataItemBase& itemBase) : - NetworkInfoDataItemBase(itemBase) { + NetworkInfoDataItemBase(itemBase), + mSrcObjPtr((NetworkInfoDataItemBase*)&itemBase) { mType = itemBase.getType(); } inline bool equals(const SystemStatusNetworkInfo& peer) { - if ((mType == peer.mType) && + if ((mAllTypes == peer.mAllTypes) && (mTypeName == peer.mTypeName) && (mSubTypeName == peer.mSubTypeName) && (mAvailable == peer.mAvailable) && @@ -487,8 +494,24 @@ public: } return false; } + inline virtual SystemStatusItemBase& collate(SystemStatusItemBase& curInfo) { + uint64_t allTypes = (static_cast(curInfo)).mAllTypes; + if (mConnected) { + mAllTypes |= allTypes; + } else if (0 != mAllTypes) { + mAllTypes = (allTypes & (~mAllTypes)); + } // else (mConnected == false && mAllTypes == 0) + // we keep mAllTypes as 0, which means no more connections. + + if (nullptr != mSrcObjPtr) { + // this is critical, changing mAllTypes of the original obj + mSrcObjPtr->mAllTypes = mAllTypes; + } + return *this; + } inline void dump(void) override { - LOC_LOGD("NetworkInfo: type=%u connected=%u", mType, mConnected); + LOC_LOGD("NetworkInfo: mAllTypes=%" PRIx64 " connected=%u mType=%x", + mAllTypes, mConnected, mType); } }; @@ -783,13 +806,9 @@ private: // Data members static pthread_mutex_t mMutexSystemStatus; SystemStatusReports mCache; - bool mConnected; - - template - bool setItemBaseinReport(TYPE_REPORT& report, const TYPE_ITEMBASE& s); template - bool setIteminReport(TYPE_REPORT& report, const TYPE_ITEM& s); + bool setIteminReport(TYPE_REPORT& report, TYPE_ITEM&& s); // set default dataitem derived item in report cache template diff --git a/core/data-items/DataItemConcreteTypesBase.h b/core/data-items/DataItemConcreteTypesBase.h index fd744088..065366d3 100644 --- a/core/data-items/DataItemConcreteTypesBase.h +++ b/core/data-items/DataItemConcreteTypesBase.h @@ -221,9 +221,23 @@ protected: class NetworkInfoDataItemBase : public IDataItemCore { public: + enum NetworkType { + TYPE_MOBILE, + TYPE_WIFI, + TYPE_ETHERNET, + TYPE_BLUETOOTH, + TYPE_MMS, + TYPE_SUPL, + TYPE_DUN, + TYPE_HIPRI, + TYPE_WIMAX, + TYPE_UNKNOWN, + }; NetworkInfoDataItemBase( - int32_t type, string typeName, string subTypeName, + NetworkType initialType, int32_t type, string typeName, string subTypeName, bool available, bool connected, bool roaming ): + mAllTypes((initialType >= TYPE_UNKNOWN || initialType < TYPE_MOBILE) ? + 0 : (1<& dlist) { NetworkInfoDataItemBase* networkInfo = static_cast(each); - mXtraSysStatObj->updateConnectionStatus(networkInfo->mConnected, - networkInfo->mType); + mXtraSysStatObj->updateConnections(networkInfo->getAllTypes()); } break; diff --git a/gnss/XtraSystemStatusObserver.h b/gnss/XtraSystemStatusObserver.h index 6bf3f58e..af0789b6 100644 --- a/gnss/XtraSystemStatusObserver.h +++ b/gnss/XtraSystemStatusObserver.h @@ -33,22 +33,20 @@ #include #include #include -#include using namespace std; using loc_core::IOsObserver; using loc_core::IDataItemObserver; using loc_core::IDataItemCore; using loc_util::LocIpc; -using CONNECTIONS = set; class XtraSystemStatusObserver : public IDataItemObserver, public LocIpc{ public : // constructor & destructor inline XtraSystemStatusObserver(IOsObserver* sysStatObs, const MsgTask* msgTask): mSystemStatusObsrvr(sysStatObs), mMsgTask(msgTask), - mGpsLock(-1), mXtraThrottle(true), mReqStatusReceived(false), mDelayLocTimer(*this), - mIsConnectivityStatusKnown (false) { + mGpsLock(-1), mConnections(0), mXtraThrottle(true), mReqStatusReceived(false), + mDelayLocTimer(*this), mIsConnectivityStatusKnown (false) { subscribe(true); startListeningNonBlocking(LOC_IPC_HAL); mDelayLocTimer.start(100 /*.1 sec*/, false); @@ -63,7 +61,7 @@ public : virtual void notify(const list& dlist); bool updateLockStatus(uint32_t lock); - bool updateConnectionStatus(bool connected, int32_t type); + bool updateConnections(uint64_t allConnections); bool updateTac(const string& tac); bool updateMccMnc(const string& mccmnc); bool updateXtraThrottle(const bool enabled); @@ -77,7 +75,7 @@ private: IOsObserver* mSystemStatusObsrvr; const MsgTask* mMsgTask; int32_t mGpsLock; - CONNECTIONS mConnections; + uint64_t mConnections; string mTac; string mMccmnc; bool mXtraThrottle; From 664e6431705d425d208ad65f21bb66501ff2c6bf Mon Sep 17 00:00:00 2001 From: Katz Yamada Date: Mon, 7 May 2018 09:45:20 -0700 Subject: [PATCH 08/11] fix: Incorrect time estimate in debug report GNSS Time estimate shown in Gnss debug report is incorrect. It always shows default value instead of value delivered by PQWM1 message. Change-Id: Iff471613ac6fa25d213c14b543871b6c3ae7af0a CRs-Fixed: 2235219 --- android/GnssDebug.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/android/GnssDebug.cpp b/android/GnssDebug.cpp index 33d7aa52..e80eee6b 100644 --- a/android/GnssDebug.cpp +++ b/android/GnssDebug.cpp @@ -120,8 +120,7 @@ Return GnssDebug::getDebugData(getDebugData_cb _hidl_cb) reports.mTime.frequencyUncertaintyNsPerSec; } - if (data.time.timeEstimate <= 0 || - data.time.timeEstimate > GNSS_DEBUG_UNKNOWN_UTC_TIME) { + if (data.time.timeEstimate < GNSS_DEBUG_UNKNOWN_UTC_TIME) { data.time.timeEstimate = GNSS_DEBUG_UNKNOWN_UTC_TIME; } if (data.time.timeUncertaintyNs <= 0 || From 2ade2811c606908d4e10e7e2aaaf4773755c27d7 Mon Sep 17 00:00:00 2001 From: Katz Yamada Date: Fri, 23 Mar 2018 10:32:51 -0700 Subject: [PATCH 09/11] fix: LocIpc client app unable to exit LocIpc client apps such as garden app is unable to delete LocIpc object since its socket listening thread cannot be closed while it is waiting for data and cannot be closed. Fixed to close it by sending an abort message. CRs-Fixed: 2213212 Change-Id: I95f26862e9faf7bd75a2f447421ba4ab7220576e --- utils/LocIpc.cpp | 38 ++++++++++++++++++++++++-------------- utils/LocIpc.h | 3 +-- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/utils/LocIpc.cpp b/utils/LocIpc.cpp index 26a20765..59b659e4 100644 --- a/utils/LocIpc.cpp +++ b/utils/LocIpc.cpp @@ -28,19 +28,8 @@ */ #include -#include -#include #include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include "gps_extended_c.h" #include "LocIpc.h" namespace loc_util { @@ -52,8 +41,10 @@ namespace loc_util { #define LOC_MSG_BUF_LEN 8192 #define LOC_MSG_HEAD "$MSGLEN$" +#define LOC_MSG_ABORT "LocIpcMsg::ABORT" class LocIpcRunnable : public LocRunnable { +friend LocIpc; public: LocIpcRunnable(LocIpc& locIpc, const std::string& ipcName) : mLocIpc(locIpc), mIpcName(ipcName) {} @@ -70,10 +61,10 @@ private: }; bool LocIpc::startListeningNonBlocking(const std::string& name) { - mRunnable.reset(new LocIpcRunnable(*this, name)); + mRunnable = new LocIpcRunnable(*this, name); std::string threadName("LocIpc-"); threadName.append(name); - return mThread.start(threadName.c_str(), mRunnable.get()); + return mThread.start(threadName.c_str(), mRunnable); } bool LocIpc::startListeningBlocking(const std::string& name) { @@ -107,6 +98,7 @@ bool LocIpc::startListeningBlocking(const std::string& name) { ssize_t nBytes = 0; std::string msg = ""; + std::string abort = LOC_MSG_ABORT; while (1) { msg.resize(LOC_MSG_BUF_LEN); nBytes = ::recvfrom(mIpcFd, (void*)(msg.data()), msg.size(), 0, NULL, NULL); @@ -116,6 +108,11 @@ bool LocIpc::startListeningBlocking(const std::string& name) { continue; } + if (strncmp(msg.data(), abort.c_str(), abort.length()) == 0) { + LOC_LOGi("recvd abort msg.data %s", msg.data()); + break; + } + if (strncmp(msg.data(), LOC_MSG_HEAD, sizeof(LOC_MSG_HEAD) - 1)) { // short message msg.resize(nBytes); @@ -142,7 +139,6 @@ bool LocIpc::startListeningBlocking(const std::string& name) { if (mStopRequested) { mStopRequested = false; return true; - } else { LOC_LOGe("cannot read socket. reason:%s", strerror(errno)); (void)::close(mIpcFd); @@ -152,14 +148,28 @@ bool LocIpc::startListeningBlocking(const std::string& name) { } void LocIpc::stopListening() { + + const char *socketName = nullptr; mStopRequested = true; + if (mRunnable) { + std::string abort = LOC_MSG_ABORT; + socketName = (reinterpret_cast(mRunnable))->mIpcName.c_str(); + send(socketName, abort); + mRunnable = nullptr; + } + if (mIpcFd >= 0) { if (::close(mIpcFd)) { LOC_LOGe("cannot close socket:%s", strerror(errno)); } mIpcFd = -1; } + + //delete from the file system at the end + if (socketName) { + unlink(socketName); + } } bool LocIpc::send(const char name[], const std::string& data) { diff --git a/utils/LocIpc.h b/utils/LocIpc.h index 0c37a7ad..a1a994d1 100644 --- a/utils/LocIpc.h +++ b/utils/LocIpc.h @@ -32,7 +32,6 @@ #include #include -#include #include #include #include @@ -96,7 +95,7 @@ private: int mIpcFd; bool mStopRequested; LocThread mThread; - std::unique_ptr mRunnable; + LocRunnable *mRunnable; }; class LocIpcSender { From c0243c4ef526a178bde0e22c4b4ed9bd521881a5 Mon Sep 17 00:00:00 2001 From: Harikrishnan Hariharan Date: Mon, 14 May 2018 12:11:10 +0530 Subject: [PATCH 10/11] Fix KW issues in IOsObserver Fix KW issue in IOsObserver of non-void function not returning value. Change-Id: I8c4bc8939fe1518f28ff66029e6e000a3e9fef75 CRs-Fixed: 2239733 --- core/observer/IOsObserver.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/observer/IOsObserver.h b/core/observer/IOsObserver.h index 40d76717..f6618281 100644 --- a/core/observer/IOsObserver.h +++ b/core/observer/IOsObserver.h @@ -91,8 +91,8 @@ public: inline virtual void turnOn (DataItemId /*dit*/, int /*timeOut*/){} inline virtual void turnOff (DataItemId /*dit*/) {} #ifdef USE_GLIB - inline virtual bool connectBackhaul() {} - inline virtual bool disconnectBackhaul() {} + inline virtual bool connectBackhaul() { return false; } + inline virtual bool disconnectBackhaul() { return false; } #endif /** From 1f5fa2def4559d6fd10ca8052798296c291272be Mon Sep 17 00:00:00 2001 From: Katz Yamada Date: Tue, 3 Apr 2018 16:37:47 -0700 Subject: [PATCH 11/11] fix: Creating LocationAPI object rejected LocationAPI::createInstance() to accept if any one of gnssNiCb, trackingCb, gnssLocationCb or gnssMeasurementsCb is set. Change-Id: I3d026cd608aca2b9e0ee93617e10dc0b32e37849 CRs-Fixed: 2218707 --- location/LocationAPI.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/location/LocationAPI.cpp b/location/LocationAPI.cpp index 0111a9c0..e43d9e03 100644 --- a/location/LocationAPI.cpp +++ b/location/LocationAPI.cpp @@ -62,6 +62,7 @@ static bool isGnssClient(LocationCallbacks& locationCallbacks) { return (locationCallbacks.gnssNiCb != nullptr || locationCallbacks.trackingCb != nullptr || + locationCallbacks.gnssLocationInfoCb != nullptr || locationCallbacks.gnssMeasurementsCb != nullptr); }