desktop_scene_main.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #include <furi.h>
  2. #include <furi_hal.h>
  3. #include <applications.h>
  4. #include <assets_icons.h>
  5. #include <loader/loader.h>
  6. #include "../desktop_i.h"
  7. #include "../views/desktop_events.h"
  8. #include "../views/desktop_view_main.h"
  9. #include "desktop_scene.h"
  10. #include "desktop_scene_i.h"
  11. #define TAG "DesktopSrv"
  12. #define MUSIC_PLAYER_APP EXT_PATH("/apps/Misc/music_player.fap")
  13. #define SNAKE_GAME_APP EXT_PATH("/apps/Games/snake_game.fap")
  14. #define CLOCK_APP EXT_PATH("/apps/Tools/clock.fap")
  15. static void desktop_scene_main_new_idle_animation_callback(void* context) {
  16. furi_assert(context);
  17. Desktop* desktop = context;
  18. view_dispatcher_send_custom_event(
  19. desktop->view_dispatcher, DesktopAnimationEventNewIdleAnimation);
  20. }
  21. static void desktop_scene_main_check_animation_callback(void* context) {
  22. furi_assert(context);
  23. Desktop* desktop = context;
  24. view_dispatcher_send_custom_event(
  25. desktop->view_dispatcher, DesktopAnimationEventCheckAnimation);
  26. }
  27. static void desktop_scene_main_interact_animation_callback(void* context) {
  28. furi_assert(context);
  29. Desktop* desktop = context;
  30. view_dispatcher_send_custom_event(
  31. desktop->view_dispatcher, DesktopAnimationEventInteractAnimation);
  32. }
  33. #ifdef APP_ARCHIVE
  34. static void desktop_switch_to_app(Desktop* desktop, const FlipperApplication* flipper_app) {
  35. furi_assert(desktop);
  36. furi_assert(flipper_app);
  37. furi_assert(flipper_app->app);
  38. furi_assert(flipper_app->name);
  39. if(furi_thread_get_state(desktop->scene_thread) != FuriThreadStateStopped) {
  40. FURI_LOG_E("Desktop", "Thread is already running");
  41. return;
  42. }
  43. FuriHalRtcHeapTrackMode mode = furi_hal_rtc_get_heap_track_mode();
  44. if(mode > FuriHalRtcHeapTrackModeNone) {
  45. furi_thread_enable_heap_trace(desktop->scene_thread);
  46. } else {
  47. furi_thread_disable_heap_trace(desktop->scene_thread);
  48. }
  49. furi_thread_set_name(desktop->scene_thread, flipper_app->name);
  50. furi_thread_set_stack_size(desktop->scene_thread, flipper_app->stack_size);
  51. furi_thread_set_callback(desktop->scene_thread, flipper_app->app);
  52. furi_thread_start(desktop->scene_thread);
  53. }
  54. #endif
  55. static void desktop_scene_main_open_app_or_profile(Desktop* desktop, const char* path) {
  56. do {
  57. LoaderStatus status = loader_start(desktop->loader, FAP_LOADER_APP_NAME, path);
  58. if(status == LoaderStatusOk) break;
  59. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  60. status = loader_start(desktop->loader, "Passport", NULL);
  61. if(status != LoaderStatusOk) {
  62. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  63. }
  64. } while(false);
  65. }
  66. void desktop_scene_main_callback(DesktopEvent event, void* context) {
  67. Desktop* desktop = (Desktop*)context;
  68. view_dispatcher_send_custom_event(desktop->view_dispatcher, event);
  69. }
  70. void desktop_scene_main_on_enter(void* context) {
  71. Desktop* desktop = (Desktop*)context;
  72. DesktopMainView* main_view = desktop->main_view;
  73. animation_manager_set_context(desktop->animation_manager, desktop);
  74. animation_manager_set_new_idle_callback(
  75. desktop->animation_manager, desktop_scene_main_new_idle_animation_callback);
  76. animation_manager_set_check_callback(
  77. desktop->animation_manager, desktop_scene_main_check_animation_callback);
  78. animation_manager_set_interact_callback(
  79. desktop->animation_manager, desktop_scene_main_interact_animation_callback);
  80. desktop_main_set_callback(main_view, desktop_scene_main_callback, desktop);
  81. view_dispatcher_switch_to_view(desktop->view_dispatcher, DesktopViewIdMain);
  82. }
  83. bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) {
  84. Desktop* desktop = (Desktop*)context;
  85. bool consumed = false;
  86. if(event.type == SceneManagerEventTypeCustom) {
  87. switch(event.event) {
  88. case DesktopMainEventOpenMenu:
  89. loader_show_menu();
  90. consumed = true;
  91. break;
  92. case DesktopMainEventOpenLockMenu:
  93. scene_manager_next_scene(desktop->scene_manager, DesktopSceneLockMenu);
  94. consumed = true;
  95. break;
  96. case DesktopMainEventOpenDebug:
  97. scene_manager_next_scene(desktop->scene_manager, DesktopSceneDebug);
  98. consumed = true;
  99. break;
  100. case DesktopMainEventOpenArchive:
  101. #ifdef APP_ARCHIVE
  102. desktop_switch_to_app(desktop, &FLIPPER_ARCHIVE);
  103. #endif
  104. consumed = true;
  105. break;
  106. case DesktopMainEventOpenPowerOff: {
  107. LoaderStatus status = loader_start(desktop->loader, "Power", "off");
  108. if(status != LoaderStatusOk) {
  109. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  110. }
  111. consumed = true;
  112. break;
  113. }
  114. case DesktopMainEventOpenFavoritePrimary:
  115. DESKTOP_SETTINGS_LOAD(&desktop->settings);
  116. if(desktop->settings.favorite_primary.is_external) {
  117. LoaderStatus status = loader_start(
  118. desktop->loader,
  119. FAP_LOADER_APP_NAME,
  120. desktop->settings.favorite_primary.name_or_path);
  121. if(status != LoaderStatusOk) {
  122. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  123. }
  124. } else {
  125. LoaderStatus status = loader_start(
  126. desktop->loader, desktop->settings.favorite_primary.name_or_path, NULL);
  127. if(status != LoaderStatusOk) {
  128. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  129. }
  130. }
  131. consumed = true;
  132. break;
  133. case DesktopMainEventOpenFavoriteSecondary:
  134. DESKTOP_SETTINGS_LOAD(&desktop->settings);
  135. if(desktop->settings.favorite_secondary.is_external) {
  136. LoaderStatus status = loader_start(
  137. desktop->loader,
  138. FAP_LOADER_APP_NAME,
  139. desktop->settings.favorite_secondary.name_or_path);
  140. if(status != LoaderStatusOk) {
  141. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  142. }
  143. } else {
  144. LoaderStatus status = loader_start(
  145. desktop->loader, desktop->settings.favorite_secondary.name_or_path, NULL);
  146. if(status != LoaderStatusOk) {
  147. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  148. }
  149. }
  150. consumed = true;
  151. break;
  152. case DesktopAnimationEventCheckAnimation:
  153. animation_manager_check_blocking_process(desktop->animation_manager);
  154. consumed = true;
  155. break;
  156. case DesktopAnimationEventNewIdleAnimation:
  157. animation_manager_new_idle_process(desktop->animation_manager);
  158. consumed = true;
  159. break;
  160. case DesktopAnimationEventInteractAnimation:
  161. if(!animation_manager_interact_process(desktop->animation_manager)) {
  162. LoaderStatus status = loader_start(desktop->loader, "Passport", NULL);
  163. if(status != LoaderStatusOk) {
  164. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  165. }
  166. }
  167. consumed = true;
  168. break;
  169. case DesktopMainEventOpenPassport: {
  170. LoaderStatus status = loader_start(desktop->loader, "Passport", NULL);
  171. if(status != LoaderStatusOk) {
  172. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  173. }
  174. break;
  175. }
  176. case DesktopMainEventOpenGame: {
  177. desktop_scene_main_open_app_or_profile(desktop, SNAKE_GAME_APP);
  178. break;
  179. }
  180. case DesktopMainEventOpenClock: {
  181. desktop_scene_main_open_app_or_profile(desktop, CLOCK_APP);
  182. break;
  183. }
  184. case DesktopMainEventOpenMusicPlayer: {
  185. desktop_scene_main_open_app_or_profile(desktop, MUSIC_PLAYER_APP);
  186. break;
  187. }
  188. case DesktopLockedEventUpdate:
  189. desktop_view_locked_update(desktop->locked_view);
  190. consumed = true;
  191. break;
  192. default:
  193. break;
  194. }
  195. }
  196. return consumed;
  197. }
  198. void desktop_scene_main_on_exit(void* context) {
  199. Desktop* desktop = (Desktop*)context;
  200. animation_manager_set_new_idle_callback(desktop->animation_manager, NULL);
  201. animation_manager_set_check_callback(desktop->animation_manager, NULL);
  202. animation_manager_set_interact_callback(desktop->animation_manager, NULL);
  203. animation_manager_set_context(desktop->animation_manager, desktop);
  204. }