blob: dc08a76e640e941c6a5911f8e6a8b63de1d2a20d [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"),
Harikrishnan Hariharanf0d7fe82017-09-04 11:55:13 +053044#ifdef USE_GLIB
45 mBackHaulConnectReqCount(0),
46#endif
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053047 mClientIndex(IndexFactory<IDataItemObserver*, DataItemId> :: createClientIndex()),
48 mDataItemIndex(IndexFactory<IDataItemObserver*, DataItemId> :: createDataItemIndex())
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053049{
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053050 mContext.mMsgTask = msgTask;
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053051}
52
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053053SystemStatusOsObserver::~SystemStatusOsObserver()
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053054{
55 // Close data-item library handle
56 DataItemsFactoryProxy::closeDataItemLibraryHandle();
57
58 // Destroy cache
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053059 for (auto each : mDataItemCache) {
60 if (nullptr != each.second) {
61 delete each.second;
62 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053063 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053064
65 mDataItemCache.clear();
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053066 delete mClientIndex;
67 delete mDataItemIndex;
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053068}
69
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053070void SystemStatusOsObserver::setSubscriptionObj(IDataItemSubscription* subscriptionObj)
71{
72 mContext.mSubscriptionObj = subscriptionObj;
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053073
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053074 LOC_LOGD("Request cache size - Subscribe:%zu RequestData:%zu",
75 mSubscribeReqCache.size(), mReqDataCache.size());
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053076
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053077 // we have received the subscription object. process cached requests
78 // process - subscribe request cache
79 for (auto each : mSubscribeReqCache) {
80 subscribe(each.second, each.first);
81 }
82 // process - requestData request cache
83 for (auto each : mReqDataCache) {
84 requestData(each.second, each.first);
85 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +053086}
87
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +053088// Helper to cache requests subscribe and requestData till subscription obj is obtained
89void SystemStatusOsObserver::cacheObserverRequest(ObserverReqCache& reqCache,
90 const list<DataItemId>& l, IDataItemObserver* client)
91{
92 ObserverReqCache::iterator dicIter = reqCache.find(client);
93 if (dicIter != reqCache.end()) {
94 // found
95 list<DataItemId> difference(0);
96 set_difference(l.begin(), l.end(),
97 dicIter->second.begin(), dicIter->second.end(),
98 inserter(difference, difference.begin()));
99 if (!difference.empty()) {
100 difference.sort();
101 dicIter->second.merge(difference);
102 dicIter->second.unique();
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530103 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530104 }
105 else {
106 // not found
107 reqCache[client] = l;
108 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530109}
110
111/******************************************************************************
112 IDataItemSubscription Overrides
113******************************************************************************/
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530114void SystemStatusOsObserver::subscribe(
115 const list<DataItemId>& l, IDataItemObserver* client)
116{
117 if (nullptr == mContext.mSubscriptionObj) {
118 LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__);
119 cacheObserverRequest(mSubscribeReqCache, l, client);
120 return;
121 }
122
123 struct HandleSubscribeReq : public LocMsg {
124 HandleSubscribeReq(SystemStatusOsObserver* parent,
125 const list<DataItemId>& l, IDataItemObserver* client) :
126 mParent(parent), mClient(client), mDataItemList(l) {}
127 virtual ~HandleSubscribeReq() {}
128 void proc() const {
129
130 if (mDataItemList.empty()) {
131 LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
132 return;
133 }
134
135 // Handle First Response
136 list<DataItemId> pendingFirstResponseList(0);
137 mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList);
138
139 // Do not send first response for only pendingFirstResponseList,
140 // instead send for all the data items (present in the cache) that
141 // have been subscribed for each time.
142 mParent->sendFirstResponse(mDataItemList, mClient);
143
144 list<DataItemId> yetToSubscribeDataItemsList(0);
145 mParent->mDataItemIndex->add(mClient, mDataItemList, yetToSubscribeDataItemsList);
146
147 // Send subscription list to framework
148 if (!yetToSubscribeDataItemsList.empty()) {
149 mParent->mContext.mSubscriptionObj->subscribe(yetToSubscribeDataItemsList, mParent);
150 LOC_LOGD("Subscribe Request sent to framework for the following");
151 mParent->logMe(yetToSubscribeDataItemsList);
152 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530153 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530154 SystemStatusOsObserver* mParent;
155 IDataItemObserver* mClient;
156 const list<DataItemId> mDataItemList;
157 };
158 mContext.mMsgTask->sendMsg(new (nothrow) HandleSubscribeReq(this, l, client));
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530159}
160
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530161void SystemStatusOsObserver::updateSubscription(
162 const list<DataItemId>& l, IDataItemObserver* client)
163{
164 if (nullptr == mContext.mSubscriptionObj) {
165 LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
166 return;
167 }
168
169 struct HandleUpdateSubscriptionReq : public LocMsg {
170 HandleUpdateSubscriptionReq(SystemStatusOsObserver* parent,
171 const list<DataItemId>& l, IDataItemObserver* client) :
172 mParent(parent), mClient(client), mDataItemList(l) {}
173 virtual ~HandleUpdateSubscriptionReq() {}
174 void proc() const {
175 if (mDataItemList.empty()) {
176 LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
177 return;
178 }
179
180 list<DataItemId> currentlySubscribedList(0);
181 mParent->mClientIndex->getSubscribedList(mClient, currentlySubscribedList);
182
183 list<DataItemId> removeDataItemList(0);
184 set_difference(currentlySubscribedList.begin(), currentlySubscribedList.end(),
185 mDataItemList.begin(), mDataItemList.end(),
186 inserter(removeDataItemList,removeDataItemList.begin()));
187
188 // Handle First Response
189 list<DataItemId> pendingFirstResponseList(0);
190 mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList);
191
192 // Send First Response
193 mParent->sendFirstResponse(pendingFirstResponseList, mClient);
194
195 list<DataItemId> yetToSubscribeDataItemsList(0);
196 mParent->mDataItemIndex->add(
197 mClient, mDataItemList, yetToSubscribeDataItemsList);
198
199 // Send subscription list to framework
200 if (!yetToSubscribeDataItemsList.empty()) {
201 mParent->mContext.mSubscriptionObj->subscribe(
202 yetToSubscribeDataItemsList, mParent);
203 LOC_LOGD("Subscribe Request sent to framework for the following");
204 mParent->logMe(yetToSubscribeDataItemsList);
205 }
206
207 list<DataItemId> unsubscribeList(0);
208 list<DataItemId> unused(0);
209 mParent->mClientIndex->remove(mClient, removeDataItemList, unused);
210
211 if (!mParent->mClientIndex->isSubscribedClient(mClient)) {
212 mParent->mDataItemIndex->remove(
213 list<IDataItemObserver*> (1,mClient), unsubscribeList);
214 }
215 if (!unsubscribeList.empty()) {
216 // Send unsubscribe to framework
217 mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent);
218 LOC_LOGD("Unsubscribe Request sent to framework for the following");
219 mParent->logMe(unsubscribeList);
220 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530221 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530222 SystemStatusOsObserver* mParent;
223 IDataItemObserver* mClient;
224 const list<DataItemId> mDataItemList;
225 };
226 mContext.mMsgTask->sendMsg(new (nothrow) HandleUpdateSubscriptionReq(this, l, client));
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530227}
228
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530229void SystemStatusOsObserver::requestData(
230 const list<DataItemId>& l, IDataItemObserver* client)
231{
232 if (nullptr == mContext.mSubscriptionObj) {
233 LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__);
234 cacheObserverRequest(mReqDataCache, l, client);
235 return;
236 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530237
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530238 struct HandleRequestData : public LocMsg {
239 HandleRequestData(SystemStatusOsObserver* parent,
240 const list<DataItemId>& l, IDataItemObserver* client) :
241 mParent(parent), mClient(client), mDataItemList(l) {}
242 virtual ~HandleRequestData() {}
243 void proc() const {
244 if (mDataItemList.empty()) {
245 LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
246 return;
247 }
248
249 list<DataItemId> yetToSubscribeDataItemsList(0);
250 mParent->mClientIndex->add(
251 mClient, mDataItemList, yetToSubscribeDataItemsList);
252 mParent->mDataItemIndex->add(
253 mClient, mDataItemList, yetToSubscribeDataItemsList);
254
255 // Send subscription list to framework
256 if (!mDataItemList.empty()) {
257 mParent->mContext.mSubscriptionObj->requestData(mDataItemList, mParent);
258 LOC_LOGD("Subscribe Request sent to framework for the following");
259 mParent->logMe(yetToSubscribeDataItemsList);
260 }
261 }
262 SystemStatusOsObserver* mParent;
263 IDataItemObserver* mClient;
264 const list<DataItemId> mDataItemList;
265 };
266 mContext.mMsgTask->sendMsg(new (nothrow) HandleRequestData(this, l, client));
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530267}
268
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530269void SystemStatusOsObserver::unsubscribe(
270 const list<DataItemId>& l, IDataItemObserver* client)
271{
272 if (nullptr == mContext.mSubscriptionObj) {
273 LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
274 return;
275 }
276 struct HandleUnsubscribeReq : public LocMsg {
277 HandleUnsubscribeReq(SystemStatusOsObserver* parent,
278 const list<DataItemId>& l, IDataItemObserver* client) :
279 mParent(parent), mClient(client), mDataItemList(l) {}
280 virtual ~HandleUnsubscribeReq() {}
281 void proc() const {
282 if (mDataItemList.empty()) {
283 LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
284 return;
285 }
286
287 list<DataItemId> unsubscribeList(0);
288 list<DataItemId> unused(0);
289 mParent->mClientIndex->remove(mClient, mDataItemList, unused);
290
291 for (auto each : mDataItemList) {
292 list<IDataItemObserver*> clientListSubs(0);
293 list<IDataItemObserver*> clientListOut(0);
294 mParent->mDataItemIndex->remove(
295 each, list<IDataItemObserver*> (1,mClient), clientListOut);
296 // check if there are any other subscribed client for this data item id
297 mParent->mDataItemIndex->getListOfSubscribedClients(each, clientListSubs);
298 if (clientListSubs.empty())
299 {
300 LOC_LOGD("Client list subscribed is empty for dataitem - %d", each);
301 unsubscribeList.push_back(each);
302 }
303 }
304
305 if (!unsubscribeList.empty()) {
306 // Send unsubscribe to framework
307 mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent);
308 LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
309 mParent->logMe(unsubscribeList);
310 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530311 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530312 SystemStatusOsObserver* mParent;
313 IDataItemObserver* mClient;
314 const list<DataItemId> mDataItemList;
315 };
316 mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeReq(this, l, client));
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530317}
318
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530319void SystemStatusOsObserver::unsubscribeAll(IDataItemObserver* client)
320{
321 if (nullptr == mContext.mSubscriptionObj) {
322 LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
323 return;
324 }
325
326 struct HandleUnsubscribeAllReq : public LocMsg {
327 HandleUnsubscribeAllReq(SystemStatusOsObserver* parent,
328 IDataItemObserver* client) :
329 mParent(parent), mClient(client) {}
330 virtual ~HandleUnsubscribeAllReq() {}
331 void proc() const {
332 list<IDataItemObserver*> clients(1, mClient);
333 list<DataItemId> unsubscribeList(0);
334 if(0 == mParent->mClientIndex->remove(mClient)) {
335 return;
336 }
337 mParent->mDataItemIndex->remove(clients, unsubscribeList);
338
339 if (!unsubscribeList.empty()) {
340 // Send unsubscribe to framework
341 mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent);
342 LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
343 mParent->logMe(unsubscribeList);
344 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530345 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530346 SystemStatusOsObserver* mParent;
347 IDataItemObserver* mClient;
348 };
349 mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeAllReq(this, client));
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530350}
351
352/******************************************************************************
353 IDataItemObserver Overrides
354******************************************************************************/
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530355void SystemStatusOsObserver::notify(const list<IDataItemCore*>& dlist)
356{
357 list<IDataItemCore*> dataItemList(0);
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530358
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530359 for (auto each : dlist) {
360 string dv;
361 each->stringify(dv);
362 LOC_LOGD("notify: DataItem In Value:%s", dv.c_str());
363
364 IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId());
365 if (nullptr == di) {
366 LOC_LOGE("Unable to create dataitem:%d", each->getId());
367 return;
368 }
369
370 // Copy contents into the newly created data item
371 di->copy(each);
372 dataItemList.push_back(di);
373 // Request systemstatus to record this dataitem in its cache
374 SystemStatus* systemstatus = SystemStatus::getInstance(mContext.mMsgTask);
375 if(nullptr != systemstatus) {
376 systemstatus->eventDataItemNotify(di);
377 }
378 }
379
380 struct HandleNotify : public LocMsg {
381 HandleNotify(SystemStatusOsObserver* parent, const list<IDataItemCore*>& l) :
382 mParent(parent), mDList(l) {}
383 virtual ~HandleNotify() {
384 for (auto each : mDList) {
385 delete each;
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530386 }
387 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530388 void proc() const {
389 // Update Cache with received data items and prepare
390 // list of data items to be sent.
391 list<DataItemId> dataItemIdsToBeSent(0);
392 for (auto item : mDList) {
393 bool dataItemUpdated = false;
394 mParent->updateCache(item, dataItemUpdated);
395 if (dataItemUpdated) {
396 dataItemIdsToBeSent.push_back(item->getId());
397 }
398 }
399
400 // Send data item to all subscribed clients
401 list<IDataItemObserver*> clientList(0);
402 for (auto each : dataItemIdsToBeSent) {
403 list<IDataItemObserver*> clients(0);
404 mParent->mDataItemIndex->getListOfSubscribedClients(each, clients);
405 for (auto each_cient: clients) {
406 clientList.push_back(each_cient);
407 }
408 }
409 clientList.unique();
410
411 for (auto client : clientList) {
412 list<DataItemId> dataItemIdsSubscribedByThisClient(0);
413 list<DataItemId> dataItemIdsToBeSentForThisClient(0);
414 mParent->mClientIndex->getSubscribedList(
415 client, dataItemIdsSubscribedByThisClient);
416 dataItemIdsSubscribedByThisClient.sort();
417 dataItemIdsToBeSent.sort();
418
419 set_intersection(dataItemIdsToBeSent.begin(),
420 dataItemIdsToBeSent.end(),
421 dataItemIdsSubscribedByThisClient.begin(),
422 dataItemIdsSubscribedByThisClient.end(),
423 inserter(dataItemIdsToBeSentForThisClient,
424 dataItemIdsToBeSentForThisClient.begin()));
425
426 mParent->sendCachedDataItems(dataItemIdsToBeSentForThisClient, client);
427 dataItemIdsSubscribedByThisClient.clear();
428 dataItemIdsToBeSentForThisClient.clear();
429 }
430 }
431 SystemStatusOsObserver* mParent;
432 const list<IDataItemCore*> mDList;
433 };
434 mContext.mMsgTask->sendMsg(new (nothrow) HandleNotify(this, dataItemList));
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530435}
436
437/******************************************************************************
438 IFrameworkActionReq Overrides
439******************************************************************************/
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530440void SystemStatusOsObserver::turnOn(DataItemId dit, int timeOut)
441{
442 if (nullptr == mContext.mFrameworkActionReqObj) {
443 LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__);
444 return;
445 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530446
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530447 // Check if data item exists in mActiveRequestCount
448 map<DataItemId, int>::iterator citer = mActiveRequestCount.find(dit);
449 if (citer == mActiveRequestCount.end()) {
450 // Data item not found in map
451 // Add reference count as 1 and add dataitem to map
452 pair<DataItemId, int> cpair(dit, 1);
453 mActiveRequestCount.insert(cpair);
454 LOC_LOGD("Sending turnOn request");
455
456 // Send action turn on to framework
457 struct HandleTurnOnMsg : public LocMsg {
458 HandleTurnOnMsg(IFrameworkActionReq* framework,
459 DataItemId dit, int timeOut) :
460 mFrameworkActionReqObj(framework), mDataItemId(dit), mTimeOut(timeOut) {}
461 virtual ~HandleTurnOnMsg() {}
462 void proc() const {
463 mFrameworkActionReqObj->turnOn(mDataItemId, mTimeOut);
464 }
465 IFrameworkActionReq* mFrameworkActionReqObj;
466 DataItemId mDataItemId;
467 int mTimeOut;
468 };
469 mContext.mMsgTask->sendMsg(new (nothrow) HandleTurnOnMsg(this, dit, timeOut));
470 }
471 else {
472 // Found in map, update reference count
473 citer->second++;
474 LOC_LOGD("turnOn - Data item:%d Num_refs:%d", dit, citer->second);
475 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530476}
477
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530478void SystemStatusOsObserver::turnOff(DataItemId dit)
479{
480 if (nullptr == mContext.mFrameworkActionReqObj) {
481 LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__);
482 return;
483 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530484
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530485 // Check if data item exists in mActiveRequestCount
486 map<DataItemId, int>::iterator citer = mActiveRequestCount.find(dit);
487 if (citer != mActiveRequestCount.end()) {
488 // found
489 citer->second--;
490 LOC_LOGD("turnOff - Data item:%d Remaining:%d", dit, citer->second);
491 if(citer->second == 0) {
492 // if this was last reference, remove item from map and turn off module
493 mActiveRequestCount.erase(citer);
494
495 // Send action turn off to framework
496 struct HandleTurnOffMsg : public LocMsg {
497 HandleTurnOffMsg(IFrameworkActionReq* framework, DataItemId dit) :
498 mFrameworkActionReqObj(framework), mDataItemId(dit) {}
499 virtual ~HandleTurnOffMsg() {}
500 void proc() const {
501 mFrameworkActionReqObj->turnOff(mDataItemId);
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530502 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530503 IFrameworkActionReq* mFrameworkActionReqObj;
504 DataItemId mDataItemId;
505 };
506 mContext.mMsgTask->sendMsg(
507 new (nothrow) HandleTurnOffMsg(mContext.mFrameworkActionReqObj, dit));
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530508 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530509 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530510}
511
Harikrishnan Hariharanf0d7fe82017-09-04 11:55:13 +0530512#ifdef USE_GLIB
513bool SystemStatusOsObserver::connectBackhaul()
514{
515 bool result = false;
516
517 if (mContext.mFrameworkActionReqObj != NULL) {
518 struct HandleConnectBackhaul : public LocMsg {
519 HandleConnectBackhaul(IFrameworkActionReq* fwkActReq) :
520 mFwkActionReqObj(fwkActReq) {}
521 virtual ~HandleConnectBackhaul() {}
522 void proc() const {
523 LOC_LOGD("HandleConnectBackhaul");
524 mFwkActionReqObj->connectBackhaul();
525 }
526 IFrameworkActionReq* mFwkActionReqObj;
527 };
528 mContext.mMsgTask->sendMsg(
529 new (nothrow) HandleConnectBackhaul(mContext.mFrameworkActionReqObj));
530 result = true;
531 }
532 else {
533 ++mBackHaulConnectReqCount;
534 LOC_LOGE("Framework action request object is NULL.Caching connect request: %d",
535 mBackHaulConnectReqCount);
536 result = false;
537 }
538 return result;
539
540}
541
542bool SystemStatusOsObserver::disconnectBackhaul()
543{
544 bool result = false;
545
546 if (mContext.mFrameworkActionReqObj != NULL) {
547 struct HandleDisconnectBackhaul : public LocMsg {
548 HandleDisconnectBackhaul(IFrameworkActionReq* fwkActReq) :
549 mFwkActionReqObj(fwkActReq) {}
550 virtual ~HandleDisconnectBackhaul() {}
551 void proc() const {
552 LOC_LOGD("HandleDisconnectBackhaul");
553 mFwkActionReqObj->disconnectBackhaul();
554 }
555 IFrameworkActionReq* mFwkActionReqObj;
556 };
557 mContext.mMsgTask->sendMsg(
558 new (nothrow) HandleDisconnectBackhaul(mContext.mFrameworkActionReqObj));
559 }
560 else {
561 if (mBackHaulConnectReqCount > 0) {
562 --mBackHaulConnectReqCount;
563 }
564 LOC_LOGE("Framework action request object is NULL.Caching disconnect request: %d",
565 mBackHaulConnectReqCount);
566 result = false;
567 }
568 return result;
569}
570#endif
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530571/******************************************************************************
572 Helpers
573******************************************************************************/
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530574void SystemStatusOsObserver::sendFirstResponse(
575 const list<DataItemId>& l, IDataItemObserver* to)
576{
577 if (l.empty()) {
578 LOC_LOGV("list is empty. Nothing to do. Exiting");
579 return;
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530580 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530581
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530582 string clientName;
583 to->getName(clientName);
584 list<IDataItemCore*> dataItems(0);
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530585
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530586 for (auto each : l) {
587 map<DataItemId, IDataItemCore*>::const_iterator citer = mDataItemCache.find(each);
588 if (citer != mDataItemCache.end()) {
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530589 string dv;
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530590 citer->second->stringify(dv);
591 LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str());
592 dataItems.push_back(citer->second);
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530593 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530594 }
595 if (dataItems.empty()) {
596 LOC_LOGV("No items to notify. Nothing to do. Exiting");
597 return;
598 }
599 to->notify(dataItems);
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530600}
601
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530602void SystemStatusOsObserver::sendCachedDataItems(
603 const list<DataItemId>& l, IDataItemObserver* to)
604{
605 string clientName;
606 to->getName(clientName);
607 list<IDataItemCore*> dataItems(0);
608
609 for (auto each : l) {
610 string dv;
611 IDataItemCore* di = mDataItemCache[each];
612 di->stringify(dv);
613 LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str());
614 dataItems.push_back(di);
615 }
616 to->notify(dataItems);
617}
618
619void SystemStatusOsObserver::updateCache(IDataItemCore* d, bool& dataItemUpdated)
620{
621 if (nullptr == d) {
622 return;
623 }
624
625 // Check if data item exists in cache
626 map<DataItemId, IDataItemCore*>::iterator citer =
627 mDataItemCache.find(d->getId());
628 if (citer == mDataItemCache.end()) {
629 // New data item; not found in cache
630 IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId());
631 if (nullptr == dataitem) {
632 return;
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530633 }
634
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530635 // Copy the contents of the data item
636 dataitem->copy(d);
637 pair<DataItemId, IDataItemCore*> cpair(d->getId(), dataitem);
638 // Insert in mDataItemCache
639 mDataItemCache.insert(cpair);
640 dataItemUpdated = true;
641 }
642 else {
643 // Found in cache; Update cache if necessary
644 if(0 == citer->second->copy(d, &dataItemUpdated)) {
645 return;
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530646 }
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530647 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530648
Harikrishnan Hariharanff8b3172017-08-11 17:36:10 +0530649 if (dataItemUpdated) {
650 LOC_LOGV("DataItem:%d updated:%d", d->getId(), dataItemUpdated);
651 }
Harikrishnan Hariharanee2d6652017-08-11 15:13:38 +0530652}
653
654} // namespace loc_core
655