blob: 319f1d7ad2d468e9db9cf2d9ccc8a22ffb775338 [file] [log] [blame]
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +05301/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation, nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29#define LOG_TAG "LocSvc_SystemStatusOsObserver"
30
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053031#include <algorithm>
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053032#include <SystemStatus.h>
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053033#include <SystemStatusOsObserver.h>
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053034#include <IDataItemCore.h>
35#include <IClientIndex.h>
36#include <IDataItemIndex.h>
37#include <IndexFactory.h>
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053038#include <DataItemsFactoryProxy.h>
39
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053040namespace loc_core
41{
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053042SystemStatusOsObserver::SystemStatusOsObserver(const MsgTask* msgTask) :
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053043 mAddress("SystemStatusOsObserver"),
44 mClientIndex(IndexFactory<IDataItemObserver*, DataItemId> :: createClientIndex()),
45 mDataItemIndex(IndexFactory<IDataItemObserver*, DataItemId> :: createDataItemIndex())
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053046{
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053047 mContext.mMsgTask = msgTask;
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053048}
49
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053050SystemStatusOsObserver::~SystemStatusOsObserver()
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053051{
52 // Close data-item library handle
53 DataItemsFactoryProxy::closeDataItemLibraryHandle();
54
55 // Destroy cache
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053056 for (auto each : mDataItemCache) {
57 if (nullptr != each.second) {
58 delete each.second;
59 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053060 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053061
62 mDataItemCache.clear();
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053063 delete mClientIndex;
64 delete mDataItemIndex;
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053065}
66
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053067void SystemStatusOsObserver::setSubscriptionObj(IDataItemSubscription* subscriptionObj)
68{
69 mContext.mSubscriptionObj = subscriptionObj;
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053070
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053071 LOC_LOGD("Request cache size - Subscribe:%zu RequestData:%zu",
72 mSubscribeReqCache.size(), mReqDataCache.size());
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053073
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053074 // we have received the subscription object. process cached requests
75 // process - subscribe request cache
76 for (auto each : mSubscribeReqCache) {
77 subscribe(each.second, each.first);
78 }
79 // process - requestData request cache
80 for (auto each : mReqDataCache) {
81 requestData(each.second, each.first);
82 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053083}
84
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053085// Helper to cache requests subscribe and requestData till subscription obj is obtained
86void SystemStatusOsObserver::cacheObserverRequest(ObserverReqCache& reqCache,
87 const list<DataItemId>& l, IDataItemObserver* client)
88{
89 ObserverReqCache::iterator dicIter = reqCache.find(client);
90 if (dicIter != reqCache.end()) {
91 // found
92 list<DataItemId> difference(0);
93 set_difference(l.begin(), l.end(),
94 dicIter->second.begin(), dicIter->second.end(),
95 inserter(difference, difference.begin()));
96 if (!difference.empty()) {
97 difference.sort();
98 dicIter->second.merge(difference);
99 dicIter->second.unique();
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530100 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530101 }
102 else {
103 // not found
104 reqCache[client] = l;
105 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530106}
107
108/******************************************************************************
109 IDataItemSubscription Overrides
110******************************************************************************/
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530111void SystemStatusOsObserver::subscribe(
112 const list<DataItemId>& l, IDataItemObserver* client)
113{
114 if (nullptr == mContext.mSubscriptionObj) {
115 LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__);
116 cacheObserverRequest(mSubscribeReqCache, l, client);
117 return;
118 }
119
120 struct HandleSubscribeReq : public LocMsg {
121 HandleSubscribeReq(SystemStatusOsObserver* parent,
122 const list<DataItemId>& l, IDataItemObserver* client) :
123 mParent(parent), mClient(client), mDataItemList(l) {}
124 virtual ~HandleSubscribeReq() {}
125 void proc() const {
126
127 if (mDataItemList.empty()) {
128 LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
129 return;
130 }
131
132 // Handle First Response
133 list<DataItemId> pendingFirstResponseList(0);
134 mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList);
135
136 // Do not send first response for only pendingFirstResponseList,
137 // instead send for all the data items (present in the cache) that
138 // have been subscribed for each time.
139 mParent->sendFirstResponse(mDataItemList, mClient);
140
141 list<DataItemId> yetToSubscribeDataItemsList(0);
142 mParent->mDataItemIndex->add(mClient, mDataItemList, yetToSubscribeDataItemsList);
143
144 // Send subscription list to framework
145 if (!yetToSubscribeDataItemsList.empty()) {
146 mParent->mContext.mSubscriptionObj->subscribe(yetToSubscribeDataItemsList, mParent);
147 LOC_LOGD("Subscribe Request sent to framework for the following");
148 mParent->logMe(yetToSubscribeDataItemsList);
149 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530150 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530151 SystemStatusOsObserver* mParent;
152 IDataItemObserver* mClient;
153 const list<DataItemId> mDataItemList;
154 };
155 mContext.mMsgTask->sendMsg(new (nothrow) HandleSubscribeReq(this, l, client));
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530156}
157
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530158void SystemStatusOsObserver::updateSubscription(
159 const list<DataItemId>& l, IDataItemObserver* client)
160{
161 if (nullptr == mContext.mSubscriptionObj) {
162 LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
163 return;
164 }
165
166 struct HandleUpdateSubscriptionReq : public LocMsg {
167 HandleUpdateSubscriptionReq(SystemStatusOsObserver* parent,
168 const list<DataItemId>& l, IDataItemObserver* client) :
169 mParent(parent), mClient(client), mDataItemList(l) {}
170 virtual ~HandleUpdateSubscriptionReq() {}
171 void proc() const {
172 if (mDataItemList.empty()) {
173 LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
174 return;
175 }
176
177 list<DataItemId> currentlySubscribedList(0);
178 mParent->mClientIndex->getSubscribedList(mClient, currentlySubscribedList);
179
180 list<DataItemId> removeDataItemList(0);
181 set_difference(currentlySubscribedList.begin(), currentlySubscribedList.end(),
182 mDataItemList.begin(), mDataItemList.end(),
183 inserter(removeDataItemList,removeDataItemList.begin()));
184
185 // Handle First Response
186 list<DataItemId> pendingFirstResponseList(0);
187 mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList);
188
189 // Send First Response
190 mParent->sendFirstResponse(pendingFirstResponseList, mClient);
191
192 list<DataItemId> yetToSubscribeDataItemsList(0);
193 mParent->mDataItemIndex->add(
194 mClient, mDataItemList, yetToSubscribeDataItemsList);
195
196 // Send subscription list to framework
197 if (!yetToSubscribeDataItemsList.empty()) {
198 mParent->mContext.mSubscriptionObj->subscribe(
199 yetToSubscribeDataItemsList, mParent);
200 LOC_LOGD("Subscribe Request sent to framework for the following");
201 mParent->logMe(yetToSubscribeDataItemsList);
202 }
203
204 list<DataItemId> unsubscribeList(0);
205 list<DataItemId> unused(0);
206 mParent->mClientIndex->remove(mClient, removeDataItemList, unused);
207
208 if (!mParent->mClientIndex->isSubscribedClient(mClient)) {
209 mParent->mDataItemIndex->remove(
210 list<IDataItemObserver*> (1,mClient), unsubscribeList);
211 }
212 if (!unsubscribeList.empty()) {
213 // Send unsubscribe to framework
214 mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent);
215 LOC_LOGD("Unsubscribe Request sent to framework for the following");
216 mParent->logMe(unsubscribeList);
217 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530218 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530219 SystemStatusOsObserver* mParent;
220 IDataItemObserver* mClient;
221 const list<DataItemId> mDataItemList;
222 };
223 mContext.mMsgTask->sendMsg(new (nothrow) HandleUpdateSubscriptionReq(this, l, client));
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530224}
225
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530226void SystemStatusOsObserver::requestData(
227 const list<DataItemId>& l, IDataItemObserver* client)
228{
229 if (nullptr == mContext.mSubscriptionObj) {
230 LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__);
231 cacheObserverRequest(mReqDataCache, l, client);
232 return;
233 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530234
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530235 struct HandleRequestData : public LocMsg {
236 HandleRequestData(SystemStatusOsObserver* parent,
237 const list<DataItemId>& l, IDataItemObserver* client) :
238 mParent(parent), mClient(client), mDataItemList(l) {}
239 virtual ~HandleRequestData() {}
240 void proc() const {
241 if (mDataItemList.empty()) {
242 LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
243 return;
244 }
245
246 list<DataItemId> yetToSubscribeDataItemsList(0);
247 mParent->mClientIndex->add(
248 mClient, mDataItemList, yetToSubscribeDataItemsList);
249 mParent->mDataItemIndex->add(
250 mClient, mDataItemList, yetToSubscribeDataItemsList);
251
252 // Send subscription list to framework
253 if (!mDataItemList.empty()) {
254 mParent->mContext.mSubscriptionObj->requestData(mDataItemList, mParent);
255 LOC_LOGD("Subscribe Request sent to framework for the following");
256 mParent->logMe(yetToSubscribeDataItemsList);
257 }
258 }
259 SystemStatusOsObserver* mParent;
260 IDataItemObserver* mClient;
261 const list<DataItemId> mDataItemList;
262 };
263 mContext.mMsgTask->sendMsg(new (nothrow) HandleRequestData(this, l, client));
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530264}
265
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530266void SystemStatusOsObserver::unsubscribe(
267 const list<DataItemId>& l, IDataItemObserver* client)
268{
269 if (nullptr == mContext.mSubscriptionObj) {
270 LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
271 return;
272 }
273 struct HandleUnsubscribeReq : public LocMsg {
274 HandleUnsubscribeReq(SystemStatusOsObserver* parent,
275 const list<DataItemId>& l, IDataItemObserver* client) :
276 mParent(parent), mClient(client), mDataItemList(l) {}
277 virtual ~HandleUnsubscribeReq() {}
278 void proc() const {
279 if (mDataItemList.empty()) {
280 LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
281 return;
282 }
283
284 list<DataItemId> unsubscribeList(0);
285 list<DataItemId> unused(0);
286 mParent->mClientIndex->remove(mClient, mDataItemList, unused);
287
288 for (auto each : mDataItemList) {
289 list<IDataItemObserver*> clientListSubs(0);
290 list<IDataItemObserver*> clientListOut(0);
291 mParent->mDataItemIndex->remove(
292 each, list<IDataItemObserver*> (1,mClient), clientListOut);
293 // check if there are any other subscribed client for this data item id
294 mParent->mDataItemIndex->getListOfSubscribedClients(each, clientListSubs);
295 if (clientListSubs.empty())
296 {
297 LOC_LOGD("Client list subscribed is empty for dataitem - %d", each);
298 unsubscribeList.push_back(each);
299 }
300 }
301
302 if (!unsubscribeList.empty()) {
303 // Send unsubscribe to framework
304 mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent);
305 LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
306 mParent->logMe(unsubscribeList);
307 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530308 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530309 SystemStatusOsObserver* mParent;
310 IDataItemObserver* mClient;
311 const list<DataItemId> mDataItemList;
312 };
313 mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeReq(this, l, client));
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530314}
315
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530316void SystemStatusOsObserver::unsubscribeAll(IDataItemObserver* client)
317{
318 if (nullptr == mContext.mSubscriptionObj) {
319 LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
320 return;
321 }
322
323 struct HandleUnsubscribeAllReq : public LocMsg {
324 HandleUnsubscribeAllReq(SystemStatusOsObserver* parent,
325 IDataItemObserver* client) :
326 mParent(parent), mClient(client) {}
327 virtual ~HandleUnsubscribeAllReq() {}
328 void proc() const {
329 list<IDataItemObserver*> clients(1, mClient);
330 list<DataItemId> unsubscribeList(0);
331 if(0 == mParent->mClientIndex->remove(mClient)) {
332 return;
333 }
334 mParent->mDataItemIndex->remove(clients, unsubscribeList);
335
336 if (!unsubscribeList.empty()) {
337 // Send unsubscribe to framework
338 mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent);
339 LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
340 mParent->logMe(unsubscribeList);
341 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530342 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530343 SystemStatusOsObserver* mParent;
344 IDataItemObserver* mClient;
345 };
346 mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeAllReq(this, client));
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530347}
348
349/******************************************************************************
350 IDataItemObserver Overrides
351******************************************************************************/
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530352void SystemStatusOsObserver::notify(const list<IDataItemCore*>& dlist)
353{
354 list<IDataItemCore*> dataItemList(0);
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530355
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530356 for (auto each : dlist) {
357 string dv;
358 each->stringify(dv);
359 LOC_LOGD("notify: DataItem In Value:%s", dv.c_str());
360
361 IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId());
362 if (nullptr == di) {
363 LOC_LOGE("Unable to create dataitem:%d", each->getId());
364 return;
365 }
366
367 // Copy contents into the newly created data item
368 di->copy(each);
369 dataItemList.push_back(di);
370 // Request systemstatus to record this dataitem in its cache
371 SystemStatus* systemstatus = SystemStatus::getInstance(mContext.mMsgTask);
372 if(nullptr != systemstatus) {
373 systemstatus->eventDataItemNotify(di);
374 }
375 }
376
377 struct HandleNotify : public LocMsg {
378 HandleNotify(SystemStatusOsObserver* parent, const list<IDataItemCore*>& l) :
379 mParent(parent), mDList(l) {}
380 virtual ~HandleNotify() {
381 for (auto each : mDList) {
382 delete each;
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530383 }
384 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530385 void proc() const {
386 // Update Cache with received data items and prepare
387 // list of data items to be sent.
388 list<DataItemId> dataItemIdsToBeSent(0);
389 for (auto item : mDList) {
390 bool dataItemUpdated = false;
391 mParent->updateCache(item, dataItemUpdated);
392 if (dataItemUpdated) {
393 dataItemIdsToBeSent.push_back(item->getId());
394 }
395 }
396
397 // Send data item to all subscribed clients
398 list<IDataItemObserver*> clientList(0);
399 for (auto each : dataItemIdsToBeSent) {
400 list<IDataItemObserver*> clients(0);
401 mParent->mDataItemIndex->getListOfSubscribedClients(each, clients);
402 for (auto each_cient: clients) {
403 clientList.push_back(each_cient);
404 }
405 }
406 clientList.unique();
407
408 for (auto client : clientList) {
409 list<DataItemId> dataItemIdsSubscribedByThisClient(0);
410 list<DataItemId> dataItemIdsToBeSentForThisClient(0);
411 mParent->mClientIndex->getSubscribedList(
412 client, dataItemIdsSubscribedByThisClient);
413 dataItemIdsSubscribedByThisClient.sort();
414 dataItemIdsToBeSent.sort();
415
416 set_intersection(dataItemIdsToBeSent.begin(),
417 dataItemIdsToBeSent.end(),
418 dataItemIdsSubscribedByThisClient.begin(),
419 dataItemIdsSubscribedByThisClient.end(),
420 inserter(dataItemIdsToBeSentForThisClient,
421 dataItemIdsToBeSentForThisClient.begin()));
422
423 mParent->sendCachedDataItems(dataItemIdsToBeSentForThisClient, client);
424 dataItemIdsSubscribedByThisClient.clear();
425 dataItemIdsToBeSentForThisClient.clear();
426 }
427 }
428 SystemStatusOsObserver* mParent;
429 const list<IDataItemCore*> mDList;
430 };
431 mContext.mMsgTask->sendMsg(new (nothrow) HandleNotify(this, dataItemList));
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530432}
433
434/******************************************************************************
435 IFrameworkActionReq Overrides
436******************************************************************************/
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530437void SystemStatusOsObserver::turnOn(DataItemId dit, int timeOut)
438{
439 if (nullptr == mContext.mFrameworkActionReqObj) {
440 LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__);
441 return;
442 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530443
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530444 // Check if data item exists in mActiveRequestCount
445 map<DataItemId, int>::iterator citer = mActiveRequestCount.find(dit);
446 if (citer == mActiveRequestCount.end()) {
447 // Data item not found in map
448 // Add reference count as 1 and add dataitem to map
449 pair<DataItemId, int> cpair(dit, 1);
450 mActiveRequestCount.insert(cpair);
451 LOC_LOGD("Sending turnOn request");
452
453 // Send action turn on to framework
454 struct HandleTurnOnMsg : public LocMsg {
455 HandleTurnOnMsg(IFrameworkActionReq* framework,
456 DataItemId dit, int timeOut) :
457 mFrameworkActionReqObj(framework), mDataItemId(dit), mTimeOut(timeOut) {}
458 virtual ~HandleTurnOnMsg() {}
459 void proc() const {
460 mFrameworkActionReqObj->turnOn(mDataItemId, mTimeOut);
461 }
462 IFrameworkActionReq* mFrameworkActionReqObj;
463 DataItemId mDataItemId;
464 int mTimeOut;
465 };
466 mContext.mMsgTask->sendMsg(new (nothrow) HandleTurnOnMsg(this, dit, timeOut));
467 }
468 else {
469 // Found in map, update reference count
470 citer->second++;
471 LOC_LOGD("turnOn - Data item:%d Num_refs:%d", dit, citer->second);
472 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530473}
474
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530475void SystemStatusOsObserver::turnOff(DataItemId dit)
476{
477 if (nullptr == mContext.mFrameworkActionReqObj) {
478 LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__);
479 return;
480 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530481
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530482 // Check if data item exists in mActiveRequestCount
483 map<DataItemId, int>::iterator citer = mActiveRequestCount.find(dit);
484 if (citer != mActiveRequestCount.end()) {
485 // found
486 citer->second--;
487 LOC_LOGD("turnOff - Data item:%d Remaining:%d", dit, citer->second);
488 if(citer->second == 0) {
489 // if this was last reference, remove item from map and turn off module
490 mActiveRequestCount.erase(citer);
491
492 // Send action turn off to framework
493 struct HandleTurnOffMsg : public LocMsg {
494 HandleTurnOffMsg(IFrameworkActionReq* framework, DataItemId dit) :
495 mFrameworkActionReqObj(framework), mDataItemId(dit) {}
496 virtual ~HandleTurnOffMsg() {}
497 void proc() const {
498 mFrameworkActionReqObj->turnOff(mDataItemId);
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530499 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530500 IFrameworkActionReq* mFrameworkActionReqObj;
501 DataItemId mDataItemId;
502 };
503 mContext.mMsgTask->sendMsg(
504 new (nothrow) HandleTurnOffMsg(mContext.mFrameworkActionReqObj, dit));
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530505 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530506 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530507}
508
509/******************************************************************************
510 Helpers
511******************************************************************************/
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530512void SystemStatusOsObserver::sendFirstResponse(
513 const list<DataItemId>& l, IDataItemObserver* to)
514{
515 if (l.empty()) {
516 LOC_LOGV("list is empty. Nothing to do. Exiting");
517 return;
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530518 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530519
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530520 string clientName;
521 to->getName(clientName);
522 list<IDataItemCore*> dataItems(0);
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530523
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530524 for (auto each : l) {
525 map<DataItemId, IDataItemCore*>::const_iterator citer = mDataItemCache.find(each);
526 if (citer != mDataItemCache.end()) {
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530527 string dv;
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530528 citer->second->stringify(dv);
529 LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str());
530 dataItems.push_back(citer->second);
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530531 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530532 }
533 if (dataItems.empty()) {
534 LOC_LOGV("No items to notify. Nothing to do. Exiting");
535 return;
536 }
537 to->notify(dataItems);
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530538}
539
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530540void SystemStatusOsObserver::sendCachedDataItems(
541 const list<DataItemId>& l, IDataItemObserver* to)
542{
543 string clientName;
544 to->getName(clientName);
545 list<IDataItemCore*> dataItems(0);
546
547 for (auto each : l) {
548 string dv;
549 IDataItemCore* di = mDataItemCache[each];
550 di->stringify(dv);
551 LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str());
552 dataItems.push_back(di);
553 }
554 to->notify(dataItems);
555}
556
557void SystemStatusOsObserver::updateCache(IDataItemCore* d, bool& dataItemUpdated)
558{
559 if (nullptr == d) {
560 return;
561 }
562
563 // Check if data item exists in cache
564 map<DataItemId, IDataItemCore*>::iterator citer =
565 mDataItemCache.find(d->getId());
566 if (citer == mDataItemCache.end()) {
567 // New data item; not found in cache
568 IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId());
569 if (nullptr == dataitem) {
570 return;
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530571 }
572
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530573 // Copy the contents of the data item
574 dataitem->copy(d);
575 pair<DataItemId, IDataItemCore*> cpair(d->getId(), dataitem);
576 // Insert in mDataItemCache
577 mDataItemCache.insert(cpair);
578 dataItemUpdated = true;
579 }
580 else {
581 // Found in cache; Update cache if necessary
582 if(0 == citer->second->copy(d, &dataItemUpdated)) {
583 return;
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530584 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530585 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530586
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530587 if (dataItemUpdated) {
588 LOC_LOGV("DataItem:%d updated:%d", d->getId(), dataItemUpdated);
589 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530590}
591
592} // namespace loc_core
593