From d5f12fe1bb6455ba33f7d621e3cc1631a24d1ad7 Mon Sep 17 00:00:00 2001 From: dianjixz <18637716021@163.com> Date: Thu, 20 Aug 2026 13:32:21 +0800 Subject: [PATCH 1/2] feat: integrate FactoryTest display mode build --- projects/FactoryTest/SConstruct | 22 ++++++++++++++++++++-- projects/FactoryTest/main_FactoryTest | 2 +- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/projects/FactoryTest/SConstruct b/projects/FactoryTest/SConstruct index 685496a3..7ffeef2d 100644 --- a/projects/FactoryTest/SConstruct +++ b/projects/FactoryTest/SConstruct @@ -31,12 +31,18 @@ if os.environ.get("CONFIG_DEFAULT_FILE") == None: config_dir = Path("build") / "config" config_stamp_path = config_dir / "config_default_file" selected_config = os.environ.get("CONFIG_DEFAULT_FILE", "config_defaults.mk") +product_mode_enabled = os.environ.get("FACTORY_TEST_PRODUCT_MODE", "").lower() in ( + "1", "y", "yes", "true" +) +selected_config_stamp = "{}\nFACTORY_TEST_PRODUCT_MODE={}".format( + selected_config, int(product_mode_enabled) +) previous_config = ( config_stamp_path.read_text(encoding="utf-8").strip() if config_stamp_path.exists() else None ) -if previous_config != selected_config: +if previous_config != selected_config_stamp: for generated_config in ( "global_config.mk", "global_config.h", @@ -46,14 +52,25 @@ if previous_config != selected_config: if generated_config_path.exists(): generated_config_path.unlink() config_dir.mkdir(parents=True, exist_ok=True) - config_stamp_path.write_text(selected_config + "\n", encoding="utf-8") + config_stamp_path.write_text(selected_config_stamp + "\n", encoding="utf-8") if "cross" in os.environ.get("CONFIG_DEFAULT_FILE", ''): cross_package_enabled = True config_tmp_path = config_dir / "config_tmp.mk" sysroot_path_str = static_lib_path.as_posix().replace('"', r'\"') + display_mode_config = ( + "CONFIG_FACTORY_TEST_PRODUCT_MODE=y\n" + "CONFIG_V9_5_LV_USE_LINUX_DRM=y\n" + "# CONFIG_V9_5_LV_USE_LINUX_FBDEV is not set\n" + if product_mode_enabled + else + "# CONFIG_FACTORY_TEST_PRODUCT_MODE is not set\n" + "# CONFIG_V9_5_LV_USE_LINUX_DRM is not set\n" + "CONFIG_V9_5_LV_USE_LINUX_FBDEV=y\n" + ) config_tmp_content = ( f'CONFIG_TOOLCHAIN_SYSROOT="{sysroot_path_str}"\n' + + display_mode_config ) if not config_tmp_path.exists() or config_tmp_path.read_text() != config_tmp_content: config_tmp_path.parent.mkdir(parents=True, exist_ok=True) @@ -65,6 +82,7 @@ else: os.environ["SDK_PATH"] = str(sdk_path) os.environ["EXT_COMPONENTS_PATH"] = str(sdk_path.parent / "ext_components") +os.environ["CONFIG_CJSON_ENABLED"] = "y" env = SConscript( str(sdk_path / "tools" / "scons" / "project.py"), diff --git a/projects/FactoryTest/main_FactoryTest b/projects/FactoryTest/main_FactoryTest index 9c6803e9..14ced93f 160000 --- a/projects/FactoryTest/main_FactoryTest +++ b/projects/FactoryTest/main_FactoryTest @@ -1 +1 @@ -Subproject commit 9c6803e9800bf316c7375b3834a64b01b0102fcf +Subproject commit 14ced93fa76d146986934e5859d00a6ff72f8b30 From cde19bbac8a26609a1e2903140cff398c070fa76 Mon Sep 17 00:00:00 2001 From: dianjixz <18637716021@163.com> Date: Thu, 20 Aug 2026 13:35:18 +0800 Subject: [PATCH 2/2] chore: commit remaining workspace changes --- projects/LaunchWizard/main/src/main.cpp | 6 ++--- projects/LaunchWizard/main/ui/application.h | 6 ++--- .../main/ui/first_boot_policy.cpp | 5 ---- .../LaunchWizard/main/ui/first_boot_policy.h | 5 ---- .../LaunchWizard/main/ui/wizard_service.cpp | 24 ++----------------- .../LaunchWizard/main/ui/wizard_service.h | 6 ++--- projects/LaunchWizard/main/ui/wizard_view.cpp | 4 ++-- projects/LaunchWizard/main_Keyboard_Guide | 2 +- .../tests/test_first_boot_policy.cpp | 7 ------ 9 files changed, 14 insertions(+), 51 deletions(-) diff --git a/projects/LaunchWizard/main/src/main.cpp b/projects/LaunchWizard/main/src/main.cpp index 4637fc45..3c4513c0 100644 --- a/projects/LaunchWizard/main/src/main.cpp +++ b/projects/LaunchWizard/main/src/main.cpp @@ -33,10 +33,10 @@ int main(int argc, char *argv[]) if (force) printf("LaunchWizard: test mode, bypassing first-boot detection\n"); - // The keyboard tutorial runs first and exactly once per device, whether - // the OOBE that follows is shown or skipped (Imager-provisioned devices). + // The keyboard tutorial always runs first on a normal (non-test) launch, + // whether the OOBE that follows is shown or skipped. if (!force) - launch_wizard_run_keyboard_guide_once(); + launch_wizard_run_keyboard_guide(); if (!force && !launch_wizard_should_run()) { printf("LaunchWizard: first-boot desktop is not active, starting APPLaunch\n"); diff --git a/projects/LaunchWizard/main/ui/application.h b/projects/LaunchWizard/main/ui/application.h index 79311aeb..a5aee3ea 100644 --- a/projects/LaunchWizard/main/ui/application.h +++ b/projects/LaunchWizard/main/ui/application.h @@ -13,8 +13,8 @@ void launch_wizard_ui_teardown(void); bool launch_wizard_should_run(void); int launch_wizard_finish_configured_system(void); -// Shows the one-shot keyboard tutorial before the OOBE decision. Runs exactly -// once per device (marker baked by pi-gen), whether or not the wizard follows. -void launch_wizard_run_keyboard_guide_once(void); +// Shows the keyboard tutorial before the OOBE decision on every non-test +// launch. +void launch_wizard_run_keyboard_guide(void); #endif // LAUNCH_WIZARD_APPLICATION_H diff --git a/projects/LaunchWizard/main/ui/first_boot_policy.cpp b/projects/LaunchWizard/main/ui/first_boot_policy.cpp index ba4ba6eb..5020112b 100644 --- a/projects/LaunchWizard/main/ui/first_boot_policy.cpp +++ b/projects/LaunchWizard/main/ui/first_boot_policy.cpp @@ -12,9 +12,4 @@ bool should_run_wizard(const FirstBootState &state) return state.legacy_piwiz_active; } -bool should_run_keyboard_guide(bool marker_present, bool binary_present) -{ - return marker_present && binary_present; -} - } // namespace launch_wizard diff --git a/projects/LaunchWizard/main/ui/first_boot_policy.h b/projects/LaunchWizard/main/ui/first_boot_policy.h index 17289534..087a89a8 100644 --- a/projects/LaunchWizard/main/ui/first_boot_policy.h +++ b/projects/LaunchWizard/main/ui/first_boot_policy.h @@ -33,11 +33,6 @@ struct FirstBootState { // Imager), so first boot skips straight to the launcher. bool should_run_wizard(const FirstBootState &state); -// The keyboard guide runs exactly once per device, before and independently of -// the OOBE wizard. A missing binary keeps the marker so a later boot (e.g. -// after the package lands) can still show the guide. -bool should_run_keyboard_guide(bool marker_present, bool binary_present); - } // namespace launch_wizard #endif // LAUNCH_WIZARD_FIRST_BOOT_POLICY_H diff --git a/projects/LaunchWizard/main/ui/wizard_service.cpp b/projects/LaunchWizard/main/ui/wizard_service.cpp index c41229b8..3818df32 100644 --- a/projects/LaunchWizard/main/ui/wizard_service.cpp +++ b/projects/LaunchWizard/main/ui/wizard_service.cpp @@ -67,9 +67,7 @@ constexpr const char *kAccountJournalPath = constexpr const char *kRearmOobeMarker = "/var/lib/applaunch/run-oobe"; // Baked into every factory image by pi-gen; removed once first boot finishes. constexpr const char *kFactoryOobeMarker = "/var/lib/LaunchWizard/run-oobe"; -// One-shot keyboard tutorial shown before the OOBE (also baked by pi-gen). -constexpr const char *kKeyboardGuideMarker = - "/var/lib/LaunchWizard/run-keyboard-guide"; +// Keyboard tutorial shown before the OOBE on every non-test launch. constexpr const char *kKeyboardGuideBinary = "/usr/share/APPLaunch/bin/M5CardputerZero-Keyboard-Guide"; @@ -1065,30 +1063,12 @@ bool launch_wizard::WizardService::should_run() #endif } -void launch_wizard::WizardService::run_keyboard_guide_once() +void launch_wizard::WizardService::run_keyboard_guide() { #if LAUNCH_WIZARD_DRY_RUN // The guide is a separate on-device binary; nothing to preview in SDL. return; #else - const bool marker_present = access(kKeyboardGuideMarker, F_OK) == 0; - const bool binary_present = access(kKeyboardGuideBinary, X_OK) == 0; - if (!should_run_keyboard_guide(marker_present, binary_present)) { - if (marker_present) - fprintf(stderr, - "LaunchWizard: keyboard guide binary missing; skipping guide\n"); - return; - } - - // Consume the marker *before* exec: if the guide ever hangs and the user - // power-cycles, the next boot must not be trapped in the guide again. - if (remove(kKeyboardGuideMarker) != 0 && errno != ENOENT) { - fprintf(stderr, "LaunchWizard: failed to remove keyboard guide marker: %s\n", - strerror(errno)); - return; // Without the consumed marker, re-running is worse than skipping. - } - sync(); - printf("LaunchWizard: starting keyboard guide\n"); fflush(stdout); diff --git a/projects/LaunchWizard/main/ui/wizard_service.h b/projects/LaunchWizard/main/ui/wizard_service.h index 813fbcda..16063b43 100644 --- a/projects/LaunchWizard/main/ui/wizard_service.h +++ b/projects/LaunchWizard/main/ui/wizard_service.h @@ -36,9 +36,9 @@ class WizardService { static std::string reboot(); static bool should_run(); static int finish_configured_system(); - // Runs the one-shot keyboard tutorial (before the OOBE decision) and - // consumes its marker. Returns once the guide exits or is unavailable. - static void run_keyboard_guide_once(); + // Runs the keyboard tutorial before the OOBE decision. Returns once the + // guide exits or fails to start. + static void run_keyboard_guide(); }; } // namespace launch_wizard diff --git a/projects/LaunchWizard/main/ui/wizard_view.cpp b/projects/LaunchWizard/main/ui/wizard_view.cpp index c2e16249..8c4b2884 100644 --- a/projects/LaunchWizard/main/ui/wizard_view.cpp +++ b/projects/LaunchWizard/main/ui/wizard_view.cpp @@ -1475,9 +1475,9 @@ int launch_wizard_finish_configured_system(void) return launch_wizard::WizardService::finish_configured_system(); } -void launch_wizard_run_keyboard_guide_once(void) +void launch_wizard_run_keyboard_guide(void) { - launch_wizard::WizardService::run_keyboard_guide_once(); + launch_wizard::WizardService::run_keyboard_guide(); } void launch_wizard_register_event(void) diff --git a/projects/LaunchWizard/main_Keyboard_Guide b/projects/LaunchWizard/main_Keyboard_Guide index 4719bed5..1d9a4483 160000 --- a/projects/LaunchWizard/main_Keyboard_Guide +++ b/projects/LaunchWizard/main_Keyboard_Guide @@ -1 +1 @@ -Subproject commit 4719bed547a3c0565e76d0353183cff9fc451cc0 +Subproject commit 1d9a448351e93c0545474612760e56f19fd831e9 diff --git a/projects/LaunchWizard/tests/test_first_boot_policy.cpp b/projects/LaunchWizard/tests/test_first_boot_policy.cpp index 9148dd2f..980f0bde 100644 --- a/projects/LaunchWizard/tests/test_first_boot_policy.cpp +++ b/projects/LaunchWizard/tests/test_first_boot_policy.cpp @@ -61,13 +61,6 @@ bool test_first_boot_policy() state.user_has_password = true; passed &= expect_wizard(true, state, "legacy piwiz ignores password"); - // Keyboard guide: needs both the marker and the installed binary; a - // missing binary keeps the marker for a later boot. - passed &= launch_wizard::should_run_keyboard_guide(true, true); - passed &= !launch_wizard::should_run_keyboard_guide(true, false); - passed &= !launch_wizard::should_run_keyboard_guide(false, true); - passed &= !launch_wizard::should_run_keyboard_guide(false, false); - if (!passed) std::cerr << "first boot policy tests failed\n"; return passed;