Skip to content

fix(AnalyzeView): Fix onboard log download path and refactor controller#14194

Open
HTRamsey wants to merge 1 commit intomavlink:masterfrom
HTRamsey:fix/onboard-log-download
Open

fix(AnalyzeView): Fix onboard log download path and refactor controller#14194
HTRamsey wants to merge 1 commit intomavlink:masterfrom
HTRamsey:fix/onboard-log-download

Conversation

@HTRamsey
Copy link
Copy Markdown
Collaborator

Summary

  • Fix download path bug: Deduplicated filenames were missing the download directory prefix, causing onboard logs to download to the home directory instead of the user-selected path
  • Add data download retry limit: _findMissingData could retry indefinitely; now bounded by kMaxDataRetries
  • Fix silent error on seek failure: File seek failures now properly report "Error" status instead of silently returning
  • Extract MAVLink send helper: Consolidated repeated vehicle/link null-check and message pack/send boilerplate into a _sendMavlinkMessage template
  • Flatten _logData: Replaced deeply nested logic with early returns, removing the result flag pattern
  • Remove dead compression API: Removed unimplemented compressLogFile, cancelCompression, and related stubs/properties/signals
  • Select-all checkbox: Header checkbox now toggles selection on all log entries
  • Guard auto-refresh: Page load no longer calls refresh() without an active vehicle
  • Minor: Fix error log to print actual file path, ensure download directory exists via mkpath, name retry constants, fix typo, remove unused QML import, deduplicate status string formatting

Test plan

  • Connect to vehicle and navigate to Analyze > Onboard Logs
  • Download a log — verify it lands in the selected directory
  • Download the same log again — verify the deduplicated file also lands in the correct directory
  • Use the header checkbox to select/deselect all logs
  • Open the Onboard Logs page without a vehicle connected — verify no spurious warnings in console
  • Cancel a download mid-transfer — verify partial file is cleaned up

Copilot AI review requested due to automatic review settings March 23, 2026 19:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the Analyze > Onboard Logs workflow by fixing the download destination bug (especially for deduplicated filenames), tightening download retry behavior, and simplifying MAVLink message sending while adding a select-all control in the UI.

Changes:

  • Fixes log download path handling (including duplicate filename generation) and ensures the destination directory is created.
  • Adds bounded retry logic for missing log data/list retrieval and refactors log-data handling for clearer control flow.
  • Updates the QML page to guard auto-refresh without an active vehicle and adds a header checkbox to select/deselect all logs.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
src/AnalyzeView/OnboardLogs/OnboardLogPage.qml Guards initial refresh without a connected vehicle; adds select-all checkbox behavior; removes unused import.
src/AnalyzeView/OnboardLogs/OnboardLogEntry.cc Enables ctor/dtor debug logging for onboard log entry/download data objects.
src/AnalyzeView/OnboardLogs/OnboardLogController.h Removes unused compression API surface and adds retry constants + MAVLink send helper declaration.
src/AnalyzeView/OnboardLogs/OnboardLogController.cc Fixes deduped file path, adds retry cap, refactors _logData, adds _sendMavlinkMessage, and ensures download directory exists.
Comments suppressed due to low confidence (1)

src/AnalyzeView/OnboardLogs/OnboardLogController.cc:63

  • QDir().mkpath(_downloadPath) return value is ignored. If directory creation fails (permissions/invalid path), the controller still enters downloading mode and later file open/resize will fail. Please check the mkpath result and fail early (set current entry status to Error and stop downloading) with a warning that includes the path.
    (void) QDir().mkpath(_downloadPath);

    _setDownloading(true);
    _receivedAllData();
}

