[FL-2627] Flipper applications: SDK, build and debug system (#1387)

* Added support for running applications from SD card (FAPs - Flipper Application Packages)
* Added plugin_dist target for fbt to build FAPs
* All apps of type FlipperAppType.EXTERNAL and FlipperAppType.PLUGIN are built as FAPs by default
* Updated VSCode configuration for new fbt features - re-deploy stock configuration to use them
* Added debugging support for FAPs with fbt debug & VSCode
* Added public firmware API with automated versioning

Co-authored-by: hedger <hedger@users.noreply.github.com>
Co-authored-by: SG <who.just.the.doctor@gmail.com>
Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
SG
2022-09-15 02:11:38 +10:00
committed by Aleksandr Kutuzov
parent 0f6f9ad52e
commit b9a766d909
895 changed files with 8862 additions and 1465 deletions

View File

@@ -0,0 +1,30 @@
#include "bt_settings_scene.h"
// Generate scene on_enter handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
void (*const bt_settings_on_enter_handlers[])(void*) = {
#include "bt_settings_scene_config.h"
};
#undef ADD_SCENE
// Generate scene on_event handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
bool (*const bt_settings_on_event_handlers[])(void* context, SceneManagerEvent event) = {
#include "bt_settings_scene_config.h"
};
#undef ADD_SCENE
// Generate scene on_exit handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
void (*const bt_settings_on_exit_handlers[])(void* context) = {
#include "bt_settings_scene_config.h"
};
#undef ADD_SCENE
// Initialize scene handlers configuration structure
const SceneManagerHandlers bt_settings_scene_handlers = {
.on_enter_handlers = bt_settings_on_enter_handlers,
.on_event_handlers = bt_settings_on_event_handlers,
.on_exit_handlers = bt_settings_on_exit_handlers,
.scene_num = BtSettingsAppSceneNum,
};

View File

@@ -0,0 +1,29 @@
#pragma once
#include <gui/scene_manager.h>
// Generate scene id and total number
#define ADD_SCENE(prefix, name, id) BtSettingsAppScene##id,
typedef enum {
#include "bt_settings_scene_config.h"
BtSettingsAppSceneNum,
} BtSettingsAppScene;
#undef ADD_SCENE
extern const SceneManagerHandlers bt_settings_scene_handlers;
// Generate scene on_enter handlers declaration
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
#include "bt_settings_scene_config.h"
#undef ADD_SCENE
// Generate scene on_event handlers declaration
#define ADD_SCENE(prefix, name, id) \
bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
#include "bt_settings_scene_config.h"
#undef ADD_SCENE
// Generate scene on_exit handlers declaration
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
#include "bt_settings_scene_config.h"
#undef ADD_SCENE

View File

@@ -0,0 +1,3 @@
ADD_SCENE(bt_settings, start, Start)
ADD_SCENE(bt_settings, forget_dev_confirm, ForgetDevConfirm)
ADD_SCENE(bt_settings, forget_dev_success, ForgetDevSuccess)

View File

@@ -0,0 +1,44 @@
#include "../bt_settings_app.h"
#include "furi_hal_bt.h"
void bt_settings_scene_forget_dev_confirm_dialog_callback(DialogExResult result, void* context) {
furi_assert(context);
BtSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, result);
}
void bt_settings_scene_forget_dev_confirm_on_enter(void* context) {
BtSettingsApp* app = context;
DialogEx* dialog = app->dialog;
dialog_ex_set_header(dialog, "Unpair All Devices?", 64, 3, AlignCenter, AlignTop);
dialog_ex_set_text(
dialog, "All previous pairings\nwill be lost!", 64, 22, AlignCenter, AlignTop);
dialog_ex_set_left_button_text(dialog, "Back");
dialog_ex_set_right_button_text(dialog, "Unpair");
dialog_ex_set_context(dialog, app);
dialog_ex_set_result_callback(dialog, bt_settings_scene_forget_dev_confirm_dialog_callback);
view_dispatcher_switch_to_view(app->view_dispatcher, BtSettingsAppViewDialog);
}
bool bt_settings_scene_forget_dev_confirm_on_event(void* context, SceneManagerEvent event) {
BtSettingsApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == DialogExResultLeft) {
consumed = scene_manager_previous_scene(app->scene_manager);
} else if(event.event == DialogExResultRight) {
bt_forget_bonded_devices(app->bt);
scene_manager_next_scene(app->scene_manager, BtSettingsAppSceneForgetDevSuccess);
consumed = true;
}
}
return consumed;
}
void bt_settings_scene_forget_dev_confirm_on_exit(void* context) {
BtSettingsApp* app = context;
dialog_ex_reset(app->dialog);
}

