desktop_scene_main.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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/Media/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. if(desktop->in_transition) return;
  69. view_dispatcher_send_custom_event(desktop->view_dispatcher, event);
  70. }
  71. void desktop_scene_main_on_enter(void* context) {
  72. Desktop* desktop = (Desktop*)context;
  73. DesktopMainView* main_view = desktop->main_view;
  74. animation_manager_set_context(desktop->animation_manager, desktop);
  75. animation_manager_set_new_idle_callback(
  76. desktop->animation_manager, desktop_scene_main_new_idle_animation_callback);
  77. animation_manager_set_check_callback(
  78. desktop->animation_manager, desktop_scene_main_check_animation_callback);
  79. animation_manager_set_interact_callback(
  80. desktop->animation_manager, desktop_scene_main_interact_animation_callback);
  81. desktop_main_set_callback(main_view, desktop_scene_main_callback, desktop);
  82. view_dispatcher_switch_to_view(desktop->view_dispatcher, DesktopViewIdMain);
  83. }
  84. bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) {
  85. Desktop* desktop = (Desktop*)context;
  86. bool consumed = false;
  87. if(event.type == SceneManagerEventTypeCustom) {
  88. switch(event.event) {
  89. case DesktopMainEventOpenMenu:
  90. loader_show_menu();
  91. consumed = true;
  92. break;
  93. case DesktopMainEventOpenLockMenu:
  94. scene_manager_next_scene(desktop->scene_manager, DesktopSceneLockMenu);
  95. consumed = true;
  96. break;
  97. case DesktopMainEventOpenDebug:
  98. scene_manager_next_scene(desktop->scene_manager, DesktopSceneDebug);
  99. consumed = true;
  100. break;
  101. case DesktopMainEventOpenArchive:
  102. #ifdef APP_ARCHIVE
  103. desktop_switch_to_app(desktop, &FLIPPER_ARCHIVE);
  104. #endif
  105. consumed = true;
  106. break;
  107. case DesktopMainEventOpenPowerOff: {
  108. LoaderStatus status = loader_start(desktop->loader, "Power", "off");
  109. if(status != LoaderStatusOk) {
  110. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  111. }
  112. consumed = true;
  113. break;
  114. }
  115. case DesktopMainEventOpenFavoritePrimary:
  116. DESKTOP_SETTINGS_LOAD(&desktop->settings);
  117. if(desktop->settings.favorite_primary.is_external) {
  118. LoaderStatus status = loader_start(
  119. desktop->loader,
  120. FAP_LOADER_APP_NAME,
  121. desktop->settings.favorite_primary.name_or_path);
  122. if(status != LoaderStatusOk) {
  123. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  124. }
  125. } else {
  126. LoaderStatus status = loader_start(
  127. desktop->loader, desktop->settings.favorite_primary.name_or_path, NULL);
  128. if(status != LoaderStatusOk) {
  129. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  130. }
  131. }
  132. consumed = true;
  133. break;
  134. case DesktopMainEventOpenFavoriteSecondary:
  135. DESKTOP_SETTINGS_LOAD(&desktop->settings);
  136. if(desktop->settings.favorite_secondary.is_external) {
  137. LoaderStatus status = loader_start(
  138. desktop->loader,
  139. FAP_LOADER_APP_NAME,
  140. desktop->settings.favorite_secondary.name_or_path);
  141. if(status != LoaderStatusOk) {
  142. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  143. }
  144. } else {
  145. LoaderStatus status = loader_start(
  146. desktop->loader, desktop->settings.favorite_secondary.name_or_path, NULL);
  147. if(status != LoaderStatusOk) {
  148. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  149. }
  150. }
  151. consumed = true;
  152. break;
  153. case DesktopAnimationEventCheckAnimation:
  154. animation_manager_check_blocking_process(desktop->animation_manager);
  155. consumed = true;
  156. break;
  157. case DesktopAnimationEventNewIdleAnimation:
  158. animation_manager_new_idle_process(desktop->animation_manager);
  159. consumed = true;
  160. break;
  161. case DesktopAnimationEventInteractAnimation:
  162. if(!animation_manager_interact_process(desktop->animation_manager)) {
  163. LoaderStatus status = loader_start(desktop->loader, "Passport", NULL);
  164. if(status != LoaderStatusOk) {
  165. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  166. }
  167. }
  168. consumed = true;
  169. break;
  170. case DesktopMainEventOpenPassport: {
  171. LoaderStatus status = loader_start(desktop->loader, "Passport", NULL);
  172. if(status != LoaderStatusOk) {
  173. FURI_LOG_E(TAG, "loader_start failed: %d", status);
  174. }
  175. break;
  176. }
  177. case DesktopMainEventOpenGame: {
  178. desktop_scene_main_open_app_or_profile(desktop, SNAKE_GAME_APP);
  179. break;
  180. }
  181. case DesktopMainEventOpenClock: {
  182. desktop_scene_main_open_app_or_profile(desktop, CLOCK_APP);
  183. break;
  184. }
  185. case DesktopMainEventOpenMusicPlayer: {
  186. desktop_scene_main_open_app_or_profile(desktop, MUSIC_PLAYER_APP);
  187. break;
  188. }
  189. case DesktopLockedEventUpdate:
  190. desktop_view_locked_update(desktop->locked_view);
  191. consumed = true;
  192. break;
  193. default:
  194. break;
  195. }
  196. }
  197. return consumed;
  198. }
  199. void desktop_scene_main_on_exit(void* context) {
  200. Desktop* desktop = (Desktop*)context;
  201. animation_manager_set_new_idle_callback(desktop->animation_manager, NULL);
  202. animation_manager_set_check_callback(desktop->animation_manager, NULL);
  203. animation_manager_set_interact_callback(desktop->animation_manager, NULL);
  204. animation_manager_set_context(desktop->animation_manager, desktop);
  205. }