Taskmanager / src /

data.c

  1. /*
  2. * Copyright (c) 2016 Samsung Electronics Co., Ltd
  3. *
  4. * Licensed under the Flora License, Version 1.1 (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
  7. *
  8. * http://floralicense.org/license/
  9. *
  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.
  15. */
  16.  
  17. #include <package_manager.h>
  18. #include <app_common.h>
  19. #include <app_manager.h>
  20. #include <Elementary.h>
  21.  
  22. #include "data.h"
  23. #include "$(appName).h"
  24. #include "item.h"
  25. #include "defines.h"
  26.  
  27. static struct data_info {
  28. app_info_filter_h app_info_filter;
  29. Eina_List *apps_list;
  30. char *taskmgr_id;
  31. } s_info = {
  32. .app_info_filter = NULL,
  33. .apps_list = NULL,
  34. .taskmgr_id = NULL
  35. };
  36.  
  37. app_item_t *_item_create(const char *app_id, const char *icon_path);
  38. static void _clear_application_list(void);
  39. static bool _app_info_cb(app_info_h app_info, void *user_data);
  40. static int _compare_strings(char *app_id1, char *app_id2);
  41. static int _compare_items_cb(const void *data1, const void *data2);
  42. static void _remove_app_from_list(char *app_id);
  43.  
  44.  
  45. /**
  46. * @brief Initialization function for data module.
  47. */
  48. void data_initialize(void)
  49. {
  50. if (app_info_filter_create(&s_info.app_info_filter) != APP_MANAGER_ERROR_NONE) {
  51. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create app info filter");
  52. return;
  53. }
  54.  
  55. if (app_info_filter_add_bool(s_info.app_info_filter, PACKAGE_INFO_PROP_APP_NODISPLAY, false) != APP_MANAGER_ERROR_NONE) {
  56. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to set nodisplay property for filter");
  57. return;
  58. }
  59.  
  60. if (app_get_id(&s_info.taskmgr_id) != APP_ERROR_NONE)
  61. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get taskmgr id");
  62. }
  63.  
  64. /**
  65. * @brief Finalization function for data module.
  66. */
  67. void data_finalize(void)
  68. {
  69. if (app_info_filter_destroy(s_info.app_info_filter) != APP_MANAGER_ERROR_NONE)
  70. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to destroy filter handle");
  71.  
  72. s_info.app_info_filter = NULL;
  73.  
  74. _clear_application_list();
  75. }
  76.  
  77. /**
  78. * @brief Function which obtains a list of all the running applications.
  79. * For each found running application, an additional data is acquired:
  80. * - application identifier,
  81. * - application icon path.
  82. * These information is wrapped with app_item_t structure and packed into
  83. * a list.
  84. * @return This function returns the applications list if it was successfully
  85. * created, otherwise NULL is returned.
  86. */
  87. Eina_List * data_application_mgr_get_running_apps(void)
  88. {
  89. if (s_info.apps_list)
  90. _clear_application_list();
  91.  
  92. if (!s_info.app_info_filter) {
  93. dlog_print(DLOG_ERROR, LOG_TAG, "App info filter not initialized");
  94. return NULL;
  95. }
  96.  
  97. if (app_info_filter_foreach_appinfo(s_info.app_info_filter, _app_info_cb, NULL) != APP_MANAGER_ERROR_NONE) {
  98. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to execute callback for each filtered application");
  99. return NULL;
  100. }
  101.  
  102. s_info.apps_list = eina_list_sort(s_info.apps_list, 0, _compare_items_cb);
  103.  
  104. return s_info.apps_list;
  105. }
  106.  
  107. /**
  108. * @brief Function which terminates an application with given identifier.
  109. * @param[in] app_id The identifier of the application to be terminated.
  110. * @return This function returns 'true' if a requested application was successfully
  111. * terminated, otherwise 'false' is returned.
  112. */
  113. bool data_application_mgr_terminate_app(char *app_id)
  114. {
  115. app_context_h app_context = NULL;
  116.  
  117. if (!app_id) {
  118. dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
  119. return false;
  120. }
  121.  
  122. if (app_manager_get_app_context(app_id, &app_context) != APP_MANAGER_ERROR_NONE) {
  123. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get app context");
  124. return false;
  125. }
  126.  
  127. if (app_manager_request_terminate_bg_app(app_context) != APP_MANAGER_ERROR_NONE) {
  128. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to terminate app");
  129. return false;
  130. }
  131.  
  132. if (app_context_destroy(app_context) != APP_MANAGER_ERROR_NONE) {
  133. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to destroy context handle");
  134. return false;
  135. }
  136.  
  137. _remove_app_from_list(app_id);
  138.  
  139. return true;
  140. }
  141.  
  142. /**
  143. * @brief Function which resumes an application with given identifier.
  144. * @param[in] app_id The identifier of the application to be resumed.
  145. * @return This function returns 'true' if a requested application was successfully
  146. * resumed, otherwise 'false' is returned.
  147. */
  148. bool data_application_mgr_resume_app(char *app_id)
  149. {
  150. app_context_h app_context = NULL;
  151.  
  152. if (!app_id) {
  153. dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
  154. return false;
  155. }
  156.  
  157. if (app_manager_get_app_context(app_id, &app_context) != APP_MANAGER_ERROR_NONE) {
  158. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get app context");
  159. return false;
  160. }
  161.  
  162. if (app_manager_resume_app(app_context) != APP_MANAGER_ERROR_NONE) {
  163. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to resume app");
  164. return false;
  165. }
  166.  
  167. if (app_context_destroy(app_context) != APP_MANAGER_ERROR_NONE) {
  168. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to destroy context handle");
  169. return false;
  170. }
  171.  
  172. return true;
  173. }
  174.  
  175. /**
  176. * @brief Internal function which creates an item for application's information
  177. * display (icon and application's identifier).
  178. * @param[in] app_id The identifier of an application which is to be displayed.
  179. * @param[in] icon_path The path to the application's icon to be displayed.
  180. * @return This function returns an allocated app_item_t structure with provided
  181. * data stored. If the function fails, then NULL is returned.
  182. */
  183. app_item_t *_item_create(const char *app_id, const char *icon_path)
  184. {
  185. app_item_t *item;
  186.  
  187. if (!app_id || !icon_path) {
  188. dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
  189. return NULL;
  190. }
  191.  
  192. item = (app_item_t *)calloc(1, sizeof(app_item_t));
  193. if (!item) {
  194. dlog_print(DLOG_ERROR, LOG_TAG, "Allocation failed");
  195. return NULL;
  196. }
  197.  
  198. item->app_id = strdup(app_id);
  199. item->icon_path = strdup(icon_path);
  200.  
  201. return item;
  202. }
  203.  
  204. /**
  205. * @brief Internal function which clears the applications list from all the
  206. * app_item_t structures.
  207. */
  208. static void _clear_application_list(void)
  209. {
  210. Eina_List *it = NULL;
  211. app_item_t *item = NULL;
  212.  
  213. EINA_LIST_FOREACH(s_info.apps_list, it, item)
  214. {
  215. free(item->app_id);
  216. free(item->icon_path);
  217. free(item);
  218. }
  219.  
  220. eina_list_free(s_info.apps_list);
  221. s_info.apps_list = NULL;
  222. }
  223.  
  224. /**
  225. * @brief Internal callback function responsible for applications list creation.
  226. * This callback function is attached with app_info_filter_foreach_appinfo() function
  227. * and is invoked for each installed application which does not have 'no display' flag set.
  228. * Once this callback function is invoked, it obtains the application identifier,
  229. * associated icon's path and running state. If the running state is set to 'false',
  230. * then this function ends its execution, otherwise all the acquired information
  231. * is stored in a list in a form of app_item_t structure.
  232. * @param[in] app_info The application information handle which is used for application's
  233. * identifier and icon's path acquisition.
  234. * @param[in] user_data The user data passed to the app_info_filter_foreach_appinfo() function.
  235. * @return This function returns 'true' if provided app_info represents running application,
  236. * otherwise 'false' is returned.
  237. */
  238. static bool _app_info_cb(app_info_h app_info, void *user_data)
  239. {
  240. char *app_id = NULL;
  241. char *app_icon = NULL;
  242. bool running = false;
  243. app_item_t *new_item = NULL;
  244.  
  245. if (app_info_get_app_id(app_info, &app_id) != APP_MANAGER_ERROR_NONE) {
  246. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get app id");
  247. return false;
  248. }
  249.  
  250. if (app_info_get_icon(app_info, &app_icon) != APP_MANAGER_ERROR_NONE) {
  251. char *res_path = app_get_shared_resource_path();
  252. if(!res_path) {
  253. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get app icon");
  254. return false;
  255. }
  256. const char *common_icon = "taskmanager.png";
  257. app_icon = (char*)malloc(1 + strlen(res_path) + strlen(common_icon));
  258. sprintf(app_icon, "%s%s", res_path, common_icon);
  259. }
  260.  
  261. if (app_manager_is_running(app_id, &running) != APP_MANAGER_ERROR_NONE) {
  262. free(app_id);
  263. free(app_icon);
  264. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get running state");
  265. return false;
  266. }
  267.  
  268. if (running && _compare_strings(app_id, s_info.taskmgr_id)) {
  269. new_item = _item_create(app_id, app_icon);
  270. if (!new_item) {
  271. free(app_id);
  272. free(app_icon);
  273. dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create new item");
  274. return false;
  275. }
  276.  
  277. s_info.apps_list = eina_list_append(s_info.apps_list, new_item);
  278. }
  279.  
  280. free(app_id);
  281. free(app_icon);
  282.  
  283. return true;
  284. }
  285.  
  286. /**
  287. * @brief Internal function which performs two strings comparison with length checking.
  288. * @param[in] app_id1 The first string.
  289. * @param[in] app_id2 The second string.
  290. * @return This function returns:
  291. * - -1 if the first character that does not match has a lower value in app_id1 than in app_id2
  292. * or if both strings are equal,
  293. * - 1 if the first character that does not match has a greater value in app_id1 than in app_id2.
  294. */
  295. static int _compare_strings(char *app_id1, char *app_id2)
  296. {
  297. int ret = strncmp(app_id1, app_id2, ITEM_APP_ID_STR_MAX_LENGTH);
  298.  
  299. if (strlen(app_id1) == strlen(app_id2) && !ret)
  300. return 0;
  301. else
  302. return ret > 0 ? 1 : -1;
  303. }
  304.  
  305. /**
  306. * @brief Internal callback function responsible for two app_item_t structures comparison.
  307. * This function is attached with the eina_list_sort() function and is used for list
  308. * items sorting.
  309. * @param[in] data1 The first data object to compare.
  310. * @param[in] data2 The second data object to compare.
  311. * @return This function returns:
  312. * - -1 if the first character that does not match has a lower value in app_id1 than in app_id2
  313. * or if both strings are equal,
  314. * - 1 if the first character that does not match has a greater value in app_id1 than in app_id2.
  315. */
  316. static int _compare_items_cb(const void *data1, const void *data2)
  317. {
  318. app_item_t *item1 = NULL;
  319. app_item_t *item2 = NULL;
  320.  
  321. if (!data1 || !data2) {
  322. dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
  323. return 0;
  324. }
  325.  
  326. item1 = (app_item_t *)data1;
  327. item2 = (app_item_t *)data2;
  328.  
  329. return _compare_strings(item1->app_id, item2->app_id);
  330. }
  331.  
  332. /**
  333. * @brief Internal function responsible for app_item structure with given application
  334. * identifier removal from the list.
  335. * @param[in] app_id The application identifier which structure is to be removed.
  336. */
  337. static void _remove_app_from_list(char *app_id)
  338. {
  339. Eina_List *it = NULL;
  340. app_item_t *item = NULL;
  341.  
  342. EINA_LIST_FOREACH(s_info.apps_list, it, item)
  343. if (!_compare_strings(item->app_id, app_id)) {
  344. s_info.apps_list = eina_list_remove(s_info.apps_list, item);
  345. free(item->app_id);
  346. free(item->icon_path);
  347. free(item);
  348. break;
  349. }
  350. }