View File

@@ -0,0 +1,41 @@
#include "../bt_settings_app.h"
#include "furi_hal_bt.h"
void bt_settings_app_scene_forget_dev_success_popup_callback(void* context) {
BtSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, BtSettingsCustomEventExitView);
}
void bt_settings_scene_forget_dev_success_on_enter(void* context) {
BtSettingsApp* app = context;
Popup* popup = app->popup;
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
popup_set_header(popup, "Done", 14, 15, AlignLeft, AlignTop);
popup_set_timeout(popup, 1500);
popup_set_context(popup, app);
popup_set_callback(popup, bt_settings_app_scene_forget_dev_success_popup_callback);
popup_enable_timeout(popup);
view_dispatcher_switch_to_view(app->view_dispatcher, BtSettingsAppViewPopup);
}
bool bt_settings_scene_forget_dev_success_on_event(void* context, SceneManagerEvent event) {
BtSettingsApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == BtSettingsCustomEventExitView) {
if(scene_manager_has_previous_scene(app->scene_manager, BtSettingsAppSceneStart)) {
consumed = scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, BtSettingsAppSceneStart);
}
}
}
return consumed;
}
void bt_settings_scene_forget_dev_success_on_exit(void* context) {
BtSettingsApp* app = context;
popup_reset(app->popup);
}

View File

@@ -0,0 +1,91 @@
#include "../bt_settings_app.h"
#include "furi_hal_bt.h"
enum BtSetting {
BtSettingOff,
BtSettingOn,
BtSettingNum,
};
enum BtSettingIndex {
BtSettingIndexSwitchBt,
BtSettingIndexForgetDev,
};
const char* const bt_settings_text[BtSettingNum] = {
"OFF",
"ON",
};
static void bt_settings_scene_start_var_list_change_callback(VariableItem* item) {
BtSettingsApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, bt_settings_text[index]);
view_dispatcher_send_custom_event(app->view_dispatcher, index);
}
static void bt_settings_scene_start_var_list_enter_callback(void* context, uint32_t index) {
furi_assert(context);
BtSettingsApp* app = context;
if(index == BtSettingIndexForgetDev) {
view_dispatcher_send_custom_event(
app->view_dispatcher, BtSettingsCustomEventForgetDevices);
}
}
void bt_settings_scene_start_on_enter(void* context) {
BtSettingsApp* app = context;
VariableItemList* var_item_list = app->var_item_list;
VariableItem* item;
if(furi_hal_bt_is_ble_gatt_gap_supported()) {
item = variable_item_list_add(
var_item_list,
"Bluetooth",
BtSettingNum,
bt_settings_scene_start_var_list_change_callback,
app);
if(app->settings.enabled) {
variable_item_set_current_value_index(item, BtSettingOn);
variable_item_set_current_value_text(item, bt_settings_text[BtSettingOn]);
} else {
variable_item_set_current_value_index(item, BtSettingOff);
variable_item_set_current_value_text(item, bt_settings_text[BtSettingOff]);
}
variable_item_list_add(var_item_list, "Forget All Paired Devices", 1, NULL, NULL);
variable_item_list_set_enter_callback(
var_item_list, bt_settings_scene_start_var_list_enter_callback, app);
} else {
item = variable_item_list_add(var_item_list, "Bluetooth", 1, NULL, NULL);
variable_item_set_current_value_text(item, "Broken");
}
view_dispatcher_switch_to_view(app->view_dispatcher, BtSettingsAppViewVarItemList);
}
bool bt_settings_scene_start_on_event(void* context, SceneManagerEvent event) {
BtSettingsApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == BtSettingOn) {
furi_hal_bt_start_advertising();
app->settings.enabled = true;
consumed = true;
} else if(event.event == BtSettingOff) {
app->settings.enabled = false;
furi_hal_bt_stop_advertising();
consumed = true;
} else if(event.event == BtSettingsCustomEventForgetDevices) {
scene_manager_next_scene(app->scene_manager, BtSettingsAppSceneForgetDevConfirm);
consumed = true;
}
}
return consumed;
}
void bt_settings_scene_start_on_exit(void* context) {
BtSettingsApp* app = context;
variable_item_list_reset(app->var_item_list);
}