1 /* 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 #ifndef __SYSTEM_STATUS_OSOBSERVER__ 30 #define __SYSTEM_STATUS_OSOBSERVER__ 31 32 #include <cinttypes> 33 #include <string> 34 #include <list> 35 #include <map> 36 #include <new> 37 #include <vector> 38 39 #include <MsgTask.h> 40 #include <DataItemId.h> 41 #include <IOsObserver.h> 42 #include <loc_pla.h> 43 #include <log_util.h> 44 #include <LocUnorderedSetMap.h> 45 46 namespace loc_core 47 { 48 /****************************************************************************** 49 SystemStatusOsObserver 50 ******************************************************************************/ 51 using namespace std; 52 using namespace loc_util; 53 54 // Forward Declarations 55 class IDataItemCore; 56 class SystemStatus; 57 class SystemStatusOsObserver; 58 typedef map<IDataItemObserver*, list<DataItemId>> ObserverReqCache; 59 typedef LocUnorderedSetMap<IDataItemObserver*, DataItemId> ClientToDataItems; 60 typedef LocUnorderedSetMap<DataItemId, IDataItemObserver*> DataItemToClients; 61 typedef unordered_map<DataItemId, IDataItemCore*> DataItemIdToCore; 62 typedef unordered_map<DataItemId, int> DataItemIdToInt; 63 64 struct ObserverContext { 65 IDataItemSubscription* mSubscriptionObj; 66 IFrameworkActionReq* mFrameworkActionReqObj; 67 const MsgTask* mMsgTask; 68 SystemStatusOsObserver* mSSObserver; 69 ObserverContextObserverContext70 inline ObserverContext(const MsgTask* msgTask, SystemStatusOsObserver* observer) : 71 mSubscriptionObj(NULL), mFrameworkActionReqObj(NULL), 72 mMsgTask(msgTask), mSSObserver(observer) {} 73 }; 74 75 // Clients wanting to get data from OS/Framework would need to 76 // subscribe with OSObserver using IDataItemSubscription interface. 77 // Such clients would need to implement IDataItemObserver interface 78 // to receive data when it becomes available. 79 class SystemStatusOsObserver : public IOsObserver { 80 81 public: 82 // ctor SystemStatusOsObserver(SystemStatus * systemstatus,const MsgTask * msgTask)83 inline SystemStatusOsObserver(SystemStatus* systemstatus, const MsgTask* msgTask) : 84 mSystemStatus(systemstatus), mContext(msgTask, this), 85 mAddress("SystemStatusOsObserver"), 86 mClientToDataItems(MAX_DATA_ITEM_ID), mDataItemToClients(MAX_DATA_ITEM_ID) 87 #ifdef USE_GLIB 88 , mBackHaulConnectReqCount(0) 89 #endif 90 { 91 } 92 93 // dtor 94 ~SystemStatusOsObserver(); 95 96 template <typename CINT, typename COUT> 97 static COUT containerTransfer(CINT& s); 98 template <typename CINT, typename COUT> containerTransfer(CINT && s)99 inline static COUT containerTransfer(CINT&& s) { 100 return containerTransfer<CINT, COUT>(s); 101 } 102 103 // To set the subscription object 104 virtual void setSubscriptionObj(IDataItemSubscription* subscriptionObj); 105 106 // To set the framework action request object setFrameworkActionReqObj(IFrameworkActionReq * frameworkActionReqObj)107 inline void setFrameworkActionReqObj(IFrameworkActionReq* frameworkActionReqObj) { 108 mContext.mFrameworkActionReqObj = frameworkActionReqObj; 109 #ifdef USE_GLIB 110 if (mBackHaulConnectReqCount > 0) { 111 connectBackhaul(); 112 mBackHaulConnectReqCount = 0; 113 } 114 #endif 115 } 116 117 // IDataItemSubscription Overrides subscribe(const list<DataItemId> & l,IDataItemObserver * client)118 inline virtual void subscribe(const list<DataItemId>& l, IDataItemObserver* client) override { 119 subscribe(l, client, false); 120 } 121 virtual void updateSubscription(const list<DataItemId>& l, IDataItemObserver* client) override; requestData(const list<DataItemId> & l,IDataItemObserver * client)122 inline virtual void requestData(const list<DataItemId>& l, IDataItemObserver* client) override { 123 subscribe(l, client, true); 124 } 125 virtual void unsubscribe(const list<DataItemId>& l, IDataItemObserver* client) override; 126 virtual void unsubscribeAll(IDataItemObserver* client) override; 127 128 // IDataItemObserver Overrides 129 virtual void notify(const list<IDataItemCore*>& dlist) override; getName(string & name)130 inline virtual void getName(string& name) override { 131 name = mAddress; 132 } 133 134 // IFrameworkActionReq Overrides 135 virtual void turnOn(DataItemId dit, int timeOut = 0) override; 136 virtual void turnOff(DataItemId dit) override; 137 #ifdef USE_GLIB 138 virtual bool connectBackhaul() override; 139 virtual bool disconnectBackhaul(); 140 #endif 141 142 private: 143 SystemStatus* mSystemStatus; 144 ObserverContext mContext; 145 const string mAddress; 146 ClientToDataItems mClientToDataItems; 147 DataItemToClients mDataItemToClients; 148 DataItemIdToCore mDataItemCache; 149 DataItemIdToInt mActiveRequestCount; 150 151 // Cache the subscribe and requestData till subscription obj is obtained 152 void cacheObserverRequest(ObserverReqCache& reqCache, 153 const list<DataItemId>& l, IDataItemObserver* client); 154 #ifdef USE_GLIB 155 // Cache the framework action request for connect/disconnect 156 int mBackHaulConnectReqCount; 157 #endif 158 159 void subscribe(const list<DataItemId>& l, IDataItemObserver* client, bool toRequestData); 160 161 // Helpers 162 void sendCachedDataItems(const unordered_set<DataItemId>& s, IDataItemObserver* to); 163 bool updateCache(IDataItemCore* d); logMe(const unordered_set<DataItemId> & l)164 inline void logMe(const unordered_set<DataItemId>& l) { 165 IF_LOC_LOGD { 166 for (auto id : l) { 167 LOC_LOGD("DataItem %d", id); 168 } 169 } 170 } 171 }; 172 173 } // namespace loc_core 174 175 #endif //__SYSTEM_STATUS__ 176 177