Skip to content
This repository was archived by the owner on Nov 19, 2024. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
…irmware into xfw-dev
  • Loading branch information
Willy-JL committed Feb 12, 2024
2 parents c99bb46 + c8e62ba commit 4027db5
Show file tree
Hide file tree
Showing 119 changed files with 17,570 additions and 36 deletions.
2 changes: 1 addition & 1 deletion .pvsoptions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/cmsis_core -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/microtar -e lib/mlib -e lib/stm32wb_cmsis -e lib/stm32wb_copro -e lib/stm32wb_hal -e lib/u8g2 -e lib/nanopb -e */arm-none-eabi/*
--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/cmsis_core -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/microtar -e lib/mlib -e lib/stm32wb_cmsis -e lib/stm32wb_copro -e lib/stm32wb_hal -e lib/u8g2 -e lib/nanopb -e lib/mjs -e */arm-none-eabi/*
5 changes: 4 additions & 1 deletion applications/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ Small applications providing configuration for basic firmware and its services.

## system

Utility apps not visible in other menus.
Utility apps not visible in other menus, plus few external apps pre-packaged with the firmware.

- `hid_app` - BLE & USB HID remote
- `js_app` - JS engine runner
- `snake_game` - Snake game
- `storage_move_to_sd` - Data migration tool for internal storage
- `updater` - Update service & application
1 change: 1 addition & 0 deletions applications/main/archive/helpers/archive_browser.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ static const char* known_ext[] = {
[ArchiveFileTypeBadKb] = ".txt",
[ArchiveFileTypeU2f] = "?",
[ArchiveFileTypeApplication] = ".fap",
[ArchiveFileTypeJS] = ".js",
[ArchiveFileTypeSearch] = "*",
[ArchiveFileTypeUpdateManifest] = ".fuf",
[ArchiveFileTypeFolder] = "?",
Expand Down
1 change: 1 addition & 0 deletions applications/main/archive/helpers/archive_files.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ typedef enum {
ArchiveFileTypeBadKb,
ArchiveFileTypeU2f,
ArchiveFileTypeApplication,
ArchiveFileTypeJS,
ArchiveFileTypeSearch,
ArchiveFileTypeUpdateManifest,
ArchiveFileTypeFolder,
Expand Down
2 changes: 2 additions & 0 deletions applications/main/archive/scenes/archive_scene_browser.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const char* archive_get_flipper_app_name(ArchiveFileTypeEnum file_type) {
return "U2F";
case ArchiveFileTypeUpdateManifest:
return "UpdaterApp";
case ArchiveFileTypeJS:
return "JS Runner";
default:
return NULL;
}
Expand Down
1 change: 1 addition & 0 deletions applications/main/archive/views/archive_browser_view.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ static const Icon* ArchiveItemIcons[] = {
[ArchiveFileTypeBadKb] = &I_badkb_10px,
[ArchiveFileTypeU2f] = &I_u2f_10px,
[ArchiveFileTypeApplication] = &I_Apps_10px,
[ArchiveFileTypeJS] = &I_js_script_10px,
[ArchiveFileTypeSearch] = &I_search_10px,
[ArchiveFileTypeUpdateManifest] = &I_update_10px,
[ArchiveFileTypeFolder] = &I_dir_10px,
Expand Down
68 changes: 54 additions & 14 deletions applications/services/gui/modules/file_browser_worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ typedef enum {
(WorkerEvtStop | WorkerEvtLoad | WorkerEvtFolderEnter | WorkerEvtFolderExit | \
WorkerEvtFolderRefresh | WorkerEvtConfigChange)

ARRAY_DEF(_idx_last_array, int32_t) // Unused, kept for compatibility
ARRAY_DEF(_IdxLastArray, int32_t) // Unused, kept for compatibility
ARRAY_DEF(ExtFilterArray, FuriString*, FURI_STRING_OPLIST)

struct BrowserWorker {
FuriThread* thread;

FuriString* filter_extension;
FuriString* path_start;
FuriString* path_current;
FuriString* path_next;
Expand All @@ -46,7 +46,8 @@ struct BrowserWorker {
uint32_t load_count;
bool skip_assets;
bool hide_dot_files;
_idx_last_array_t _idx_last; // Unused, kept for compatibility
_IdxLastArray_t _idx_last; // Unused, kept for compatibility
ExtFilterArray_t ext_filter;

void* cb_ctx;
BrowserWorkerFolderOpenCallback folder_cb;
Expand All @@ -55,6 +56,7 @@ struct BrowserWorker {
BrowserWorkerLongLoadCallback long_load_cb;

bool keep_selection;
FuriString* passed_ext_filter;
};

static bool browser_path_is_file(FuriString* path) {
Expand All @@ -80,6 +82,31 @@ static bool browser_path_trim(FuriString* path) {
}
return is_root;
}
static void browser_parse_ext_filter(ExtFilterArray_t ext_filter, const char* filter_str) {
if(!filter_str) {
return;
}

size_t len = strlen(filter_str);
if(len == 0) {
return;
}

size_t str_offset = 0;
FuriString* ext_temp = furi_string_alloc();
while(1) {
size_t ext_len = strcspn(&filter_str[str_offset], "|");

furi_string_set_strn(ext_temp, &filter_str[str_offset], ext_len);
ExtFilterArray_push_back(ext_filter, ext_temp);

str_offset += ext_len + 1;
if(str_offset >= len) {
break;
}
}
furi_string_free(ext_temp);
}

static bool browser_filter_by_name(BrowserWorker* browser, FuriString* name, bool is_folder) {
// Skip dot files if enabled
Expand All @@ -98,12 +125,20 @@ static bool browser_filter_by_name(BrowserWorker* browser, FuriString* name, boo
}
} else {
// Filter files by extension
if((furi_string_empty(browser->filter_extension)) ||
(furi_string_cmp_str(browser->filter_extension, "*") == 0)) {
if(ExtFilterArray_size(browser->ext_filter) == 0) {
return true;
}
if(furi_string_end_with(name, browser->filter_extension)) {
return true;

ExtFilterArray_it_t it;
for(ExtFilterArray_it(it, browser->ext_filter); !ExtFilterArray_end_p(it);
ExtFilterArray_next(it)) {
FuriString* ext = *ExtFilterArray_cref(it);
if((furi_string_empty(ext)) || (furi_string_cmp_str(ext, "*") == 0)) {
return true;
}
if(furi_string_end_with(name, ext)) {
return true;
}
}
}
return false;
Expand Down Expand Up @@ -460,14 +495,17 @@ static int32_t browser_worker(void* context) {
BrowserWorker* file_browser_worker_alloc(
FuriString* path,
const char* base_path,
const char* filter_ext,
const char* ext_filter,
bool skip_assets,
bool hide_dot_files) {
BrowserWorker* browser = malloc(sizeof(BrowserWorker));

browser->filter_extension = furi_string_alloc_set(filter_ext);
ExtFilterArray_init(browser->ext_filter);

browser_parse_ext_filter(browser->ext_filter, ext_filter);
browser->skip_assets = skip_assets;
browser->hide_dot_files = hide_dot_files;
browser->passed_ext_filter = furi_string_alloc_set(ext_filter);

browser->path_current = furi_string_alloc_set(path);
browser->path_next = furi_string_alloc_set(path);
Expand All @@ -490,10 +528,12 @@ void file_browser_worker_free(BrowserWorker* browser) {
furi_thread_join(browser->thread);
furi_thread_free(browser->thread);

furi_string_free(browser->filter_extension);
furi_string_free(browser->path_next);
furi_string_free(browser->path_current);
furi_string_free(browser->path_start);
furi_string_free(browser->passed_ext_filter);

ExtFilterArray_clear(browser->ext_filter);

free(browser);
}
Expand Down Expand Up @@ -534,21 +574,21 @@ void file_browser_worker_set_long_load_callback(
void file_browser_worker_set_config(
BrowserWorker* browser,
FuriString* path,
const char* filter_ext,
const char* ext_filter,
bool skip_assets,
bool hide_dot_files) {
furi_assert(browser);
furi_string_set(browser->path_next, path);
browser->keep_selection = false;
furi_string_set(browser->filter_extension, filter_ext);
browser_parse_ext_filter(browser->ext_filter, ext_filter);
browser->skip_assets = skip_assets;
browser->hide_dot_files = hide_dot_files;
furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtConfigChange);
}

const char* file_browser_worker_get_filter_ext(BrowserWorker* browser) {
furi_assert(browser);
return furi_string_get_cstr(browser->filter_extension);
return furi_string_get_cstr(browser->passed_ext_filter);
}

void file_browser_worker_set_filter_ext(
Expand All @@ -558,7 +598,7 @@ void file_browser_worker_set_filter_ext(
furi_assert(browser);
furi_string_set(browser->path_next, path);
browser->keep_selection = true;
furi_string_set(browser->filter_extension, filter_ext);
furi_string_set(browser->passed_ext_filter, filter_ext);
furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtConfigChange);
}

Expand Down
4 changes: 2 additions & 2 deletions applications/services/gui/modules/file_browser_worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ typedef void (*BrowserWorkerLongLoadCallback)(void* context);
BrowserWorker* file_browser_worker_alloc(
FuriString* path,
const char* base_path,
const char* filter_ext,
const char* ext_filter,
bool skip_assets,
bool hide_dot_files);

Expand All @@ -53,7 +53,7 @@ void file_browser_worker_set_long_load_callback(
void file_browser_worker_set_config(
BrowserWorker* browser,
FuriString* path,
const char* filter_ext,
const char* ext_filter,
bool skip_assets,
bool hide_dot_files);

Expand Down
43 changes: 28 additions & 15 deletions applications/services/loader/loader_applications.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
#include <gui/view_holder.h>
#include <gui/modules/loading.h>
#include <dolphin/dolphin.h>
#include <lib/toolbox/path.h>

#define TAG "LoaderApplications"

#define JS_RUNNER_APP "JS Runner"

struct LoaderApplications {
FuriThread* thread;
void (*closed_cb)(void*);
Expand All @@ -36,7 +39,7 @@ void loader_applications_free(LoaderApplications* loader_applications) {
}

typedef struct {
FuriString* fap_path;
FuriString* file_path;
DialogsApp* dialogs;
Storage* storage;
Loader* loader;
Expand All @@ -48,7 +51,7 @@ typedef struct {

static LoaderApplicationsApp* loader_applications_app_alloc() {
LoaderApplicationsApp* app = malloc(sizeof(LoaderApplicationsApp)); //-V799
app->fap_path = furi_string_alloc_set(EXT_PATH("apps"));
app->file_path = furi_string_alloc_set(EXT_PATH("apps"));
app->dialogs = furi_record_open(RECORD_DIALOGS);
app->storage = furi_record_open(RECORD_STORAGE);
app->loader = furi_record_open(RECORD_LOADER);
Expand All @@ -73,7 +76,7 @@ static void loader_applications_app_free(LoaderApplicationsApp* app) {
furi_record_close(RECORD_LOADER);
furi_record_close(RECORD_DIALOGS);
furi_record_close(RECORD_STORAGE);
furi_string_free(app->fap_path);
furi_string_free(app->file_path);
free(app);
}

Expand All @@ -84,13 +87,19 @@ static bool loader_applications_item_callback(
FuriString* item_name) {
LoaderApplicationsApp* loader_applications_app = context;
furi_assert(loader_applications_app);
return flipper_application_load_name_and_icon(
path, loader_applications_app->storage, icon_ptr, item_name);
if(furi_string_end_with(path, ".fap")) {
return flipper_application_load_name_and_icon(
path, loader_applications_app->storage, icon_ptr, item_name);
} else {
path_extract_filename(path, item_name, false);
memcpy(*icon_ptr, icon_get_data(&I_js_script_10px), FAP_MANIFEST_MAX_ICON_SIZE);
return true;
}
}

static bool loader_applications_select_app(LoaderApplicationsApp* loader_applications_app) {
const DialogsFileBrowserOptions browser_options = {
.extension = ".fap",
.extension = ".fap|.js",
.skip_assets = true,
.icon = &I_unknown_10px,
.hide_ext = true,
Expand All @@ -101,8 +110,8 @@ static bool loader_applications_select_app(LoaderApplicationsApp* loader_applica

return dialog_file_browser_show(
loader_applications_app->dialogs,
loader_applications_app->fap_path,
loader_applications_app->fap_path,
loader_applications_app->file_path,
loader_applications_app->file_path,
&browser_options);
}

Expand All @@ -117,11 +126,10 @@ static void loader_pubsub_callback(const void* message, void* context) {
}
}

static void loader_applications_start_app(LoaderApplicationsApp* app) {
const char* name = furi_string_get_cstr(app->fap_path);

if(!furi_string_start_with_str(app->fap_path, EXT_PATH("apps/Games/")) &&
!furi_string_start_with_str(app->fap_path, EXT_PATH("apps/Media/"))) {
static void
loader_applications_start_app(LoaderApplicationsApp* app, const char* name, const char* args) {
if(!furi_string_start_with_str(app->file_path, EXT_PATH("apps/Games/")) &&
!furi_string_start_with_str(app->file_path, EXT_PATH("apps/Media/"))) {
dolphin_deed(DolphinDeedPluginInternalStart);
}

Expand All @@ -130,7 +138,7 @@ static void loader_applications_start_app(LoaderApplicationsApp* app) {
FuriPubSubSubscription* subscription =
furi_pubsub_subscribe(loader_get_pubsub(app->loader), loader_pubsub_callback, thread_id);

LoaderStatus status = loader_start_with_gui_error(app->loader, name, NULL);
LoaderStatus status = loader_start_with_gui_error(app->loader, name, args);

if(status == LoaderStatusOk) {
furi_thread_flags_wait(APPLICATION_STOP_EVENT, FuriFlagWaitAny, FuriWaitForever);
Expand All @@ -147,7 +155,12 @@ static int32_t loader_applications_thread(void* p) {
view_holder_start(app->view_holder);

while(loader_applications_select_app(app)) {
loader_applications_start_app(app);
if(!furi_string_end_with(app->file_path, ".js")) {
loader_applications_start_app(app, furi_string_get_cstr(app->file_path), NULL);
} else {
loader_applications_start_app(
app, JS_RUNNER_APP, furi_string_get_cstr(app->file_path));
}
}

// stop loading animation
Expand Down
1 change: 1 addition & 0 deletions applications/system/application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ App(
provides=[
"updater_app",
"storage_move_to_sd",
"js_app",
# "archive",
],
)
41 changes: 41 additions & 0 deletions applications/system/js_app/application.fam
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
App(
appid="js_app",
name="JS Runner",
apptype=FlipperAppType.SYSTEM,
entry_point="js_app",
stack_size=2 * 1024,
resources="examples",
order=0,
)

App(
appid="js_dialog",
apptype=FlipperAppType.PLUGIN,
entry_point="js_dialog_ep",
requires=["js_app"],
sources=["modules/js_dialog.c"],
)

App(
appid="js_notification",
apptype=FlipperAppType.PLUGIN,
entry_point="js_notification_ep",
requires=["js_app"],
sources=["modules/js_notification.c"],
)

App(
appid="js_badusb",
apptype=FlipperAppType.PLUGIN,
entry_point="js_badusb_ep",
requires=["js_app"],
sources=["modules/js_badusb.c"],
)

App(
appid="js_uart",
apptype=FlipperAppType.PLUGIN,
entry_point="js_uart_ep",
requires=["js_app"],
sources=["modules/js_uart.c"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
let arr_1 = Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
print("len =", arr_1.buffer.byteLength);

let arr_2 = Uint8Array(arr_1.buffer.slice(2, 6));
print("slice len =", arr_2.buffer.byteLength);
for (let i = 0; i < arr_2.buffer.byteLength; i++) {
print(arr_2[i]);
}
Loading

0 comments on commit 4027db5

Please sign in to comment.