Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions projects/APPLaunch/main/ui/model/setup_page_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,13 @@ bool SetupPageModel::move_main(int direction, int item_count)
return true;
}

void SetupPageModel::enter_sub(int item_count, int center_row)
void SetupPageModel::enter_sub(int item_count, int center_row, int preferred_index)
{
view = SetupViewState::SUB;
sub_selected_index = clamp_index(std::min(center_row, item_count - 1), item_count);
if (preferred_index >= 0)
sub_selected_index = clamp_index(preferred_index, item_count);
else
sub_selected_index = clamp_index(std::min(center_row, item_count - 1), item_count);
}

bool SetupPageModel::move_sub(int direction, int item_count)
Expand Down
3 changes: 2 additions & 1 deletion projects/APPLaunch/main/ui/model/setup_page_model.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ class SetupPageModel
std::string value_title;

bool move_main(int direction, int item_count);
void enter_sub(int item_count, int center_row = DEFAULT_CENTER_ROW);
void enter_sub(int item_count, int center_row = DEFAULT_CENTER_ROW,
int preferred_index = -1);
bool move_sub(int direction, int item_count);
void select_sub(int index, int item_count);
void enter_value(std::string title, std::vector<std::string> options, int selected_index);
Expand Down
1 change: 1 addition & 0 deletions projects/APPLaunch/main/ui/page_app/setting/bluetooth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ void BluetoothUiSession::handle_list_key(UISetupPage &page, uint32_t key)
action_operation_.abort(action_token_);
action_busy_ = false;
SetupPageAccess access(page);
refresh_status(page);
access.set_view(SetupViewState::SUB);
access.build_sub_view();
break;
Expand Down
1 change: 1 addition & 0 deletions projects/APPLaunch/main/ui/page_app/setting/menu_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct MenuItem
std::vector<SubItem> sub_items;
std::function<void()> on_enter;
std::function<void(uint32_t key)> custom_key_handler;
int default_sub_selection = -1;
};

} // namespace setting
3 changes: 1 addition & 2 deletions projects/APPLaunch/main/ui/page_app/setting/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ void Update::append(UISetupPage &page, std::vector<MenuItem> &menu)
{"Version: --", false, false, nullptr},
{"Build: --", false, false, nullptr},
};
item.default_sub_selection = 0;
item.on_enter = [page_ptr]() { Update::refresh_version_info(*page_ptr); };
menu.push_back(item);
}
Expand Down Expand Up @@ -283,7 +284,6 @@ void UISetupPage::stop_update_timer(bool cancel_job)
if (cancel_job && !update_job_id_.empty())
cp0_signal_osinfo_api({"UpdateJobCancel", update_job_id_}, nullptr);
update_job_id_.clear();
update_item_index_ = -1;
if (had_job) launcher_toast().hide();
}

