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::Utility;
40 using namespace Tizen::Base::Runtime;
45 const wchar_t OSP_ECORE_X_SONAME[] = L"libecore_x.so.1";
46 const wchar_t OSP_ECORE_SONAME[] = L"libecore.so.1";
47 const wchar_t OSP_X11_SONAME[] = L"libX11.so.6";
49 // ActiveWindow related function and variable from shared library.
51 static Ecore_X_Atom(* p_ecore_x_atom_get)(const char* name) = null;
52 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;
53 static Eina_Bool(* p_ecore_x_netwm_pid_get)(Ecore_X_Window win, int* pid) = null;
54 static int(* p_ecore_x_netwm_name_get)(Ecore_X_Window win, char** name) = null;
55 static Ecore_X_Window* (* p_ecore_x_window_root_list)(int* num_ret) = null;
56 static int* p_ECORE_X_EVENT_WINDOW_PROPERTY = null;
58 static Ecore_Event_Handler* (* p_ecore_event_handler_add)(int type, Ecore_Event_Handler_Cb func, const void* data) = null;
59 static void* (* p_ecore_event_handler_del)(Ecore_Event_Handler* event_handler) = null;
61 static int (* p_XSelectInput)(Display* display, Window w, long event_mask) = null;
62 static Display* (* p_XOpenDisplay)(_Xconst char* display_name) = null;
63 static int (* p_XCloseDisplay)(Display* display) = null;
65 static Ecore_Event_Handler* pWindowPropertyChanged = null;
67 struct _DisplayDeleter
69 void operator()(Display* pDisplay)
73 p_XCloseDisplay(pDisplay);
78 } // anonymous name-space
81 namespace Tizen { namespace App
84 _ActiveWindowManager::_ActiveWindowManager(void)
86 , __pEcoreXLibrary(null)
87 , __pEcoreLibrary(null)
91 _ActiveWindowManager::~_ActiveWindowManager(void)
93 if (__activeAppEventListenerList.GetCount() > 0)
95 if (p_ecore_event_handler_del == null)
97 _LibraryImpl& lib = GetEcoreLibraryImpl();
98 p_ecore_event_handler_del = reinterpret_cast<void*(*)(Ecore_Event_Handler* event_handler)>(lib.GetProcAddress(L"ecore_event_handler_del"));
100 if (p_ecore_event_handler_del)
102 if (pWindowPropertyChanged)
104 p_ecore_event_handler_del(pWindowPropertyChanged);
105 pWindowPropertyChanged = null;
110 delete __pX11Library;
111 delete __pEcoreXLibrary;
112 __pEcoreXLibrary = null;
113 delete __pEcoreLibrary;
114 __pEcoreLibrary = null;
118 _ActiveWindowManager::OnPropertyChanged(void* pData, int type, void* pEvent)
122 SysLog(NID_UI, "The data is not valid.");
126 _ActiveWindowManager* pThis = static_cast<_ActiveWindowManager*>(pData);
128 if (p_ecore_x_atom_get == null)
130 _LibraryImpl& lib = pThis->GetEcoreXLibraryImpl();
131 p_ecore_x_atom_get = reinterpret_cast<Ecore_X_Atom(*)(const char* name)>(lib.GetProcAddress(L"ecore_x_atom_get"));
132 SysTryReturnResult(NID_APP, p_ecore_x_atom_get != null, EINA_FALSE,
133 "A system error has been occurred. Failed to get ecore_x_atom_get.");
135 if (p_ecore_x_window_prop_window_get == null)
137 _LibraryImpl& lib = pThis->GetEcoreXLibraryImpl();
138 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"));
139 SysTryReturnResult(NID_APP, p_ecore_x_window_prop_window_get != null, EINA_FALSE,
140 "A system error has been occurred. Failed to get ecore_x_window_prop_window_get.");
142 if (p_ecore_x_netwm_pid_get == null)
144 _LibraryImpl& lib = pThis->GetEcoreXLibraryImpl();
145 p_ecore_x_netwm_pid_get = reinterpret_cast<Eina_Bool(*)(Ecore_X_Window win, int* pid)>(lib.GetProcAddress(L"ecore_x_netwm_pid_get"));
146 SysTryReturnResult(NID_APP, p_ecore_x_netwm_pid_get != null, EINA_FALSE,
147 "A system error has been occurred. Failed to get ecore_x_netwm_pid_get.");
149 if (p_ecore_x_netwm_name_get == null)
151 _LibraryImpl& lib = pThis->GetEcoreXLibraryImpl();
152 p_ecore_x_netwm_name_get = reinterpret_cast<int(*)(Ecore_X_Window win, char** name)>(lib.GetProcAddress(L"ecore_x_netwm_name_get"));
153 SysTryReturnResult(NID_APP, p_ecore_x_netwm_name_get != null, EINA_FALSE,
154 "A system error has been occurred. Failed to get ecore_x_netwm_name_get.");
159 SysLog(NID_UI, "The event is not valid.");
163 Ecore_X_Event_Window_Property* pE = (Ecore_X_Event_Window_Property*) pEvent;
164 Ecore_X_Atom atom = pE->atom;
165 Ecore_X_Atom activeAtom = p_ecore_x_atom_get("_NET_ACTIVE_WINDOW");
167 if (atom != activeAtom)
169 return ECORE_CALLBACK_PASS_ON;
172 Ecore_X_Window win = pE->win;
173 Ecore_X_Window activeWin = 0;
174 p_ecore_x_window_prop_window_get(win, activeAtom, &activeWin, 1);
177 p_ecore_x_netwm_pid_get(activeWin, &pid);
179 char* pAppName = null;
180 p_ecore_x_netwm_name_get(activeWin, &pAppName);
182 pThis->FireActiveAppEvent(activeWin, pid, pAppName);
189 return ECORE_CALLBACK_PASS_ON;
193 _ActiveWindowManager::AddActiveAppEventListener(IActiveAppEventListener& listener)
195 if (p_ecore_x_window_root_list == null)
197 _LibraryImpl& lib = GetEcoreXLibraryImpl();
198 p_ecore_x_window_root_list = reinterpret_cast<Ecore_X_Window*(*)(int* num_ret)>(lib.GetProcAddress(L"ecore_x_window_root_list"));
199 SysTryReturnResult(NID_APP, p_ecore_x_window_root_list != null, E_SYSTEM,
200 "A system error has been occurred. Failed to get p_ecore_x_window_root_list.");
202 if (p_ECORE_X_EVENT_WINDOW_PROPERTY == null)
204 _LibraryImpl& lib = GetEcoreXLibraryImpl();
205 p_ECORE_X_EVENT_WINDOW_PROPERTY = reinterpret_cast<int*>(lib.GetProcAddress(L"ECORE_X_EVENT_WINDOW_PROPERTY"));
206 SysTryReturnResult(NID_APP, p_ECORE_X_EVENT_WINDOW_PROPERTY != null, E_SYSTEM,
207 "A system error has been occurred. Failed to get p_ECORE_X_EVENT_WINDOW_PROPERTY.");
209 if (p_XOpenDisplay == null)
211 _LibraryImpl& lib = GetX11LibraryImpl();
212 p_XOpenDisplay = reinterpret_cast<Display*(*)(_Xconst char* display_name)>(lib.GetProcAddress(L"XOpenDisplay"));
213 SysTryReturnResult(NID_APP, p_XOpenDisplay != null, E_SYSTEM,
214 "A system error has been occurred. Failed to get p_XOpenDisplay.");
216 if (p_XCloseDisplay == null)
218 _LibraryImpl& lib = GetX11LibraryImpl();
219 p_XCloseDisplay = reinterpret_cast<int(*)(Display* display)>(lib.GetProcAddress(L"XCloseDisplay"));
220 SysTryReturnResult(NID_APP, p_XCloseDisplay != null, E_SYSTEM,
221 "A system error has been occurred. Failed to get p_XCloseDisplay.");
223 if (p_XSelectInput == null)
225 _LibraryImpl& lib = GetX11LibraryImpl();
226 p_XSelectInput = reinterpret_cast<int(*)(Display* display, Window w, long event_mask)>(lib.GetProcAddress(L"XSelectInput"));
227 SysTryReturnResult(NID_APP, p_XSelectInput != null, E_SYSTEM,
228 "A system error has been occurred. Failed to get p_XSelectInput.");
231 if (p_ecore_event_handler_add == null)
233 _LibraryImpl& lib = GetEcoreLibraryImpl();
234 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"));
235 SysTryReturnResult(NID_APP, p_ecore_event_handler_add != null, E_SYSTEM,
236 "A system error has been occurred. Failed to get p_ecore_event_handler_add.");
239 bool alreadyExist = __activeAppEventListenerList.Contains(&listener);
240 SysTryReturnResult(NID_APP, !alreadyExist, E_OBJ_ALREADY_EXIST, "The event listener already exist.");
241 result r = __activeAppEventListenerList.Add(&listener);
242 SysTryReturn(NID_APP, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
244 if (!pWindowPropertyChanged)
246 std::unique_ptr<Display, _DisplayDeleter> pDisplay(p_XOpenDisplay(NULL));
247 SysTryReturnResult(NID_APP, pDisplay != null, E_SYSTEM, "A system error has been occurred. Failed to XOpenDisplay.");
250 Ecore_X_Window* pRoots = p_ecore_x_window_root_list(&num);
251 SysTryReturnResult(NID_APP, pRoots != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
253 for (int i = 0; i < num; i++)
255 p_XSelectInput(pDisplay.get(), pRoots[i], PropertyChangeMask);
258 pWindowPropertyChanged = p_ecore_event_handler_add(*p_ECORE_X_EVENT_WINDOW_PROPERTY, OnPropertyChanged, (void*) this);
260 SysTryReturnResult(NID_APP, pWindowPropertyChanged, E_SYSTEM, "A system error has been occurred.");
267 _ActiveWindowManager::RemoveActiveAppEventListener(IActiveAppEventListener& listener)
269 if (p_ecore_event_handler_del == null)
271 _LibraryImpl& lib = GetEcoreLibraryImpl();
272 p_ecore_event_handler_del = reinterpret_cast<void*(*)(Ecore_Event_Handler* event_handler)>(lib.GetProcAddress(L"ecore_event_handler_del"));
273 SysTryReturnResult(NID_APP, p_ecore_event_handler_del != null, E_SYSTEM,
274 "A system error has been occurred. Failed to get p_ecore_event_handler_del.");
277 result r = __activeAppEventListenerList.Remove(&listener);
278 SysTryReturn(NID_APP, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
280 if (__activeAppEventListenerList.GetCount() == 0)
282 p_ecore_event_handler_del(pWindowPropertyChanged);
283 pWindowPropertyChanged = null;
291 _ActiveWindowManager::FireActiveAppEvent(unsigned int xid, int pid, const char* pAppName)
293 static int oldPid = 0;
297 char pkgname[255] = {0, };
298 if ((AUL_R_OK != aul_app_get_pkgname_bypid(pid, pkgname, 255)) || pkgname[0] == 0)
300 SysSecureLog(NID_APP, "Failed to get the package name from pid=%x pAppName=%s", pid, pAppName ? pAppName : "null");
303 AppId appId(_Aul::GetRealAppId(String(pkgname)));
305 std::unique_ptr<IEnumeratorT<Tizen::App::IActiveAppEventListener* > > pEnum(__activeAppEventListenerList.GetEnumeratorN());
308 while (pEnum->MoveNext() == E_SUCCESS)
310 Tizen::App::IActiveAppEventListener* pListener = null;
311 pEnum->GetCurrent(pListener);
314 pListener->OnActiveAppChanged(appId);
323 _ActiveWindowManager::GetActiveApp(AppId& appId)
325 const unsigned int windowId = GetActiveWindow();
326 const int processId = GetProcessId(windowId);
327 char pkgname[255] = {0, };
328 if (aul_app_get_pkgname_bypid(processId, pkgname, 255) != AUL_R_OK)
330 SysSecureLog(NID_APP, "Failed to get the package name from pid=%x appId=%ls", processId, appId.GetPointer());
334 appId = _Aul::GetRealAppId(String(pkgname));
336 SysLog(NID_APP, "ActiveApp is %ls.", appId.GetPointer());
341 _ActiveWindowManager::GetEcoreXLibraryImpl(void)
343 if (__pEcoreXLibrary == null)
345 __pEcoreXLibrary = new (std::nothrow) _LibraryImpl;
346 SysAssertf(__pEcoreXLibrary != null, "_LibraryImpl allocation failure.");
348 result r = __pEcoreXLibrary->Construct(OSP_ECORE_X_SONAME);
349 SysAssertf(r == E_SUCCESS, "Dynamic loading error : %s.", GetErrorMessage(r));
351 return *__pEcoreXLibrary;
355 _ActiveWindowManager::GetEcoreLibraryImpl(void)
357 if (__pEcoreLibrary == null)
359 __pEcoreLibrary = new (std::nothrow) _LibraryImpl;
360 SysAssertf(__pEcoreLibrary != null, "_LibraryImpl allocation failure.");
362 result r = __pEcoreLibrary->Construct(OSP_ECORE_SONAME);
363 SysAssertf(r == E_SUCCESS, "Dynamic loading error : %s.", GetErrorMessage(r));
365 return *__pEcoreLibrary;
369 _ActiveWindowManager::GetX11LibraryImpl(void)
371 if (__pX11Library == null)
373 __pX11Library = new (std::nothrow) _LibraryImpl;
374 SysAssertf(__pX11Library != null, "_LibraryImpl allocation failure.");
376 result r = __pX11Library->Construct(OSP_X11_SONAME);
377 SysAssertf(r == E_SUCCESS, "Dynamic loading error : %s.", GetErrorMessage(r));
379 return *__pX11Library;
383 _ActiveWindowManager::GetActiveWindow(void)
385 if (p_ecore_x_window_root_list == null)
387 _LibraryImpl& lib = GetEcoreXLibraryImpl();
388 p_ecore_x_window_root_list = reinterpret_cast<Ecore_X_Window*(*)(int* num_ret)>(lib.GetProcAddress(L"ecore_x_window_root_list"));
389 SysTryReturnResult(NID_APP, p_ecore_x_window_root_list != null, 0,
390 "A system error has been occurred. Failed to get p_ecore_x_window_root_list.");
392 if (p_ecore_x_atom_get == null)
394 _LibraryImpl& lib = GetEcoreXLibraryImpl();
395 p_ecore_x_atom_get = reinterpret_cast<Ecore_X_Atom(*)(const char* name)>(lib.GetProcAddress(L"ecore_x_atom_get"));
396 SysTryReturnResult(NID_APP, p_ecore_x_atom_get != null, 0,
397 "A system error has been occurred. Failed to get ecore_x_atom_get.");
399 if (p_ecore_x_window_prop_window_get == null)
401 _LibraryImpl& lib = GetEcoreXLibraryImpl();
402 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"));
403 SysTryReturnResult(NID_APP, p_ecore_x_window_prop_window_get != null, EINA_FALSE,
404 "A system error has been occurred. Failed to get ecore_x_window_prop_window_get.");
408 Ecore_X_Window* pRoots = p_ecore_x_window_root_list(&num);
410 Ecore_X_Window activeWin = 0;
413 Ecore_X_Atom activeAtom = p_ecore_x_atom_get("_NET_ACTIVE_WINDOW");
414 p_ecore_x_window_prop_window_get(pRoots[0], activeAtom, &activeWin, 1);
422 _ActiveWindowManager::GetProcessId(unsigned int window)
424 if (p_ecore_x_netwm_pid_get == null)
426 _LibraryImpl& lib = GetEcoreXLibraryImpl();
427 p_ecore_x_netwm_pid_get = reinterpret_cast<Eina_Bool(*)(Ecore_X_Window win, int* pid)>(lib.GetProcAddress(L"ecore_x_netwm_pid_get"));
428 SysTryReturnResult(NID_APP, p_ecore_x_netwm_pid_get != null, EINA_FALSE,
429 "A system error has been occurred. Failed to get ecore_x_netwm_pid_get.");
433 p_ecore_x_netwm_pid_get(window, &pid);