2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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.
18 * @file FApp_ActiveWindowManager.cpp
19 * @brief This is the implementation for the _ActiveWindowManager.cpp class.
22 #include <unique_ptr.h>
29 #include <FBaseSysLog.h>
30 #include <FAppIActiveAppEventListener.h>
32 #include <FBaseRt_LibraryImpl.h>
35 #include "FApp_ActiveWindowManager.h"
37 using namespace Tizen::Base;
38 using namespace Tizen::Base::Collection;
39 using namespace Tizen::Base::Runtime;
44 const wchar_t OSP_ECORE_X_SONAME[] = L"libecore_x.so.1";
45 const wchar_t OSP_ECORE_SONAME[] = L"libecore.so.1";
46 const wchar_t OSP_X11_SONAME[] = L"libX11.so.6";
48 // ActiveWindow related function and variable from shared library.
50 static Ecore_X_Atom(* p_ecore_x_atom_get)(const char* name) = null;
51 static int(* p_ecore_x_window_prop_window_get)(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Window* val, unsigned int len) = null;
52 static Eina_Bool(* p_ecore_x_netwm_pid_get)(Ecore_X_Window win, int* pid) = null;
53 static int(* p_ecore_x_netwm_name_get)(Ecore_X_Window win, char** name) = null;
54 static Ecore_X_Window* (* p_ecore_x_window_root_list)(int* num_ret) = null;
55 static int* p_ECORE_X_EVENT_WINDOW_PROPERTY = null;
57 static Ecore_Event_Handler* (* p_ecore_event_handler_add)(int type, Ecore_Event_Handler_Cb func, const void* data) = null;
58 static void* (* p_ecore_event_handler_del)(Ecore_Event_Handler* event_handler) = null;
60 static int (* p_XSelectInput)(Display* display, Window w, long event_mask) = null;
61 static Display* (* p_XOpenDisplay)(_Xconst char* display_name) = null;
62 static int (* p_XCloseDisplay)(Display* display) = null;
64 static Ecore_Event_Handler* pWindowPropertyChanged = null;
66 struct _DisplayDeleter
68 void operator()(Display* pDisplay)
72 p_XCloseDisplay(pDisplay);
77 } // anonymous name-space
80 namespace Tizen { namespace App
83 _ActiveWindowManager::_ActiveWindowManager(void)
85 , __pEcoreXLibrary(null)
86 , __pEcoreLibrary(null)
90 _ActiveWindowManager::~_ActiveWindowManager(void)
92 if (__activeAppEventListenerList.GetCount() > 0)
94 if (p_ecore_event_handler_del == null)
96 _LibraryImpl& lib = GetEcoreLibraryImpl();
97 p_ecore_event_handler_del = reinterpret_cast<void*(*)(Ecore_Event_Handler* event_handler)>(lib.GetProcAddress(L"ecore_event_handler_del"));
99 if (p_ecore_event_handler_del)
101 if (pWindowPropertyChanged)
103 p_ecore_event_handler_del(pWindowPropertyChanged);
104 pWindowPropertyChanged = null;
109 delete __pX11Library;
110 delete __pEcoreXLibrary;
111 __pEcoreXLibrary = null;
112 delete __pEcoreLibrary;
113 __pEcoreLibrary = null;
117 _ActiveWindowManager::OnPropertyChanged(void* pData, int type, void* pEvent)
121 SysLog(NID_UI, "The data is not valid.");
125 _ActiveWindowManager* pThis = static_cast<_ActiveWindowManager*>(pData);
127 if (p_ecore_x_atom_get == null)
129 _LibraryImpl& lib = pThis->GetEcoreXLibraryImpl();
130 p_ecore_x_atom_get = reinterpret_cast<Ecore_X_Atom(*)(const char* name)>(lib.GetProcAddress(L"ecore_x_atom_get"));
131 SysTryReturnResult(NID_APP, p_ecore_x_atom_get != null, EINA_FALSE,
132 "A system error has been occurred. Failed to get ecore_x_atom_get.");
134 if (p_ecore_x_window_prop_window_get == null)
136 _LibraryImpl& lib = pThis->GetEcoreXLibraryImpl();
137 p_ecore_x_window_prop_window_get = reinterpret_cast<int(*)(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Window* val, unsigned int len)>(lib.GetProcAddress(L"ecore_x_window_prop_window_get"));
138 SysTryReturnResult(NID_APP, p_ecore_x_window_prop_window_get != null, EINA_FALSE,
139 "A system error has been occurred. Failed to get ecore_x_window_prop_window_get.");
141 if (p_ecore_x_netwm_pid_get == null)
143 _LibraryImpl& lib = pThis->GetEcoreXLibraryImpl();
144 p_ecore_x_netwm_pid_get = reinterpret_cast<Eina_Bool(*)(Ecore_X_Window win, int* pid)>(lib.GetProcAddress(L"ecore_x_netwm_pid_get"));
145 SysTryReturnResult(NID_APP, p_ecore_x_netwm_pid_get != null, EINA_FALSE,
146 "A system error has been occurred. Failed to get ecore_x_netwm_pid_get.");
148 if (p_ecore_x_netwm_name_get == null)
150 _LibraryImpl& lib = pThis->GetEcoreXLibraryImpl();
151 p_ecore_x_netwm_name_get = reinterpret_cast<int(*)(Ecore_X_Window win, char** name)>(lib.GetProcAddress(L"ecore_x_netwm_name_get"));
152 SysTryReturnResult(NID_APP, p_ecore_x_netwm_name_get != null, EINA_FALSE,
153 "A system error has been occurred. Failed to get ecore_x_netwm_name_get.");
158 SysLog(NID_UI, "The event is not valid.");
162 Ecore_X_Event_Window_Property* pE = (Ecore_X_Event_Window_Property*) pEvent;
163 Ecore_X_Atom atom = pE->atom;
164 Ecore_X_Atom activeAtom = p_ecore_x_atom_get("_NET_ACTIVE_WINDOW");
166 if (atom != activeAtom)
168 return ECORE_CALLBACK_PASS_ON;
171 Ecore_X_Window win = pE->win;
172 Ecore_X_Window activeWin = 0;
173 p_ecore_x_window_prop_window_get(win, activeAtom, &activeWin, 1);
176 p_ecore_x_netwm_pid_get(activeWin, &pid);
178 char* pAppName = null;
179 p_ecore_x_netwm_name_get(activeWin, &pAppName);
181 pThis->FireActiveAppEvent(activeWin, pid, pAppName);
188 return ECORE_CALLBACK_PASS_ON;
192 _ActiveWindowManager::AddActiveAppEventListener(IActiveAppEventListener& listener)
194 if (p_ecore_x_window_root_list == null)
196 _LibraryImpl& lib = GetEcoreXLibraryImpl();
197 p_ecore_x_window_root_list = reinterpret_cast<Ecore_X_Window*(*)(int* num_ret)>(lib.GetProcAddress(L"ecore_x_window_root_list"));
198 SysTryReturnResult(NID_APP, p_ecore_x_window_root_list != null, E_SYSTEM,
199 "A system error has been occurred. Failed to get p_ecore_x_window_root_list.");
201 if (p_ECORE_X_EVENT_WINDOW_PROPERTY == null)
203 _LibraryImpl& lib = GetEcoreXLibraryImpl();
204 p_ECORE_X_EVENT_WINDOW_PROPERTY = reinterpret_cast<int*>(lib.GetProcAddress(L"ECORE_X_EVENT_WINDOW_PROPERTY"));
205 SysTryReturnResult(NID_APP, p_ECORE_X_EVENT_WINDOW_PROPERTY != null, E_SYSTEM,
206 "A system error has been occurred. Failed to get p_ECORE_X_EVENT_WINDOW_PROPERTY.");
208 if (p_XOpenDisplay == null)
210 _LibraryImpl& lib = GetX11LibraryImpl();
211 p_XOpenDisplay = reinterpret_cast<Display*(*)(_Xconst char* display_name)>(lib.GetProcAddress(L"XOpenDisplay"));
212 SysTryReturnResult(NID_APP, p_XOpenDisplay != null, E_SYSTEM,
213 "A system error has been occurred. Failed to get p_XOpenDisplay.");
215 if (p_XCloseDisplay == null)
217 _LibraryImpl& lib = GetX11LibraryImpl();
218 p_XCloseDisplay = reinterpret_cast<int(*)(Display* display)>(lib.GetProcAddress(L"XCloseDisplay"));
219 SysTryReturnResult(NID_APP, p_XCloseDisplay != null, E_SYSTEM,
220 "A system error has been occurred. Failed to get p_XCloseDisplay.");
222 if (p_XSelectInput == null)
224 _LibraryImpl& lib = GetX11LibraryImpl();
225 p_XSelectInput = reinterpret_cast<int(*)(Display* display, Window w, long event_mask)>(lib.GetProcAddress(L"XSelectInput"));
226 SysTryReturnResult(NID_APP, p_XSelectInput != null, E_SYSTEM,
227 "A system error has been occurred. Failed to get p_XSelectInput.");
230 if (p_ecore_event_handler_add == null)
232 _LibraryImpl& lib = GetEcoreLibraryImpl();
233 p_ecore_event_handler_add = reinterpret_cast<Ecore_Event_Handler*(*)(int type, Ecore_Event_Handler_Cb func, const void* data)>(lib.GetProcAddress(L"ecore_event_handler_add"));
234 SysTryReturnResult(NID_APP, p_ecore_event_handler_add != null, E_SYSTEM,
235 "A system error has been occurred. Failed to get p_ecore_event_handler_add.");
238 bool alreadyExist = __activeAppEventListenerList.Contains(&listener);
239 SysTryReturnResult(NID_APP, !alreadyExist, E_OBJ_ALREADY_EXIST, "The event listener already exist.");
240 result r = __activeAppEventListenerList.Add(&listener);
243 SysPropagate(NID_APP, r);
247 if (!pWindowPropertyChanged)
249 std::unique_ptr<Display, _DisplayDeleter> pDisplay(p_XOpenDisplay(NULL));
250 SysTryReturnResult(NID_APP, pDisplay != null, E_SYSTEM, "A system error has been occurred. Failed to XOpenDisplay.");
253 Ecore_X_Window* pRoots = p_ecore_x_window_root_list(&num);
254 SysTryReturnResult(NID_APP, pRoots != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
256 for (int i = 0; i < num; i++)
258 p_XSelectInput(pDisplay.get(), pRoots[i], PropertyChangeMask);
261 pWindowPropertyChanged = p_ecore_event_handler_add(*p_ECORE_X_EVENT_WINDOW_PROPERTY, OnPropertyChanged, (void*) this);
263 SysTryReturnResult(NID_APP, pWindowPropertyChanged, E_SYSTEM, "A system error has been occurred.");
270 _ActiveWindowManager::RemoveActiveAppEventListener(IActiveAppEventListener& listener)
272 if (p_ecore_event_handler_del == null)
274 _LibraryImpl& lib = GetEcoreLibraryImpl();
275 p_ecore_event_handler_del = reinterpret_cast<void*(*)(Ecore_Event_Handler* event_handler)>(lib.GetProcAddress(L"ecore_event_handler_del"));
276 SysTryReturnResult(NID_APP, p_ecore_event_handler_del != null, E_SYSTEM,
277 "A system error has been occurred. Failed to get p_ecore_event_handler_del.");
280 result r = __activeAppEventListenerList.Remove(&listener);
283 SysPropagate(NID_APP, r);
287 if (__activeAppEventListenerList.GetCount() == 0)
289 p_ecore_event_handler_del(pWindowPropertyChanged);
290 pWindowPropertyChanged = null;
298 _ActiveWindowManager::FireActiveAppEvent(unsigned int xid, int pid, const char* pAppName)
300 static int oldPid = 0;
304 char pkgname[255] = {0, };
305 if ((AUL_R_OK != aul_app_get_pkgname_bypid(pid, pkgname, 255)) || pkgname[0] == 0)
307 SysSecureLog(NID_APP, "Failed to get the package name from pid=%x pAppName=%s", pid, pAppName ? pAppName : "null");
310 AppId appId(_Aul::GetRealAppId(String(pkgname)));
312 std::unique_ptr<IEnumeratorT<Tizen::App::IActiveAppEventListener* > > pEnum(__activeAppEventListenerList.GetEnumeratorN());
315 while (pEnum->MoveNext() == E_SUCCESS)
317 Tizen::App::IActiveAppEventListener* pListener = null;
318 pEnum->GetCurrent(pListener);
321 pListener->OnActiveAppChanged(appId);
330 _ActiveWindowManager::GetActiveApp(AppId& appId)
332 const unsigned int windowId = GetActiveWindow();
333 const int processId = GetProcessId(windowId);
334 char pkgname[255] = {0, };
335 if (aul_app_get_pkgname_bypid(processId, pkgname, 255) != AUL_R_OK)
337 SysSecureLog(NID_APP, "Failed to get the package name from pid=%x appId=%ls", processId, appId.GetPointer());
341 appId = _Aul::GetRealAppId(String(pkgname));
343 SysLog(NID_APP, "ActiveApp is %ls.", appId.GetPointer());
348 _ActiveWindowManager::GetEcoreXLibraryImpl(void)
350 if (__pEcoreXLibrary == null)
352 __pEcoreXLibrary = new (std::nothrow) _LibraryImpl;
353 SysAssertf(__pEcoreXLibrary != null, "_LibraryImpl allocation failure.");
355 result r = __pEcoreXLibrary->Construct(OSP_ECORE_X_SONAME);
356 SysAssertf(r == E_SUCCESS, "Dynamic loading error : %s.", GetErrorMessage(r));
358 return *__pEcoreXLibrary;
362 _ActiveWindowManager::GetEcoreLibraryImpl(void)
364 if (__pEcoreLibrary == null)
366 __pEcoreLibrary = new (std::nothrow) _LibraryImpl;
367 SysAssertf(__pEcoreLibrary != null, "_LibraryImpl allocation failure.");
369 result r = __pEcoreLibrary->Construct(OSP_ECORE_SONAME);
370 SysAssertf(r == E_SUCCESS, "Dynamic loading error : %s.", GetErrorMessage(r));
372 return *__pEcoreLibrary;
376 _ActiveWindowManager::GetX11LibraryImpl(void)
378 if (__pX11Library == null)
380 __pX11Library = new (std::nothrow) _LibraryImpl;
381 SysAssertf(__pX11Library != null, "_LibraryImpl allocation failure.");
383 result r = __pX11Library->Construct(OSP_X11_SONAME);
384 SysAssertf(r == E_SUCCESS, "Dynamic loading error : %s.", GetErrorMessage(r));
386 return *__pX11Library;
390 _ActiveWindowManager::GetActiveWindow(void)
392 if (p_ecore_x_window_root_list == null)
394 _LibraryImpl& lib = GetEcoreXLibraryImpl();
395 p_ecore_x_window_root_list = reinterpret_cast<Ecore_X_Window*(*)(int* num_ret)>(lib.GetProcAddress(L"ecore_x_window_root_list"));
396 SysTryReturnResult(NID_APP, p_ecore_x_window_root_list != null, 0,
397 "A system error has been occurred. Failed to get p_ecore_x_window_root_list.");
399 if (p_ecore_x_atom_get == null)
401 _LibraryImpl& lib = GetEcoreXLibraryImpl();
402 p_ecore_x_atom_get = reinterpret_cast<Ecore_X_Atom(*)(const char* name)>(lib.GetProcAddress(L"ecore_x_atom_get"));
403 SysTryReturnResult(NID_APP, p_ecore_x_atom_get != null, 0,
404 "A system error has been occurred. Failed to get ecore_x_atom_get.");
406 if (p_ecore_x_window_prop_window_get == null)
408 _LibraryImpl& lib = GetEcoreXLibraryImpl();
409 p_ecore_x_window_prop_window_get = reinterpret_cast<int(*)(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Window* val, unsigned int len)>(lib.GetProcAddress(L"ecore_x_window_prop_window_get"));
410 SysTryReturnResult(NID_APP, p_ecore_x_window_prop_window_get != null, EINA_FALSE,
411 "A system error has been occurred. Failed to get ecore_x_window_prop_window_get.");
415 Ecore_X_Window* pRoots = p_ecore_x_window_root_list(&num);
417 Ecore_X_Window activeWin = 0;
420 Ecore_X_Atom activeAtom = p_ecore_x_atom_get("_NET_ACTIVE_WINDOW");
421 p_ecore_x_window_prop_window_get(pRoots[0], activeAtom, &activeWin, 1);
429 _ActiveWindowManager::GetProcessId(unsigned int window)
431 if (p_ecore_x_netwm_pid_get == null)
433 _LibraryImpl& lib = GetEcoreXLibraryImpl();
434 p_ecore_x_netwm_pid_get = reinterpret_cast<Eina_Bool(*)(Ecore_X_Window win, int* pid)>(lib.GetProcAddress(L"ecore_x_netwm_pid_get"));
435 SysTryReturnResult(NID_APP, p_ecore_x_netwm_pid_get != null, EINA_FALSE,
436 "A system error has been occurred. Failed to get ecore_x_netwm_pid_get.");
440 p_ecore_x_netwm_pid_get(window, &pid);