Expand All @@ -307,7 +307,6 @@ void UISetupPage::start_update_job(const char *command, int item_index)
launcher_toast().show("Launcher update unavailable");
return;
}
update_item_index_ = item_index;
update_timer_ = lv_timer_create(update_timer_cb, 500, this);
if (!update_timer_) {
stop_update_timer();
Expand Down
1 change: 0 additions & 1 deletion projects/APPLaunch/main/ui/page_app/ui_app_setup.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ class UISetupPage : public AppPage
lv_timer_t *update_timer_ = nullptr;
lv_timer_t *volume_preview_timer_ = nullptr;
std::string update_job_id_;
int update_item_index_ = -1;

static constexpr int SCREEN_W = 320;
static constexpr int SCREEN_H = 150;
Expand Down
2 changes: 1 addition & 1 deletion projects/APPLaunch/main/ui/page_app/ui_app_setup_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ void UISetupPage::handle_main_key(uint32_t key)
if (item.on_enter) item.on_enter();
if (!item.sub_items.empty()) {
int sub_count = static_cast<int>(item.sub_items.size());
model_.enter_sub(sub_count, ROW_CENTER);
model_.enter_sub(sub_count, ROW_CENTER, item.default_sub_selection);
build_sub_view();
}
break;
Expand Down
4 changes: 4 additions & 0 deletions projects/APPLaunch/tests/test_setup_page_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ int main()
assert(model.sub_selected_index == 0);
assert(model.move_sub(-1, 2));
assert(model.sub_selected_index == 1);
model.enter_sub(2, SetupPageModel::DEFAULT_CENTER_ROW, 0);
assert(model.sub_selected_index == 0);
model.enter_sub(2, SetupPageModel::DEFAULT_CENTER_ROW, 99);
assert(model.sub_selected_index == 1);
model.select_sub(0, 2);
assert(model.sub_selected_index == 0);
model.select_sub(99, 2);
Expand Down
47 changes: 43 additions & 4 deletions projects/APPLaunch/tests/test_updater_packaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ def run_update(fail_install: bool = False,
unhealthy_process: bool = False,
audit_required: bool = False,
interrupted_candidate: bool = False,
compatible: bool = True) -> tuple[subprocess.CompletedProcess[str], str, str]:
compatible: bool = True,
candidate_version: str | None = None,
installed_version: str | None = None,
rollback_version: str | None = None,
after_version: str | None = None,
compare_exit: int = 0) -> tuple[subprocess.CompletedProcess[str], str, str]:
with tempfile.TemporaryDirectory() as temp_dir:
root = Path(temp_dir)
fake_bin = root / "bin"
Expand Down Expand Up @@ -60,6 +65,8 @@ def run_update(fail_install: bool = False,
"1\n" if compatible else "0\n", encoding="ascii"
)
if provide_rollback:
cache.mkdir()
(cache / "installed.deb").write_bytes(b"trusted rollback package")
old_package = old_release / "applaunch_1.0_arm64.deb"
old_package.write_bytes(b"trusted previous package")
old_digest = hashlib.sha256(old_package.read_bytes()).hexdigest()
Expand All @@ -73,17 +80,20 @@ def run_update(fail_install: bool = False,
fake_bin / "dpkg-deb",
'case "$3" in Package) echo applaunch;; Architecture) echo arm64;; '
'X-CardputerZero-Update-ABI) echo "${TEST_UPDATE_ABI:-1}";; '
'Version) case "$2" in *installed.deb|*rollback.deb) echo 1.0;; *) echo 2.0;; esac;; esac\n',
'Version) case "$2" in *installed.deb|*rollback.deb) '
'echo "${TEST_ROLLBACK_VERSION:-1.0}";; *) '
'echo "${TEST_CANDIDATE_VERSION:-2.0}";; esac;; esac\n',
)
executable(
fake_bin / "dpkg-query",
'case "$2" in *Status*) echo installed;; *) '
'if [ -f "$TEST_MARKER" ]; then echo 2.0; else echo 1.0; fi;; esac\n',
'if [ -f "$TEST_MARKER" ]; then echo "${TEST_AFTER_VERSION:-2.0}"; '
'else echo "${TEST_INSTALLED_VERSION:-1.0}"; fi;; esac\n',
)
executable(
fake_bin / "dpkg",
'echo "dpkg $*" >>"$TEST_LOG"\n'
'case "$1" in --compare-versions) exit 0;; --audit) '
'case "$1" in --compare-versions) exit "${TEST_COMPARE_EXIT:-0}";; --audit) '
'[ ! -f "$TEST_AUDIT_MARKER" ] || echo "package needs configuration";; --configure) '
'[ "${TEST_FAIL_CONFIGURE:-0}" != 1 ] || exit 44; '
'[ "${TEST_KEEP_AUDIT_DIRTY:-0}" = 1 ] || rm -f "$TEST_AUDIT_MARKER";; -i) '
Expand Down Expand Up @@ -114,6 +124,11 @@ def run_update(fail_install: bool = False,
"TEST_FAIL_CONFIGURE": "1" if fail_configure else "0",
"TEST_KEEP_AUDIT_DIRTY": "1" if keep_audit_dirty else "0",
"TEST_AUDIT_MARKER": str(root / "audit.marker"),
"TEST_CANDIDATE_VERSION": candidate_version or "",
"TEST_INSTALLED_VERSION": installed_version or "",
"TEST_ROLLBACK_VERSION": rollback_version or "",
"TEST_AFTER_VERSION": after_version or "",
"TEST_COMPARE_EXIT": str(compare_exit),
"APPLAUNCH_UPDATER_REEXEC": "1",
"APPLAUNCH_UPDATE_EXECUTABLE": str(app_executable),
"APPLAUNCH_UPDATE_PROC_ROOT": str(proc),
Expand Down Expand Up @@ -185,6 +200,30 @@ def run_update(fail_install: bool = False,
assert missing_rollback.returncode != 0
assert status == "failed:rollback-unavailable"

local_to_cloud, status, commands = run_update(
candidate_version="2.0",
installed_version="3.0+local.test1",
rollback_version="3.0+local.test1",
after_version="2.0",
compare_exit=1,
)
assert local_to_cloud.returncode == 0, (
local_to_cloud.stderr, local_to_cloud.stdout, status, commands
)
assert status == "succeeded:2.0"
assert "dpkg -i" in commands

official_downgrade, status, commands = run_update(
candidate_version="2.0",
installed_version="3.0",
rollback_version="3.0",
after_version="2.0",
compare_exit=1,
)
assert official_downgrade.returncode != 0
assert status == "failed:version-not-newer"
assert "dpkg -i" not in commands

incompatible, status, commands = run_update(compatible=False)
assert incompatible.returncode != 0
assert status == "failed:incompatible"
Expand Down
2 changes: 1 addition & 1 deletion projects/CameraApp/main_CameraApp
2 changes: 1 addition & 1 deletion projects/FactoryTest/main_FactoryTest
Submodule main_FactoryTest updated 117 files
1 change: 1 addition & 0 deletions projects/ZClaw/main/ui/zclaw_app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ class ZClawApp : public AppPageRoot
zclaw::KeyRouteContext context;
context.startup = startup_workflow_.state();
context.input_open = input_dialog_.is_open();
context.input_mode = input_dialog_.mode();
context.approval_pending = approvals_.pending();
context.setup_retry_pending =
settings_workflow_.setup_retry_pending();
Expand Down
5 changes: 4 additions & 1 deletion projects/ZClaw/main/ui/zclaw_input_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ namespace zclaw {

bool input_is_single_line(InputMode mode)
{
return mode != InputMode::Chat;
return mode != InputMode::Chat && mode != InputMode::SetupUriEdit &&
mode != InputMode::ProviderUriEdit;
}

InputSubmission input_submission(InputMode mode, std::string value)
Expand All @@ -19,9 +20,11 @@ InputSubmission input_submission(InputMode mode, std::string value)
: InputSubmissionAction::SendChat;
break;
case InputMode::SetupEdit:
case InputMode::SetupUriEdit:
submission.action = InputSubmissionAction::ApplySetupEdit;
break;
case InputMode::ProviderEdit:
case InputMode::ProviderUriEdit:
submission.action = InputSubmissionAction::ApplyProviderEdit;
break;
case InputMode::PairingCode:
Expand Down
2 changes: 2 additions & 0 deletions projects/ZClaw/main/ui/zclaw_input_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ namespace zclaw {
enum class InputMode {
Chat,
SetupEdit,
SetupUriEdit,
ProviderEdit,
ProviderUriEdit,
PairingCode,
};

Expand Down
1 change: 1 addition & 0 deletions projects/ZClaw/main/ui/zclaw_key_event_adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ KeyEvent adapt_key_event(std::uint32_t key_code, int key_state,
event.phase = adapt_key_phase(key_state);
event.key = adapt_key(key_code);
event.shift = (modifiers & KBD_MOD_SHIFT) != 0;
event.fn = (modifiers & KBD_MOD_FN) != 0;
if (utf8)
event.text = utf8;
return event;
Expand Down
4 changes: 4 additions & 0 deletions projects/ZClaw/main/ui/zclaw_key_router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ KeyAction route_key(const KeyRouteContext &context, const KeyEvent &event)
if (context.input_open) {
if (event.key == Key::Escape)
return {KeyActionType::InputClose, {}};
if (event.key == Key::Tab &&
(context.input_mode == InputMode::SetupUriEdit ||
context.input_mode == InputMode::ProviderUriEdit))
return {KeyActionType::InputInsertNewline, {}};
if (event.key == Key::Tab)
return {KeyActionType::InputToggleSecretVisibility, {}};
if (event.key == Key::Enter && !event.shift)
Expand Down
3 changes: 3 additions & 0 deletions projects/ZClaw/main/ui/zclaw_key_router.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "zclaw_input_model.h"
#include "zclaw_settings_navigation_model.h"
#include "zclaw_startup_model.h"

Expand Down Expand Up @@ -39,11 +40,13 @@ struct KeyEvent {
Key key = Key::Other;
bool shift = false;
std::string text;
bool fn = false;
};

struct KeyRouteContext {
StartupState startup = StartupState::CheckingNetwork;
bool input_open = false;
InputMode input_mode = InputMode::Chat;
bool approval_pending = false;
bool setup_retry_pending = false;
bool setup_in_flight = false;
Expand Down
17 changes: 7 additions & 10 deletions projects/ZClaw/main/ui/zclaw_provider_workflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include "zclaw_provider_manager.h"
#include "zclaw_settings_coordinator.h"
#include "zclaw_settings_panel.h"
#include "zclaw_secret_input_model.h"

#include <cstddef>

Expand Down Expand Up @@ -73,12 +72,13 @@ void ProviderWorkflow::edit_selected_field()
const std::string *value = provider_field_value(
&provider, settings_.state().provider_edit_field());
if (value) {
const bool secret =
settings_.state().provider_edit_field() == ProviderEditField::ApiKey;
const bool uri =
settings_.state().provider_edit_field() == ProviderEditField::Uri;
input_.open_text(&fonts_,
provider_field_name(settings_.state().provider_edit_field()),
secret ? secret_input_initial_text() : *value,
InputMode::ProviderEdit, secret);
*value,
uri ? InputMode::ProviderUriEdit : InputMode::ProviderEdit,
false);
}
}

Expand All @@ -93,11 +93,8 @@ void ProviderWorkflow::apply_edit(const std::string &value)
ProviderConfig provider = providers_.providers()[provider_index];
std::string *field = provider_field_value(
&provider, settings_.state().provider_edit_field());
if (field) {
*field = settings_.state().provider_edit_field() == ProviderEditField::ApiKey
? apply_secret_input(*field, value)
: value;
}
if (field)
*field = value;
settings_.state().set_provider_edit_field(ProviderEditField::None);
std::string error;
if (!providers_.replace(static_cast<std::size_t>(provider_index), provider,
Expand Down
17 changes: 7 additions & 10 deletions projects/ZClaw/main/ui/zclaw_setup_workflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include "zclaw_provider_catalog.h"
#include "zclaw_provider_manager.h"
#include "zclaw_settings_coordinator.h"
#include "zclaw_secret_input_model.h"
#include "zclaw_ui_config_manager.h"

#include <cstddef>
Expand Down Expand Up @@ -86,12 +85,13 @@ void SetupWorkflow::edit_selected_field()
const std::string *value =
setup_field_value(&provider, settings_.state().setup_edit_field());
if (value) {
const bool secret =
settings_.state().setup_edit_field() == SetupEditField::ApiKey;
const bool uri =
settings_.state().setup_edit_field() == SetupEditField::Uri;
input_.open_text(&fonts_,
setup_field_name(settings_.state().setup_edit_field()),
secret ? secret_input_initial_text() : *value,
InputMode::SetupEdit, secret);
*value,
uri ? InputMode::SetupUriEdit : InputMode::SetupEdit,
false);
}
}

Expand All @@ -100,11 +100,8 @@ void SetupWorkflow::apply_edit(const std::string &value)
ProviderConfig provider = providers_.setup_provider();
std::string *field =
setup_field_value(&provider, settings_.state().setup_edit_field());
if (field) {
*field = settings_.state().setup_edit_field() == SetupEditField::ApiKey
? apply_secret_input(*field, value)
: value;
}
if (field)
*field = value;
settings_.state().set_setup_edit_field(SetupEditField::None);
std::string error;
if (!providers_.update_setup_provider(provider, &error))
Expand Down
13 changes: 13 additions & 0 deletions projects/ZClaw/tests/zclaw_input_routing_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ int main()
using zclaw::InputSubmissionAction;
assert(!zclaw::input_is_single_line(InputMode::Chat));
assert(zclaw::input_is_single_line(InputMode::SetupEdit));
assert(!zclaw::input_is_single_line(InputMode::SetupUriEdit));
assert(zclaw::input_is_single_line(InputMode::ProviderEdit));
assert(!zclaw::input_is_single_line(InputMode::ProviderUriEdit));
assert(zclaw::input_is_single_line(InputMode::PairingCode));
zclaw::InputSubmission submission =
zclaw::input_submission(InputMode::Chat, "hello");
Expand All @@ -29,8 +31,12 @@ int main()
InputSubmissionAction::None);
assert(zclaw::input_submission(InputMode::SetupEdit, "").action ==
InputSubmissionAction::ApplySetupEdit);
assert(zclaw::input_submission(InputMode::SetupUriEdit, "").action ==
InputSubmissionAction::ApplySetupEdit);
assert(zclaw::input_submission(InputMode::ProviderEdit, "").action ==
InputSubmissionAction::ApplyProviderEdit);
assert(zclaw::input_submission(InputMode::ProviderUriEdit, "").action ==
InputSubmissionAction::ApplyProviderEdit);

using zclaw::Key;
using zclaw::KeyActionType;
Expand All @@ -51,6 +57,8 @@ int main()
assert(!adapted.shift && adapted.text.empty());
adapted = zclaw::adapt_key_event(KEY_ESC, KBD_KEY_RELEASED, 0, "");
assert(adapted.key == Key::Escape && adapted.phase == KeyPhase::Released);
adapted = zclaw::adapt_key_event(KEY_UP, KBD_KEY_PRESSED, KBD_MOD_FN, nullptr);
assert(adapted.key == Key::Up && adapted.fn);
adapted = zclaw::adapt_key_event(KEY_RESERVED, 99, KBD_MOD_CTRL, "x");
assert(adapted.key == Key::Other && adapted.phase == KeyPhase::Unknown);
assert(!adapted.shift && adapted.text == "x");
Expand Down Expand Up @@ -100,6 +108,11 @@ int main()
KeyActionType::InputSubmit);
assert(routed(context, KeyPhase::Released, Key::Tab).type ==
KeyActionType::InputToggleSecretVisibility);
context.input_mode = InputMode::ProviderUriEdit;
assert(routed(context, KeyPhase::Released, Key::Tab).type ==
KeyActionType::InputInsertNewline);
assert(routed(context, KeyPhase::Released, Key::Escape).type ==
KeyActionType::InputClose);
assert(routed(context, KeyPhase::Released, Key::Enter, true).type ==
KeyActionType::None);
assert(routed(context, KeyPhase::Released, Key::Down).type ==
Expand Down
Loading
Loading