596 lines
23 KiB
C++
596 lines
23 KiB
C++
|
/* 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.
|
||
|
*
|
||
|
*/
|
||
|
#define LOG_TAG "LocSvc_SystemStatusOsObserver"
|
||
|
|
||
|
#include <algorithm>
|
||
|
#include <SystemStatus.h>
|
||
|
#include <SystemStatusOsObserver.h>
|
||
|
#include <IDataItemCore.h>
|
||
|
#include <IClientIndex.h>
|
||
|
#include <IDataItemIndex.h>
|
||
|
#include <IndexFactory.h>
|
||
|
#include <DataItemsFactoryProxy.h>
|
||
|
|
||
|
namespace loc_core
|
||
|
{
|
||
|
SystemStatusOsObserver::SystemStatusOsObserver(
|
||
|
SystemStatus* systemstatus, const MsgTask* msgTask) :
|
||
|
mSystemStatus(systemstatus),
|
||
|
mAddress("SystemStatusOsObserver"),
|
||
|
mClientIndex(IndexFactory<IDataItemObserver*, DataItemId> :: createClientIndex()),
|
||
|
mDataItemIndex(IndexFactory<IDataItemObserver*, DataItemId> :: createDataItemIndex())
|
||
|
{
|
||
|
mContext.mMsgTask = msgTask;
|
||
|
}
|
||
|
|
||
|
SystemStatusOsObserver::~SystemStatusOsObserver()
|
||
|
{
|
||
|
// Close data-item library handle
|
||
|
DataItemsFactoryProxy::closeDataItemLibraryHandle();
|
||
|
|
||
|
// Destroy cache
|
||
|
for (auto each : mDataItemCache) {
|
||
|
if (nullptr != each.second) {
|
||
|
delete each.second;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
mDataItemCache.clear();
|
||
|
delete mClientIndex;
|
||
|
delete mDataItemIndex;
|
||
|
}
|
||
|
|
||
|
void SystemStatusOsObserver::setSubscriptionObj(IDataItemSubscription* subscriptionObj)
|
||
|
{
|
||
|
mContext.mSubscriptionObj = subscriptionObj;
|
||
|
|
||
|
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<DataItemId>& l, IDataItemObserver* client)
|
||
|
{
|
||
|
ObserverReqCache::iterator dicIter = reqCache.find(client);
|
||
|
if (dicIter != reqCache.end()) {
|
||
|
// found
|
||
|
list<DataItemId> 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();
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
// not found
|
||
|
reqCache[client] = l;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
IDataItemSubscription Overrides
|
||
|
******************************************************************************/
|
||
|
void SystemStatusOsObserver::subscribe(
|
||
|
const list<DataItemId>& l, IDataItemObserver* client)
|
||
|
{
|
||
|
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<DataItemId>& l, IDataItemObserver* client) :
|
||
|
mParent(parent), mClient(client), mDataItemList(l) {}
|
||
|
virtual ~HandleSubscribeReq() {}
|
||
|
void proc() const {
|
||
|
|
||
|
if (mDataItemList.empty()) {
|
||
|
LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Handle First Response
|
||
|
list<DataItemId> 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<DataItemId> yetToSubscribeDataItemsList(0);
|
||
|
mParent->mDataItemIndex->add(mClient, mDataItemList, yetToSubscribeDataItemsList);
|
||
|
|
||
|
// 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);
|
||
|
}
|
||
|
}
|
||
|
SystemStatusOsObserver* mParent;
|
||
|
IDataItemObserver* mClient;
|
||
|
const list<DataItemId> mDataItemList;
|
||
|
};
|
||
|
mContext.mMsgTask->sendMsg(new (nothrow) HandleSubscribeReq(this, l, client));
|
||
|
}
|
||
|
|
||
|
void SystemStatusOsObserver::updateSubscription(
|
||
|
const list<DataItemId>& 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<DataItemId>& l, IDataItemObserver* client) :
|
||
|
mParent(parent), mClient(client), mDataItemList(l) {}
|
||
|
virtual ~HandleUpdateSubscriptionReq() {}
|
||
|
void proc() const {
|
||
|
if (mDataItemList.empty()) {
|
||
|
LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
list<DataItemId> currentlySubscribedList(0);
|
||
|
mParent->mClientIndex->getSubscribedList(mClient, currentlySubscribedList);
|
||
|
|
||
|
list<DataItemId> removeDataItemList(0);
|
||
|
set_difference(currentlySubscribedList.begin(), currentlySubscribedList.end(),
|
||
|
mDataItemList.begin(), mDataItemList.end(),
|
||
|
inserter(removeDataItemList,removeDataItemList.begin()));
|
||
|
|
||
|
// Handle First Response
|
||
|
list<DataItemId> pendingFirstResponseList(0);
|
||
|
mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList);
|
||
|
|
||
|
// Send First Response
|
||
|
mParent->sendFirstResponse(pendingFirstResponseList, mClient);
|
||
|
|
||
|
list<DataItemId> yetToSubscribeDataItemsList(0);
|
||
|
mParent->mDataItemIndex->add(
|
||
|
mClient, mDataItemList, yetToSubscribeDataItemsList);
|
||
|
|
||
|
// 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);
|
||
|
}
|
||
|
|
||
|
list<DataItemId> unsubscribeList(0);
|
||
|
list<DataItemId> unused(0);
|
||
|
mParent->mClientIndex->remove(mClient, removeDataItemList, unused);
|
||
|
|
||
|
if (!mParent->mClientIndex->isSubscribedClient(mClient)) {
|
||
|
mParent->mDataItemIndex->remove(
|
||
|
list<IDataItemObserver*> (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);
|
||
|
}
|
||
|
}
|
||
|
SystemStatusOsObserver* mParent;
|
||
|
IDataItemObserver* mClient;
|
||
|
const list<DataItemId> mDataItemList;
|
||
|
};
|
||
|
mContext.mMsgTask->sendMsg(new (nothrow) HandleUpdateSubscriptionReq(this, l, client));
|
||
|
}
|
||
|
|
||
|
void SystemStatusOsObserver::requestData(
|
||
|
const list<DataItemId>& l, IDataItemObserver* client)
|
||
|
{
|
||
|
if (nullptr == mContext.mSubscriptionObj) {
|
||
|
LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__);
|
||
|
cacheObserverRequest(mReqDataCache, l, client);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
struct HandleRequestData : public LocMsg {
|
||
|
HandleRequestData(SystemStatusOsObserver* parent,
|
||
|
const list<DataItemId>& 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<DataItemId> 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<DataItemId> mDataItemList;
|
||
|
};
|
||
|
mContext.mMsgTask->sendMsg(new (nothrow) HandleRequestData(this, l, client));
|
||
|
}
|
||
|
|
||
|
void SystemStatusOsObserver::unsubscribe(
|
||
|
const list<DataItemId>& 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<DataItemId>& l, IDataItemObserver* client) :
|
||
|
mParent(parent), mClient(client), mDataItemList(l) {}
|
||
|
virtual ~HandleUnsubscribeReq() {}
|
||
|
void proc() const {
|
||
|
if (mDataItemList.empty()) {
|
||
|
LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
list<DataItemId> unsubscribeList(0);
|
||
|
list<DataItemId> unused(0);
|
||
|
mParent->mClientIndex->remove(mClient, mDataItemList, unused);
|
||
|
|
||
|
for (auto each : mDataItemList) {
|
||
|
list<IDataItemObserver*> clientListSubs(0);
|
||
|
list<IDataItemObserver*> clientListOut(0);
|
||
|
mParent->mDataItemIndex->remove(
|
||
|
each, list<IDataItemObserver*> (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);
|
||
|
LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
|
||
|
mParent->logMe(unsubscribeList);
|
||
|
}
|
||
|
}
|
||
|
SystemStatusOsObserver* mParent;
|
||
|
IDataItemObserver* mClient;
|
||
|
const list<DataItemId> mDataItemList;
|
||
|
};
|
||
|
mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeReq(this, 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<IDataItemObserver*> clients(1, mClient);
|
||
|
list<DataItemId> 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);
|
||
|
}
|
||
|
}
|
||
|
SystemStatusOsObserver* mParent;
|
||
|
IDataItemObserver* mClient;
|
||
|
};
|
||
|
mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeAllReq(this, client));
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
IDataItemObserver Overrides
|
||
|
******************************************************************************/
|
||
|
void SystemStatusOsObserver::notify(const list<IDataItemCore*>& dlist)
|
||
|
{
|
||
|
list<IDataItemCore*> 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<IDataItemCore*>& l) :
|
||
|
mParent(parent), mDList(l) {}
|
||
|
virtual ~HandleNotify() {
|
||
|
for (auto each : mDList) {
|
||
|
delete each;
|
||
|
}
|
||
|
}
|
||
|
void proc() const {
|
||
|
// Update Cache with received data items and prepare
|
||
|
// list of data items to be sent.
|
||
|
list<DataItemId> dataItemIdsToBeSent(0);
|
||
|
for (auto item : mDList) {
|
||
|
bool dataItemUpdated = false;
|
||
|
mParent->updateCache(item, dataItemUpdated);
|
||
|
if (dataItemUpdated) {
|
||
|
dataItemIdsToBeSent.push_back(item->getId());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Send data item to all subscribed clients
|
||
|
list<IDataItemObserver*> clientList(0);
|
||
|
for (auto each : dataItemIdsToBeSent) {
|
||
|
list<IDataItemObserver*> clients(0);
|
||
|
mParent->mDataItemIndex->getListOfSubscribedClients(each, clients);
|
||
|
for (auto each_cient: clients) {
|
||
|
clientList.push_back(each_cient);
|
||
|
}
|
||
|
}
|
||
|
clientList.unique();
|
||
|
|
||
|
for (auto client : clientList) {
|
||
|
list<DataItemId> dataItemIdsSubscribedByThisClient(0);
|
||
|
list<DataItemId> dataItemIdsToBeSentForThisClient(0);
|
||
|
mParent->mClientIndex->getSubscribedList(
|
||
|
client, dataItemIdsSubscribedByThisClient);
|
||
|
dataItemIdsSubscribedByThisClient.sort();
|
||
|
dataItemIdsToBeSent.sort();
|
||
|
|
||
|
set_intersection(dataItemIdsToBeSent.begin(),
|
||
|
dataItemIdsToBeSent.end(),
|
||
|
dataItemIdsSubscribedByThisClient.begin(),
|
||
|
dataItemIdsSubscribedByThisClient.end(),
|
||
|
inserter(dataItemIdsToBeSentForThisClient,
|
||
|
dataItemIdsToBeSentForThisClient.begin()));
|
||
|
|
||
|
mParent->sendCachedDataItems(dataItemIdsToBeSentForThisClient, client);
|
||
|
dataItemIdsSubscribedByThisClient.clear();
|
||
|
dataItemIdsToBeSentForThisClient.clear();
|
||
|
}
|
||
|
}
|
||
|
SystemStatusOsObserver* mParent;
|
||
|
const list<IDataItemCore*> mDList;
|
||
|
};
|
||
|
mContext.mMsgTask->sendMsg(new (nothrow) HandleNotify(this, dataItemList));
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
IFrameworkActionReq Overrides
|
||
|
******************************************************************************/
|
||
|
void SystemStatusOsObserver::turnOn(DataItemId dit, int timeOut)
|
||
|
{
|
||
|
if (nullptr == mContext.mFrameworkActionReqObj) {
|
||
|
LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Check if data item exists in mActiveRequestCount
|
||
|
map<DataItemId, int>::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
|
||
|
pair<DataItemId, int> cpair(dit, 1);
|
||
|
mActiveRequestCount.insert(cpair);
|
||
|
LOC_LOGD("Sending turnOn request");
|
||
|
|
||
|
// Send action turn on to framework
|
||
|
struct HandleTurnOnMsg : public LocMsg {
|
||
|
HandleTurnOnMsg(IFrameworkActionReq* framework,
|
||
|
DataItemId dit, int timeOut) :
|
||
|
mFrameworkActionReqObj(framework), mDataItemId(dit), mTimeOut(timeOut) {}
|
||
|
virtual ~HandleTurnOnMsg() {}
|
||
|
void proc() const {
|
||
|
mFrameworkActionReqObj->turnOn(mDataItemId, mTimeOut);
|
||
|
}
|
||
|
IFrameworkActionReq* mFrameworkActionReqObj;
|
||
|
DataItemId mDataItemId;
|
||
|
int mTimeOut;
|
||
|
};
|
||
|
mContext.mMsgTask->sendMsg(new (nothrow) HandleTurnOnMsg(this, dit, timeOut));
|
||
|
}
|
||
|
else {
|
||
|
// Found in map, update reference count
|
||
|
citer->second++;
|
||
|
LOC_LOGD("turnOn - Data item:%d Num_refs:%d", dit, citer->second);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SystemStatusOsObserver::turnOff(DataItemId dit)
|
||
|
{
|
||
|
if (nullptr == mContext.mFrameworkActionReqObj) {
|
||
|
LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Check if data item exists in mActiveRequestCount
|
||
|
map<DataItemId, int>::iterator citer = mActiveRequestCount.find(dit);
|
||
|
if (citer != mActiveRequestCount.end()) {
|
||
|
// found
|
||
|
citer->second--;
|
||
|
LOC_LOGD("turnOff - Data item:%d Remaining:%d", dit, citer->second);
|
||
|
if(citer->second == 0) {
|
||
|
// if this was last reference, remove item from map and turn off module
|
||
|
mActiveRequestCount.erase(citer);
|
||
|
|
||
|
// Send action turn off to framework
|
||
|
struct HandleTurnOffMsg : public LocMsg {
|
||
|
HandleTurnOffMsg(IFrameworkActionReq* framework, DataItemId dit) :
|
||
|
mFrameworkActionReqObj(framework), mDataItemId(dit) {}
|
||
|
virtual ~HandleTurnOffMsg() {}
|
||
|
void proc() const {
|
||
|
mFrameworkActionReqObj->turnOff(mDataItemId);
|
||
|
}
|
||
|
IFrameworkActionReq* mFrameworkActionReqObj;
|
||
|
DataItemId mDataItemId;
|
||
|
};
|
||
|
mContext.mMsgTask->sendMsg(
|
||
|
new (nothrow) HandleTurnOffMsg(mContext.mFrameworkActionReqObj, dit));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
Helpers
|
||
|
******************************************************************************/
|
||
|
void SystemStatusOsObserver::sendFirstResponse(
|
||
|
const list<DataItemId>& l, IDataItemObserver* to)
|
||
|
{
|
||
|
if (l.empty()) {
|
||
|
LOC_LOGV("list is empty. Nothing to do. Exiting");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
string clientName;
|
||
|
to->getName(clientName);
|
||
|
list<IDataItemCore*> dataItems(0);
|
||
|
|
||
|
for (auto each : l) {
|
||
|
map<DataItemId, IDataItemCore*>::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<DataItemId>& l, IDataItemObserver* to)
|
||
|
{
|
||
|
string clientName;
|
||
|
to->getName(clientName);
|
||
|
list<IDataItemCore*> 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);
|
||
|
}
|
||
|
to->notify(dataItems);
|
||
|
}
|
||
|
|
||
|
void SystemStatusOsObserver::updateCache(IDataItemCore* d, bool& dataItemUpdated)
|
||
|
{
|
||
|
if (nullptr == d) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Check if data item exists in cache
|
||
|
map<DataItemId, IDataItemCore*>::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;
|
||
|
}
|
||
|
|
||
|
// Copy the contents of the data item
|
||
|
dataitem->copy(d);
|
||
|
pair<DataItemId, IDataItemCore*> 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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} // namespace loc_core
|
||
|
|