2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file wrt_event_delivery_detail.cpp
18 * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
20 * @brief This file is the implementation file of event delivery EFL detail class
22 #include <dpl/event/event_delivery_detail.h>
23 #include <dpl/event/event_delivery_injector.h>
24 #include <dpl/framework_appcore.h>
25 #include <dpl/framework_vconf.h>
26 #include <dpl/scoped_array.h>
27 #include <dpl/assert.h>
28 #include <dpl/log/log.h>
30 #include <sys/types.h>
37 namespace // anonymous
39 const char *GENERIC_NOTI_ROOT_PATH = "/tmp/noti/generic";
40 } // namespace anonymous
47 const char *EventDeliverySystemDetail::NOTI_EVENT_ID_GENERIC_0 = "GenericEvent0_";
48 const char *EventDeliverySystemDetail::NOTI_EVENT_ID_GENERIC_1 = "GenericEvent1_";
49 const char *EventDeliverySystemDetail::NOTI_EVENT_ID_GENERIC_2 = "GenericEvent2_";
50 const char *EventDeliverySystemDetail::NOTI_EVENT_ID_GENERIC_3 = "GenericEvent3_";
51 const char *EventDeliverySystemDetail::NOTI_EVENT_ID_GENERIC_4 = "GenericEvent4_";
53 // Global noti signal names
54 const char *GlobalNotiHibernationEnterSignal = "HIBERNATION_ENTER";
55 const char *GlobalNotiHibernationLeaveSignal = "HIBERNATION_LEAVE";
57 EventDeliverySystemDetail::EventDeliverySystemDetail()
59 // Open noti subsystem
60 LogInfo("Initializing core_util_noti subsystem...");
62 m_notiHandle = heynoti_init();
63 Assert(m_notiHandle != -1);
65 // Assume that there is ECORE environment running, attach noti library to it
66 LogPedantic("Attaching core_util_noti subsystem to ECORE...");
68 int ret = heynoti_attach_handler(m_notiHandle);
73 LogInfo("core_util_noti subsystem successfuly initialized.");
76 EventDeliverySystemDetail::~EventDeliverySystemDetail()
78 // All signal handlers should be deattached
79 Assert(m_notiSignalList.empty());
80 Assert(m_settingSignalList.empty());
81 Assert(m_globalNotiSignalList.empty());
83 // Detach noti library from ECORE environment
84 LogPedantic("Detaching core_util_noti subsystem from ECORE...");
86 int ret = heynoti_detach_handler(m_notiHandle);
91 // Close noti sybsystem
92 LogInfo("Deinitializing core_util_noti subsystem...");
94 Assert(m_notiHandle != -1);
95 heynoti_close(m_notiHandle);
97 LogInfo("core_util_noti subsystem successfuly deinitialized.");
100 std::string EventDeliverySystemDetail::ReadFile(const std::string &fileName) const
102 LogPedantic("Reading event file: " << fileName << "...");
104 std::ifstream fileStream(fileName.c_str(), std::ios::binary);
106 if (fileStream.fail())
107 return std::string("");
109 fileStream.seekg (0, std::ios::end);
110 std::streamoff length = fileStream.tellg();
111 fileStream.seekg (0, std::ios::beg);
113 ScopedArray<char> buffer(new char[length]);
114 fileStream.read(buffer.Get(), static_cast<size_t>(length));
116 if (fileStream.fail())
117 return std::string();
119 LogPedantic("Successfuly read: " << fileName << ".");
121 return std::string(buffer.Get(), buffer.Get() + length);
124 void EventDeliverySystemDetail::OnNotiGlobalSignal(void *notiData)
127 NotiSignal *notiSignal = static_cast<NotiSignal *>(notiData);
128 notiSignal->GetReceiver()->OnNotiSignal(notiSignal);
131 void EventDeliverySystemDetail::OnSettingSignal(keynode_t *keyNode, void *userParam)
133 SettingSignal *settingSignal = static_cast<SettingSignal *>(userParam);
136 LogPedantic("Got setting signal for key: " << settingSignal->GetKey());
138 std::string key = vconf_keynode_get_name(keyNode);
140 if (key == VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL)
142 int value = vconf_keynode_get_bool(keyNode);
143 EventMessages::RoamingChanged message(value > 0);
144 EventDeliverySystemInjector::Instance().Publish(message);
146 else if (key == VCONFKEY_TELEPHONY_SVC_ROAM)
149 if(vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &result) != 0)
151 LogPedantic("Cannot get current roaming status");
156 bool homeNetwork = (result != VCONFKEY_TELEPHONY_SVC_ROAM_ON);
157 EventMessages::NetworkTypeChanged message1(homeNetwork);
158 EventDeliverySystemInjector::Instance().Publish(message1);
163 LogPedantic("Unexpected setting signal key: " << key << "!");
168 void EventDeliverySystemDetail::OnGlobalNotiSignal(void *globalNotiData)
170 GlobalNotiSignal *globalNotiSignal = static_cast<GlobalNotiSignal *>(globalNotiData);
172 LogPedantic("Got global noti signal for key: " << globalNotiSignal->GetKey());
174 std::string key = globalNotiSignal->GetKey();
176 if (key == GlobalNotiHibernationEnterSignal)
178 // We need to disconnect from VCONF
179 for (SettingSignalList::iterator iterator = globalNotiSignal->GetReceiver()->m_settingSignalList.begin();
180 iterator != globalNotiSignal->GetReceiver()->m_settingSignalList.end(); ++iterator)
182 // Unegister from VCONF signals
183 int ret = vconf_ignore_key_changed(iterator->GetKey().c_str(), OnSettingSignal);
186 LogPedantic("Failed to unlisten setting: " << key << ", errno = " << errno << ".");
190 EventMessages::HibernationEnter message;
191 EventDeliverySystemInjector::Instance().Publish(message);
193 else if (key == GlobalNotiHibernationLeaveSignal)
195 // We need to reconnect to VCONF
196 for (SettingSignalList::iterator iterator = globalNotiSignal->GetReceiver()->m_settingSignalList.begin();
197 iterator != globalNotiSignal->GetReceiver()->m_settingSignalList.end(); ++iterator)
199 // Register for VCONF signals
200 int ret = vconf_notify_key_changed(iterator->GetKey().c_str(), OnSettingSignal, &*iterator);
203 LogPedantic("Failed to listen setting: key = " << key << ", errno = " << errno << ".");
207 EventMessages::HibernationLeave message;
208 EventDeliverySystemInjector::Instance().Publish(message);
212 LogPedantic("Unexpected global noti signal key: " << key << "!");
217 void EventDeliverySystemDetail::OnNotiSignal(NotiSignal *notiSignal)
219 LogPedantic("Got core_util_noti signal.");
221 if (notiSignal->GetEventName().substr(0, strlen(NOTI_EVENT_ID_GENERIC_0)) == NOTI_EVENT_ID_GENERIC_0)
223 LogPedantic("GeneticEvent0 message signal.");
225 EventDeliverySystemInjector::Instance().PublishMetaType(notiSignal->GetGcid(), ReadFile(GetGenericNotiFilePath(notiSignal->GetEventName())));
227 else if (notiSignal->GetEventName().substr(0, strlen(NOTI_EVENT_ID_GENERIC_1)) == NOTI_EVENT_ID_GENERIC_1)
229 LogPedantic("GeneticEvent1 message signal.");
231 EventDeliverySystemInjector::Instance().PublishMetaType(notiSignal->GetGcid(), ReadFile(GetGenericNotiFilePath(notiSignal->GetEventName())));
233 else if (notiSignal->GetEventName().substr(0, strlen(NOTI_EVENT_ID_GENERIC_2)) == NOTI_EVENT_ID_GENERIC_2)
235 LogPedantic("GeneticEvent2 message signal.");
237 EventDeliverySystemInjector::Instance().PublishMetaType(notiSignal->GetGcid(), ReadFile(GetGenericNotiFilePath(notiSignal->GetEventName())));
239 else if (notiSignal->GetEventName().substr(0, strlen(NOTI_EVENT_ID_GENERIC_3)) == NOTI_EVENT_ID_GENERIC_3)
241 LogPedantic("GeneticEvent3 message signal.");
243 EventDeliverySystemInjector::Instance().PublishMetaType(notiSignal->GetGcid(), ReadFile(GetGenericNotiFilePath(notiSignal->GetEventName())));
245 else if (notiSignal->GetEventName().substr(0, strlen(NOTI_EVENT_ID_GENERIC_4)) == NOTI_EVENT_ID_GENERIC_4)
247 LogPedantic("GeneticEvent4 message signal.");
249 EventDeliverySystemInjector::Instance().PublishMetaType(notiSignal->GetGcid(), ReadFile(GetGenericNotiFilePath(notiSignal->GetEventName())));
253 void EventDeliverySystemDetail::RegisterFileNotiCallback(const char *gcid, const std::string &eventName)
255 LogPedantic("Registering core_util_noti callback: gcid = " << (gcid ? gcid : "<NULL>") << ", eventName = " << eventName << ".");
256 Assert(m_notiHandle != -1);
258 // Check if already registered for signal
259 NotiSignalList::const_iterator iterator;
261 for (iterator = m_notiSignalList.begin(); iterator != m_notiSignalList.end(); ++iterator)
263 if (iterator->GetEventName() == eventName)
267 // Make real noti path
268 std::string filePath = GetGenericNotiFilePath(eventName);
270 LogPedantic("Listening file: " << filePath << ".");
273 m_notiSignalList.push_back(NotiSignal(this, gcid, eventName));
274 NotiSignal *notiSignal = &m_notiSignalList.back();
276 // Register for noti signals
277 int ret = heynoti_subscribe_file(m_notiHandle, filePath.c_str(), OnNotiGlobalSignal, notiSignal, IN_CLOSE_WRITE);
281 LogPedantic("Failed to listen file: " << filePath << ".");
285 LogPedantic("Successfuly registered listening file: " << filePath << ".");
288 void EventDeliverySystemDetail::UnregisterFileNotiCallback(const std::string &eventName)
290 LogPedantic("Unegistering core_util_noti callback: eventName = " << eventName << ".");
292 Assert(m_notiHandle != -1);
294 NotiSignalList::iterator iterator;
296 for (iterator = m_notiSignalList.begin(); iterator != m_notiSignalList.end(); ++iterator)
298 if (iterator->GetEventName() == eventName)
302 if (iterator == m_notiSignalList.end())
305 // Remove registered slot
306 m_notiSignalList.erase(iterator);
308 // Make real noti path
309 std::string filePath = GetGenericNotiFilePath(eventName);
311 LogPedantic("Unlistening file: " << filePath << ".");
313 // Register for noti signals
314 int ret = heynoti_unsubscribe_file(m_notiHandle, filePath.c_str(), OnNotiGlobalSignal);
318 LogPedantic("Failed to unlisten file: " << filePath << ".");
323 void EventDeliverySystemDetail::RegisterSettingCallback(const std::string &key)
325 LogPedantic("Registering setting: key = " << key << ".");
327 // Check if already registered for signal
328 SettingSignalList::const_iterator iterator;
330 for (iterator = m_settingSignalList.begin(); iterator != m_settingSignalList.end(); ++iterator)
332 if (iterator->GetKey() == key)
337 m_settingSignalList.push_back(SettingSignal(this, key));
338 SettingSignal *settingSignal = &m_settingSignalList.back();
340 // Register for setting signals
341 int ret = vconf_notify_key_changed(key.c_str(), OnSettingSignal, settingSignal);
345 LogPedantic("Failed to listen setting: key = " << key << ", errno = " << errno << ".");
349 LogPedantic("Successfuly registered setting: key = " << key << ".");
352 void EventDeliverySystemDetail::UnregisterSettingCallback(const std::string &key)
354 LogPedantic("Unegistering setting: key = " << key << ".");
356 SettingSignalList::iterator iterator;
358 for (iterator = m_settingSignalList.begin(); iterator != m_settingSignalList.end(); ++iterator)
360 if (iterator->GetKey() == key)
364 if (iterator == m_settingSignalList.end())
367 // Remove registered slot
368 m_settingSignalList.erase(iterator);
370 // Register for noti signals
371 int ret = vconf_ignore_key_changed(key.c_str(), OnSettingSignal);
375 LogPedantic("Failed to unlisten setting: " << key << ", errno = " << errno << ".");
380 void EventDeliverySystemDetail::RegisterGlobalNotiCallback(const std::string &key)
382 LogPedantic("Registering global noti: key = " << key << ".");
384 // Check if already registered for signal
385 GlobalNotiSignalList::const_iterator iterator;
387 for (iterator = m_globalNotiSignalList.begin(); iterator != m_globalNotiSignalList.end(); ++iterator)
389 if (iterator->GetKey() == key)
394 m_globalNotiSignalList.push_back(GlobalNotiSignal(this, key));
395 GlobalNotiSignal *globalNotiSignal = &m_globalNotiSignalList.back();
397 // Register for global noti signals
398 int ret = heynoti_subscribe(m_notiHandle, key.c_str(), OnGlobalNotiSignal, globalNotiSignal);
402 LogPedantic("Failed to listen global noti: key = " << key << ", errno = " << errno << ".");
406 LogPedantic("Successfuly registered global noti: key = " << key << ".");
409 void EventDeliverySystemDetail::UnregisterGlobalNotiCallback(const std::string &key)
411 LogPedantic("Unegistering global noti: key = " << key << ".");
413 GlobalNotiSignalList::iterator iterator;
415 for (iterator = m_globalNotiSignalList.begin(); iterator != m_globalNotiSignalList.end(); ++iterator)
417 if (iterator->GetKey() == key)
421 if (iterator == m_globalNotiSignalList.end())
424 // Remove registered slot
425 m_globalNotiSignalList.erase(iterator);
427 // Register for noti signals
428 int ret = heynoti_unsubscribe(m_notiHandle, key.c_str(), OnGlobalNotiSignal);
432 LogPedantic("Failed to unlisten global noti: " << key << ", errno = " << errno << ".");
437 void EventDeliverySystemDetail::SignalGenericNoti(const std::string &eventName, const std::string &contents) const
439 LogPedantic("Signaling core_util_noti with: eventName = " << eventName << ", buffer = " << contents << ".");
441 Assert(m_notiHandle != -1);
443 // Make real noto path
444 std::string filePath = GetGenericNotiFilePath(eventName);
446 LogPedantic("Signaling file: " << filePath << ".");
448 // Emit noti signal with user data
449 int fd = open(filePath.c_str(), O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
453 LogPedantic("Failed to signal file: " << filePath << ".");
457 // Write contents of signal to file
458 std::string::size_type written = 0;
460 while (written < contents.size())
462 int done = TEMP_FAILURE_RETRY(write(fd, static_cast<const void *>(&contents[written]), contents.size() - written));
466 LogPedantic("File stream broken: " << filePath << ".");
478 LogPedantic("Failed to close signal file: " << filePath << ".");
483 std::string EventDeliverySystemDetail::GetGenericNotiFilePath(const std::string &eventName) const
485 // Make sure that the path exists
486 if (access(GENERIC_NOTI_ROOT_PATH, F_OK) == -1)
488 LogPedantic("No root path found. Creating root path...");
491 if (mkdir(GENERIC_NOTI_ROOT_PATH, 0755) == -1)
493 LogPedantic("Failed to create root path!");
494 return std::string("~") + eventName;
497 LogPedantic("Root path created.");
500 return std::string(GENERIC_NOTI_ROOT_PATH) + "/" + eventName;
503 void EventDeliverySystemDetail::Listen(const EventMessages::RoamingChanged &event)
505 LogPedantic("RoamingChanged message listen.");
508 RegisterSettingCallback(VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL);
511 void EventDeliverySystemDetail::Listen(const EventMessages::NetworkTypeChanged &event)
513 LogPedantic("NetworkTypeChanged message listen.");
516 RegisterSettingCallback(VCONFKEY_TELEPHONY_SVC_ROAM);
519 void EventDeliverySystemDetail::Listen(const EventMessages::HibernationEnter &event)
521 LogPedantic("HibernationEnter message listen.");
524 RegisterGlobalNotiCallback(GlobalNotiHibernationEnterSignal);
527 void EventDeliverySystemDetail::Listen(const EventMessages::HibernationLeave &event)
529 LogPedantic("HibernationLeave message listen.");
532 RegisterGlobalNotiCallback(GlobalNotiHibernationLeaveSignal);
535 void EventDeliverySystemDetail::Unlisten(const EventMessages::RoamingChanged &event)
537 LogPedantic("RoamingChanged message unlisten.");
540 UnregisterSettingCallback(VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL);
543 void EventDeliverySystemDetail::Unlisten(const EventMessages::NetworkTypeChanged &event)
545 LogPedantic("NetworkTypeChanged message unlisten.");
548 UnregisterSettingCallback(VCONFKEY_TELEPHONY_SVC_ROAM);
551 void EventDeliverySystemDetail::Unlisten(const EventMessages::HibernationEnter &event)
553 LogPedantic("HibernationEnter message unlisten.");
556 UnregisterGlobalNotiCallback(GlobalNotiHibernationEnterSignal);
559 void EventDeliverySystemDetail::Unlisten(const EventMessages::HibernationLeave &event)
561 LogPedantic("HibernationLeave message unlisten.");
564 UnregisterGlobalNotiCallback(GlobalNotiHibernationLeaveSignal);