Comment on lines +255 to +259
if (!_downloadData->file.write(reinterpret_cast<const char*>(data), count)) {
qCWarning(OnboardLogControllerLog) << "Error while writing log file chunk";
_downloadData->entry->setStatus(tr("Error"));
return;
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On file write failure you set status to Error and return, but the controller stays in downloading mode and keeps retrying, leaving a corrupted/partial file. Treat write failure as fatal: abort the current download and remove the file so subsequent downloads don’t appear to succeed with a bad artifact.

Copilot uses AI. Check for mistakes.
Comment thread src/AnalyzeView/OnboardLogs/OnboardLogController.cc Outdated
Comment on lines 394 to 401
if (_downloadData->file.exists()) {
uint32_t numDups = 0;
const QStringList filename_spl = _downloadData->filename.split('.');
do {
numDups += 1;
const QString filename = filename_spl[0] + '_' + QString::number(numDups) + '.' + filename_spl[1];
_downloadData->file.setFileName(filename);
_downloadData->file.setFileName(_downloadPath + filename);
} while ( _downloadData->file.exists());
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The deduplicated filename logic is a key behavioral change (ensuring duplicates still land under _downloadPath), but the existing OnboardLogDownloadTest doesn’t exercise the duplicate-download case. Please add/extend a unit/integration test to download the same log twice and assert the second file is created under the selected directory with the expected suffix.

Copilot uses AI. Check for mistakes.
Comment on lines +13 to 14
qCDebug(OnboardLogEntryLog) << this;
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-enabling qCDebug(OnboardLogEntryLog) in these constructors/destructors can create very noisy logs and overhead when the category is enabled. Most similar ctor/dtor debug statements in the codebase are commented out; consider reverting these to commented debug, or include Q_FUNC_INFO/more context so enabling the category yields actionable logs.

Copilot uses AI. Check for mistakes.
Comment thread src/AnalyzeView/OnboardLogs/OnboardLogController.cc Outdated
Comment thread src/AnalyzeView/OnboardLogs/OnboardLogController.cc Outdated
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 23, 2026

Build Results

Platform Status

Platform Status Details
Linux Passed View
Windows Passed View
MacOS Passed View
Android Passed View

All builds passed.

Pre-commit

Check Status Details
pre-commit Failed (non-blocking) View

Pre-commit hooks: 4 passed, 34 failed, 7 skipped.

Test Results

linux-coverage: 67 passed, 0 skipped
linux-sanitizers: 67 passed, 0 skipped
Total: 134 passed, 0 skipped

Code Coverage

Coverage: 57.4%

No baseline available for comparison

Artifact Sizes

Artifact Size
QGroundControl 247.91 MB
QGroundControl-aarch64 177.20 MB
QGroundControl-installer-AMD64 135.12 MB
QGroundControl-installer-AMD64-ARM64 77.75 MB
QGroundControl-installer-ARM64 106.47 MB
QGroundControl-linux 338.01 MB
QGroundControl-mac 188.57 MB
QGroundControl-windows 188.61 MB
QGroundControl-x86_64 172.35 MB
No baseline available for comparison

Updated: 2026-04-08 12:47:00 UTC • Triggered by: Android

Fix duplicate filenames losing download directory prefix, causing logs
to land in home directory instead of the selected path. Also:

- Add retry limit for data downloads (was infinite)
- Fix seek failure silently dropping error status
- Ensure download directory exists before writing
- Extract MAVLink send boilerplate into helper template
- Flatten _logData with early returns, removing nested result flag
- Remove dead compression API stubs and unused members
- Make header checkbox a select-all toggle
- Guard auto-refresh on page load behind vehicle check
- Fix error logs to print actual file path, not bare filename
- Name retry constants, fix typo, remove unused QML import
- Simplify duplicate status string in _updateDataRate
- Enable debug logging in OnboardLogEntry ctors/dtors
@HTRamsey HTRamsey force-pushed the fix/onboard-log-download branch from d98e084 to cb220d1 Compare April 8, 2026 11:24
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 8, 2026

Codecov Report

❌ Patch coverage is 25.26316% with 71 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (master@d1aa257). Learn more about missing BASE report.

Files with missing lines Patch % Lines
...rc/AnalyzeView/OnboardLogs/OnboardLogController.cc 26.37% 53 Missing and 14 partials ⚠️
src/AnalyzeView/OnboardLogs/OnboardLogEntry.cc 0.00% 0 Missing and 4 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##             master   #14194   +/-   ##
=========================================
  Coverage          ?   25.53%           
=========================================
  Files             ?      744           
  Lines             ?    67983           
  Branches          ?    31663           
=========================================
  Hits              ?    17362           
  Misses            ?    37843           
  Partials          ?    12778           
Flag Coverage Δ
unittests 25.53% <25.26%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/AnalyzeView/OnboardLogs/OnboardLogController.h 100.00% <ø> (ø)
src/AnalyzeView/OnboardLogs/OnboardLogEntry.cc 63.63% <0.00%> (ø)
...rc/AnalyzeView/OnboardLogs/OnboardLogController.cc 35.21% <26.37%> (ø)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d1aa257...cb220d1. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

src/AnalyzeView/OnboardLogs/OnboardLogController.cc:66

  • When starting a download, the next selected entry no longer gets a status update (previously it was set to something like "Waiting"). As a result, the UI can continue to show the old status (e.g. "Available") until enough data arrives to trigger _updateDataRate(). Consider setting the entry status to a "Waiting"/"Downloading" state before calling _receivedAllData() (for example in _downloadToDirectory or _prepareLogDownload).
    _setDownloading(true);
    _receivedAllData();
}

_downloadData.reset();
}

_resetSelection(true);
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_abortDownload() calls _resetSelection(true), which marks any still-selected logs as "Canceled" even though the abort path is an error. This can mislead users by showing "Canceled" for logs that were never attempted. Consider clearing selection without the canceled flag (or using a separate error path) so only the current entry is marked "Error" and remaining entries keep their prior status.

Suggested change
_resetSelection(true);
_resetSelection();

Copilot uses AI. Check for mistakes.
Comment on lines +294 to +298
if (_retries++ > kMaxDataRetries) {
qCWarning(OnboardLogControllerLog) << "Too many errors downloading log data. Giving up.";
_abortDownload();
return;
}
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Retry limit checks use post-increment with > (e.g. if (_retries++ > kMaxDataRetries)), which allows kMaxDataRetries + 1 attempts before aborting. If the intent is to cap retries at exactly kMaxDataRetries, adjust the logic (for example, increment first or use >=) so the constant matches the actual maximum.

Copilot uses AI. Check for mistakes.
Comment on lines 9 to 19
OnboardLogDownloadData::OnboardLogDownloadData(QGCOnboardLogEntry * const logEntry)
: ID(logEntry->id())
, entry(logEntry)
{
// qCDebug(OnboardLogEntryLog) << Q_FUNC_INFO << this;
qCDebug(OnboardLogEntryLog) << this;
}

OnboardLogDownloadData::~OnboardLogDownloadData()
{
// qCDebug(OnboardLogEntryLog) << Q_FUNC_INFO << this;
qCDebug(OnboardLogEntryLog) << this;
}
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new constructor/destructor debug logs only print the object pointer (<< this), which is hard to interpret in logs and adds noise when the category is enabled. Consider including Q_FUNC_INFO (or some identifying fields like log id) or removing these statements if they’re not needed.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants