Skip to content

Editor wip - #1

Merged
besaoct merged 399 commits into
mainfrom
editor-wip
Oct 17, 2026
Merged

besaoct merged 399 commits into
mainfrom
editor-wip

Conversation

@besaoct

@besaoct besaoct commented Oct 17, 2026

Copy link
Copy Markdown
Member

No description provided.

besaoct and others added 30 commits October 15, 2026 09:33
INT-06 (engine interface additions for render preview: renderPreview job, setRenderedRanges,
powerState) is on editor-wip (first backed up in 5a13e31). The Windows lane may add INT-06 to
landed. Android files it changed: pigeon/EngineApi.g.kt, glue/{Ports,Validation,JobsHostApiImpl,
PreviewHostApiImpl,PlatformHostApiImpl,GlueRegistrar,ContextPorts}.kt, new
preview/render/RenderPreviewServices.kt (OWNER: AND-18), and one RENDER_PREVIEW branch in
core/JobRegistry.kt.

The API-02 plan_sync _GatedSession and the INT-04 wiring _ThrowingGuard now implement the new
members, so both suites compile and pass again.
Automatic backup of the editor build; may include partial work from builders still running.
Automatic backup of the editor build; may include partial work from builders still running.
Automatic backup of the editor build; may include partial work from builders still running.
Landing record: the files landed in the WIP backup commits (67881f3).

ExportCoordinatorTest.withoutAHookAMultiPassPlanStillRunsOnePass assumed AND-19's class was not in the
tree. Once PrecomposeExport existed, ExportCoordinator.multiPassExport() returned the hook it found by
reflection, so the test could no longer get null and android_unit.sh went red. ExportCoordinator now
has a test seam, `@VisibleForTesting @volatile var discoverMultiPass = true`, which the test turns off.
Lands before AND-19, as the round's review required.

Files:
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/export/ExportCoordinator.kt
- packages/danaview_editor_engine/android/src/test/kotlin/com/vecvel/danaview/editor/engine/export/ExportCoordinatorTest.kt

Verification (2026-10-15, Windows, single Gradle worker): ./gradlew :danaview_editor_engine:assembleDebug
:danaview_editor_engine:testDebugUnitTest :danaview_editor_engine:lintDebug --max-workers=1:
BUILD SUCCESSFUL; JVM suite 336 tests, 0 failures, 0 errors, 0 skipped; lint clean.
Landing record: the files landed in the WIP backup commits up to 67881f3, including the round's review fixes.

Resumed from an earlier attempt: the implementation and tests were already in the tree, committed by the danaview_wip_* backup loop. This run checked all of it against the AND-19 acceptance criteria. One defect was in my own test: PrecomposeProcessDeathTest.startPhase required pre-2.mp4 to exist during pass 2, but InAppMp4Muxer creates the file late. The test now requires pre-1.mp4 complete (length > 0) while pass 2 runs. Two of the four Kotlin files are in the shipped package: PrecomposeExport (the @keep MultiPassExport the coordinator finds by reflection; runs the passes, enforces the disk preflight, reports progress, cleans up, raises warnings only on the final pass) and PrecomposePass (the production Transformer pass through job.build/configFor/newTransformerExport; intermediates use BT.601 limited encoder colour; portrait retry as in single pass). The other two are PrecomposePlanner (greedy lane split under DecoderBudget, intermediate settings all-intra at 4x bitrate, padded duration, disk estimate, pass weights) and PrecomposeSpecs (cuts AND-08's mapped CompositionSpec at lane boundaries; the intermediate is a rate-1 MEDIA lane clipped at the rule frame; the final pass mixes audio once). Emulator results (Pixel_9_Pro_XL_API_35, emulator measurements): precomposed vs single pass at 24/30/60 fps (3 passes): min per-frame SSIM 0.99794/0.99806/0.99807, grid-cut barcodes 48/48, 60/60 and 120/120 exact in both exports, identical frame count on the grid, worst 20 ms audio window 0.000 dB. Six slots with maxVisualSequences forced to 2: preflight ok with layersVsResolution, 5 passes, min SSIM 0.99726, barcodes 60/60. Rotated source: min SSIM 0.99909, barcodes 60/60. Cancel in pass 1, 2 and 3: no work dir and no output left. Process death (two-phase am instrument + force-stop): work dir and partial output wiped, job reported interrupted once. Wall time on the emulator: 30 fps 10.3 s single vs 17.1 s precomposed (3 passes); six slots 12.9 s vs 28.2 s (5 passes). HDR test is skipped by assumption on the emulator (no 10-bit HEVC decoder): deferred.

Deferred:
- AND-19 HDR/tone-mapped source matches single pass: deferred: no device available. The x86_64 emulator has no 10-bit HEVC (Main10) decoder, so hdrSourceMatchesSinglePass skips by assumption. It needs a real device with a 10-bit HEVC decoder and a tone-mapping path (AND-01 V-N5).
- AND-19 behaviour and timing on real hardware (intermediate colour round trip on decoders that honour the signalled matrix, real encoder bitrate clamping, multi-pass wall time): deferred: no device available. All numbers reported are emulator measurements; QA-04/QA-11 re-check on devices.
- The Dart-side export preflight disk estimate does not yet include the precompose intermediates. Natively, PrecomposeExport fails with diskFull before writing when free space < DiskEstimate.peakBytes (JVM-tested). Adding the extra bytes to the Dart preflight needs a Mac-side change (see forMac).

Files:
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/export/precompose/PrecomposeExport.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/export/precompose/PrecomposePass.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/export/precompose/PrecomposePlanner.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/export/precompose/PrecomposeSpecs.kt
- packages/danaview_editor_engine/android/src/test/kotlin/com/vecvel/danaview/editor/engine/precompose/PrecomposeExportTest.kt
- packages/danaview_editor_engine/android/src/test/kotlin/com/vecvel/danaview/editor/engine/precompose/PrecomposePlannerTest.kt
- packages/danaview_editor_engine/android/src/test/kotlin/com/vecvel/danaview/editor/engine/precompose/PrecomposeSpecsTest.kt
- packages/danaview_editor_engine/android/src/test/kotlin/com/vecvel/danaview/editor/engine/precompose/PrecomposeTestSupport.kt
- packages/danaview_editor_engine/android/src/androidTest/kotlin/com/vecvel/danaview/editor/engine/precompose/PrecomposeExportTest.kt
- packages/danaview_editor_engine/android/src/androidTest/kotlin/com/vecvel/danaview/editor/engine/precompose/PrecomposeProcessDeathTest.kt
- packages/danaview_editor_engine/android/src/androidTest/kotlin/com/vecvel/danaview/editor/engine/precompose/PrecomposeTestSupport.kt

For the Mac:
1) FIX-AND-11 request (an Android-lane test defect, not a Mac file, but AND-19 must not edit AND-11's files): ExportCoordinatorTest.withoutAHookAMultiPassPlanStillRunsOnePass (packages/danaview_editor_engine/android/src/test/kotlin/com/vecvel/danaview/editor/engine/export/ExportCoordinatorTest.kt:219) sets coordinator.multiPass = null and then asserts multiPassExport() is null. Now that AND-19's PrecomposeExport exists, ExportCoordinator.multiPassExport() returns multiPass ?: discoveredMultiPass, so the assertion fails ('expected null, but was PrecomposeExport'). android_unit.sh then fails with 336 tests and 1 failure. Fix inside AND-11: add a seam that disables reflection discovery, or change the test to assert the discovered hook is used. 2) Flaky test (AND-09): effects.Media3ChainGlTest.media3HostedProgramsMatchTheEffectPasses failed inside the full android_emulator.sh connected suite on Pixel_9_Pro_XL_API_35 (expected:<480> but was:<1920>) and passed when run alone. It looks like state leaking between tests or flakiness under load; android_emulator.sh stopped at that failure. 3) Dart-side preflight: the native preflight message (ExportPreflightMsg) carries no disk figure. AND-19 does its own disk check at job start (diskFull before anything is written, counting intermediates via PrecomposePlanner.diskEstimate). If the Dart export preflight (UX-39 or the core estimate) should count intermediates before start, it needs about extraBytes = max(2*I, I + output) - output, where I = 4x export bitrate x (durUs + 1 grid frame) / 8 x 1.02, whenever layersVsResolution is reported. That is a Mac-side change. 4) No Pigeon, glue, Gradle or manifest change is needed for AND-19.

Verification:
All commands ran from packages/danaview_editor_engine/example/android with ~/danaview_env.sh sourced.
- ./gradlew :danaview_editor_engine:assembleDebug :danaview_editor_engine:testDebugUnitTest --tests 'com.vecvel.danaview.editor.engine.precompose.*' -> exit 0. PrecomposeExportTest 7, PrecomposePlannerTest 13, PrecomposeSpecsTest 5: 25 tests, 0 failures, 0 skipped.
- ./gradlew :danaview_editor_engine:lintDebug -> exit 0.
- Under the emulator lock on Pixel_9_Pro_XL_API_35: ./gradlew :danaview_editor_engine:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.package=com.vecvel.danaview.editor.engine.precompose -> BUILD SUCCESSFUL in 3m 58s, 0 failed. hdrSourceMatchesSinglePass was skipped by assumption (no 10-bit HEVC decoder on the emulator). The two process-death phases are skipped by design in a normal run.
- Two-phase process death, run by hand: adb install the androidTest APK; am instrument -e danaviewPrecomposeKillPhase start (#startPhase) -> OK (1 test); am force-stop com.vecvel.danaview.editor.engine.test; am instrument -e danaviewPrecomposeKillPhase verify (#verifyPhase) -> OK (1 test).
- bash scripts/ci/editor/android_unit.sh -> BUILD FAILED: 336 tests, 1 failed. The failure is AND-11's ExportCoordinatorTest.withoutAHookAMultiPassPlanStillRunsOnePass (see forMac).
- bash scripts/ci/editor/android_emulator.sh (under the lock) -> connectedDebugAndroidTest finished 240 tests, 1 failed: AND-09's effects.Media3ChainGlTest.media3HostedProgramsMatchTheEffectPasses (expected:<480> but was:<1920>). Rerun alone (-Pandroid.testInstrumentationRunnerArguments.class=...Media3ChainGlTest) -> BUILD SUCCESSFUL in 20s, so it fails only inside the full suite (flaky or state leaking between tests). The script stopped at that failure, so I ran its last step by hand: flutter test integration_test/engine_smoke_test.dart -d emulator-5554 -> All tests passed! (4).
- No Dart was touched. Lock removed and emulator stopped (adb emu kill).

Review fixes folded in (round review, fixer 2026-10-15):
- intermediateLane() now passes the padded durUs as visibleUs, so the layer stays visible through the padding frame of pre-n (n >= 2).
- Intermediates are checked on the written files: each pre-n.mp4 is scanned with MediaExtractor before the next pass deletes it (all sync samples, or >= 4x the export bitrate).
- Parity metric: studio-range (16 + 219*Y/255) Y-plane SSIM >= 0.995 per frame; full-range luma SSIM is logged only (emulator match60: full-range min 0.98646, studio-range min 0.99807). Exactly one retry is allowed, only for a one-frame shortfall, logged under the tag DanaviewPrecomposeRetry; two or more frames below fail at once.

Verification after the fixes (2026-10-15, single Gradle worker): assembleDebug, testDebugUnitTest (336 tests, 0 failures, 0 skipped) and lintDebug: BUILD SUCCESSFUL. The precompose and export instrumented tests are re-run on the emulator next.
Automatic backup of the editor build; may include partial work from builders still running.
Automatic backup of the editor build; may include partial work from builders still running.
besaoct and others added 29 commits October 17, 2026 00:45
Automatic backup of the editor build; may include partial work from builders still running.
…slashes (M-11)

Mac-lead-approved Android-lane edit to an INT-07/ENG-06 file (relayed by the owner, 2026-10-17).
Landing record: the files landed in the WIP backup commits up to 2171828.

The Int07GlueTest fake port now records intoDir.invariantSeparatorsPath, so the result path and the args assertion both pass on Windows.

Files:
- packages/danaview_editor_engine/android/src/test/kotlin/com/vecvel/danaview/editor/engine/glue/Int07GlueTest.kt

Tests: Int07GlueTest is 11/11 green on Windows. That is the 9 original names (2 with M-19 assertions changed, see M-19) plus 2 new M-19 tests.
…stFixtures (M-12)

Mac-lead-approved Android-lane edit to an INT-07/ENG-06 file (relayed by the owner, 2026-10-17).
Landing record: the files landed in the WIP backup commits up to 2171828.

build.gradle.kts now makes every androidTest lint task (any name containing AndroidTest that starts with 'lint' or contains 'LintModel', which includes lintAnalyzeDebugAndroidTest and generateDebugAndroidTestLintModel) depend on tasks.matching { name == 'syncDanaviewTestFixtures' }. The match is empty when the ENG-09 harness is not applied. Nothing else in the file changed (no versions, no lint.xml).

Files:
- packages/danaview_editor_engine/android/build.gradle.kts

Tests: Before the fix, ':danaview_editor_engine:lintDebug :danaview_editor_engine:assembleDebugAndroidTest' in one invocation failed with the 'uses this output of task syncDanaviewTestFixtures without declaring a dependency' error. After the fix the same invocation gives BUILD SUCCESSFUL. I ran it a second time after deleting the generated danaviewTestFixtures dir, so the sync really executed before the lint tasks, and it was still successful. lintDebug passes on the new code.
…ll timeout and cancel (M-16)

Mac-lead-approved Android-lane edit to an INT-07/ENG-06 file (relayed by the owner, 2026-10-17).
Landing record: the files landed in the WIP backup commits up to 2171828.

New platform/PickCopier.kt (pure JVM). Each copy runs on a process-wide cached daemon pool (danaview-copy-N, background priority), so danaview-io only validates, normalizes and hands off. A watchdog thread (danaview-copy-watch) fails a copy with io (retryable) when nothing arrives for 5 min before the first byte (provider query, open, first read; cloud providers may download first) or for 60 s between later reads. On failure it closes the source to unblock the read, interrupts the copy thread and deletes the <uuid> dir; the copy thread deletes it again when it wakes. start() returns a Cancellable: a cancelled copy fails with cancelled and its partial file is deleted. Completion happens exactly once, whichever of success, error, stall or cancel comes first. PickMaterializer is now one instance per ContextPlatformPort (per Flutter engine) and tracks its in-flight copies; GlueRegistrar.detach calls cancelMaterializations(). No Pigeon or Dart change: there is still no Dart-callable cancel, which would need an [INTEGRATION] ticket. A source that never unblocks keeps its pool thread, but never holds a lane.

Review findings fixed before landing: (1) a stall or cancel during the provider query/open could not free its copy thread: the query and open now take a CancellationSignal that abort cancels; (2) abort deleted the partial copy on the cancelling thread (main, from GlueRegistrar.detach): the delete now runs on the watchdog thread.
No Dart-callable cancel exists; adding one needs an [INTEGRATION] ticket.

Files:
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/platform/PickCopier.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/platform/PickMaterializer.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/glue/ContextPorts.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/glue/GlueRegistrar.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/glue/PlatformHostApiImpl.kt
- packages/danaview_editor_engine/android/src/test/kotlin/com/vecvel/danaview/editor/engine/platform/PickCopierTest.kt
- packages/danaview_editor_engine/android/src/androidTest/kotlin/com/vecvel/danaview/editor/engine/platform/PickMaterializerTest.kt

Tests: JVM PickCopierTest, 10 tests, all pass. Covered: the copy runs on danaview-copy; a stall gives io and leaves nothing; an open timeout gives io; cancel gives cancelled, deletes the partial file and completes once (also when cancelled before the thread starts). danaviewIoAnswersRecorderProbeAndFreeBytesWhileACopyHangs uses real-thread lanes with the real PlatformHostApiImpl, RecorderHostApiImpl and EngineHostApiImpl: isRecording, freeBytes and probe all answer while a copy hangs, then cancel gives a 'cancelled' Pigeon error and the dir is deleted. On device (emulator-5554, API 35), PickMaterializerTest.danaviewIoKeepsAnsweringWhileACopyHangsUntilCancelAll passes on the real HandlerThread danaview-io.
… free-space preflight (M-18)

Mac-lead-approved Android-lane edit to an INT-07/ENG-06 file (relayed by the owner, 2026-10-17).
Landing record: the files landed in the WIP backup commits up to 2171828.

The storage-full code is diskFull, which already exists in ErrorCodes and in the Pigeon doc. Source side: SecurityException → permissionDenied; FileNotFoundException with EACCES/EPERM/'Permission denied' → permissionDenied; any other FileNotFoundException (the item is gone) → mediaOffline; open or read IOException → io. Output side (the engine's own work dir): ENOSPC/EDQUOT, or under 1 MiB free → diskFull; everything else → io, so a full disk or an EACCES on the output no longer reads as mediaOffline. A failed mkdirs is diskFull when under 64 MiB is free, otherwise io. Free-space preflight: the source size comes from OpenableColumns.SIZE or File.length(). When known and usable space < size + 64 MiB (Dart's ImportPolicy.freeSpaceMarginBytes), the copy fails diskFull before anything is written. This is the native half of M-17's concern; the Dart preflight stays with the Mac. I also refined the shared EngineErrors.from: a FileNotFoundException is now mediaOffline only when it is not EACCES/EPERM (→ permissionDenied) or ENOSPC (→ diskFull). That applies engine-wide; existing tests that expect mediaOffline still pass. New helpers EngineErrors.isNoSpace and isPermissionDenied.

This also covers the native half of M-17 (owner-approved 2026-10-17): with a known source size, a copy that would leave under size + 64 MiB free fails diskFull before anything is written (64 MiB mirrors Dart's ImportPolicy.freeSpaceMarginBytes); ENOSPC mid-copy fails diskFull and deletes the partial file. The Dart preflight half of M-17 stays with the Mac.

Files:
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/core/ErrorCodes.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/platform/PickCopier.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/platform/PickMaterializer.kt
- packages/danaview_editor_engine/android/src/test/kotlin/com/vecvel/danaview/editor/engine/platform/PickCopierTest.kt
- packages/danaview_editor_engine/android/src/test/kotlin/com/vecvel/danaview/editor/engine/platform/PickPathsAndCodesTest.kt

Tests: JVM PickCopierTest: a known size that does not fit → diskFull with no open; output ENOSPC → diskFull; output EACCES or ENAMETOOLONG → io; ENOSPC mid-copy → diskFull and the partial file is deleted; source SecurityException, EACCES or 'Permission denied' → permissionDenied; ENOENT or 'No item' → mediaOffline; read error → io. PickPathsAndCodesTest.fileNotFoundIsOnlyMediaOfflineWhenTheFileIsGone also passes. On device, PickMaterializerTest.missingAndUnreadableSourcesGetTheirOwnCodes passes (ran, not assumption-skipped): a missing file → mediaOffline, a deleted FileProvider item → mediaOffline, a mode-000 file → permissionDenied, and no partial dirs are left.
…s (M-19)

Mac-lead-approved Android-lane edit to an INT-07/ENG-06 file (relayed by the owner, 2026-10-17).
Landing record: the files landed in the WIP backup commits up to 2171828.

ExportNotificationTexts.withFallbacks replaces each blank or over-256-char string with its English default, for that string only. Check.notificationTexts now returns the cleaned texts and never throws, so neither initialize nor export start can fail because of texts. ExportNotificationTexts.set applies the fallbacks too. The root port's initialize path uses the new setFromInitialize: texts equal to the English defaults (an engine started with the default config) do not replace localized texts another engine already set, while other localized texts do. An export start that carries texts, English included, always replaces them for its job. ExportNotification.kt is unchanged.

Files:
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/export/ExportNotificationTexts.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/glue/Validation.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/glue/EngineHostApiImpl.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/glue/ExportHostApiImpl.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/glue/ContextPorts.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/glue/Ports.kt
- packages/danaview_editor_engine/android/src/test/kotlin/com/vecvel/danaview/editor/engine/glue/Int07GlueTest.kt

Tests: Int07GlueTest has 2 new tests. initializeFallsBackPerStringInsteadOfFailing: blank, empty and 257-char strings fall back, exactly 256 chars is kept, and the valid localized strings stay. aDefaultConfigEngineKeepsTheLocalizedTextsOfAnother: goes through the real ContextEngineRootPort. Two existing assertions changed to match the approved behaviour; neither was weakened. The 'bad text → internal' check was moved into initializeFallsBackPerStringInsteadOfFailing. The start test now expects success, and that the 300-char cancel became 'Cancel' while the other strings stayed localized. On device, the export and service androidTest packages pass.
… Dart (M-20)

Mac-lead-approved Android-lane edit to an INT-07/ENG-06 file (relayed by the owner, 2026-10-17).
Landing record: the files landed in the WIP backup commits up to 2171828.

New Paths.normalizeFileUriOrPath implements Uri.toFilePath(windows: false) semantics. Plain paths go to normalize() unchanged and are never decoded. For file: URIs, each segment is percent-decoded as UTF-8 exactly once, '+' stays '+', and a '%' not followed by two hex digits stays a literal '%' (as Dart's parse re-escapes it). It returns null for a non-empty authority (including localhost), a query or fragment, an encoded '/' or NUL, invalid UTF-8, or '..'. Only PickMaterializer uses it. Paths.normalize is unchanged because other callers build file:// strings from raw paths: RenderedRangeHandler.fileUri and RenderPreviewSpecs:141, which are AND-18 code and consistent with each other; Probe already decodes via Uri.parse().path.

Files:
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/core/Paths.kt
- packages/danaview_editor_engine/android/src/main/kotlin/com/vecvel/danaview/editor/engine/platform/PickMaterializer.kt
- packages/danaview_editor_engine/android/src/test/kotlin/com/vecvel/danaview/editor/engine/platform/PickPathsAndCodesTest.kt
- packages/danaview_editor_engine/android/src/androidTest/kotlin/com/vecvel/danaview/editor/engine/platform/PickMaterializerTest.kt

Tests: JVM PickPathsAndCodesTest covers %20, %25, UTF-8 escapes, '+', invalid escapes, no double-decoding ('file:///a/My%2520Clip.mp4' → '/a/My%20Clip.mp4'; plain '/a/My%20Clip.mp4' unchanged), and the refused URIs. On device, PickMaterializerTest.percentEncodedFileUrisAreDecodedLikeDart copies 'file://…/My%20Clip.bin' as 'My Clip.bin'; contentPicksAreCopiedWithTheirDisplayName and appOwnedCopiesUnderWorkAreReturnedAsIs also pass.

Verification for M-11, M-12, M-16, M-18, M-19 and M-20 (Windows, one Gradle worker):
- After the review fixes, one invocation of :danaview_editor_engine:testDebugUnitTest :danaview_editor_engine:lintDebug :danaview_editor_engine:assembleDebugAndroidTest: BUILD SUCCESSFUL; 413 JVM tests, 0 failures, 0 errors (the full suite is green on Windows for the first time); lint 0 errors.
- connectedDebugAndroidTest on the API 35 emulator for platform, export and service: all PickMaterializerTest (5), export and service tests pass. One failure, PickerFlowTest.photoPickerMultiPickPersistsGrants (AND-14), fails alone too and is unrelated: it taps the first two Photo Picker items, and the emulator gallery now holds QA-02's saved exports, which sort ahead of the test's inserted items. Follow-up for AND-14: select the test's own items.
- Review: PASS with two minor findings, both fixed (see M-16). No Pigeon, Dart, dependency, lint.xml or manifest change.

For the Mac:
All six edits are Android-only. No Pigeon or generated code changed, no method names or signatures changed, and no dependency versions, lint.xml or manifest changed.

Behaviour the Dart side will now see:
(a) materializePick returns codes that match the Pigeon doc. diskFull covers ENOSPC, and also a known source size that would leave less than 64 MiB free; the 64 MiB mirrors ImportPolicy.freeSpaceMarginBytes. A stalled copy fails with io and retryable=true after 60 s with no new bytes, or 5 min before the first byte. A copy fails with cancelled when its Flutter engine detaches. mobile_media_access.dart already maps diskFull to StoreFailure(diskFull) and the other codes through mediaAccessFailureOf, so no Dart change is needed. M-17's Dart half (media_pool_service calling _preflight(size, moving: false) before materializing) is still yours; the native side now refuses copies that would not fit.
(b) Notification texts never fail initialize or start. A bad string falls back to its English default for that string only. An initialize that sends exactly the English defaults does not overwrite localized texts already set by another engine; an export start that carries texts always applies them. The optional Dart-side asserts in the ExportNotificationTexts constructor (D5) are still up to you.
(c) EngineErrors.from now maps a FileNotFoundException with EACCES/EPERM to permissionDenied and one with ENOSPC to diskFull, engine-wide. Before, every FileNotFoundException was mediaOffline.

QA-02 note for your next full pass: the emulator gallery holds QA-02's saved exports (Movies/Danaview/export-*.mp4), which makes AND-14's PickerFlowTest.photoPickerMultiPickPersistsGrants pick the wrong items. Either clear Movies/Danaview on emulator-5554 before the native androidTest pass, or have the test select its own dv_pick_* items by name.
…ose flush, handoff playhead, suite and host harness, pick free-space check

FIX-M15: close never waits on an attached open / first resolve; tasks suspend on close; bounded release steps with [EditorClose]/[EditorLifecycle] logs. Device logs will show whether the remaining on-screen delay is native (see close_after_recovery_test header).
FIX-M1: tier-aware close flush (4/6/8/10 s), 'Still saving' dialog, saves never lost; harness waits for save idle.
FIX-M9: player handoff playhead on the fresh-install/data-clear path.
FIX-QA00-R7: M-2, M-14, M-10, M-4, M-13, M-3, M-5. FIX-HOST-R7: M-6 verified activity finish and swipe, M-7 direct notification cancel.
FIX-M17-DART: free-space check before materializing a pick.
Automatic backup of the editor build; may include partial work from builders still running.
Automatic backup of the editor build; may include partial work from builders still running.
Automatic backup of the editor build; may include partial work from builders still running.
Automatic backup of the editor build; may include partial work from builders still running.
Automatic backup of the editor build; may include partial work from builders still running.
Automatic backup of the editor build; may include partial work from builders still running.
Automatic backup of the editor build; may include partial work from builders still running.
Automatic backup of the editor build; may include partial work from builders still running.
Automatic backup of the editor build; may include partial work from builders still running.
Automatic backup of the editor build; may include partial work from builders still running.
The Freebuff project id is machine-specific state that got swept into a WIP
backup commit; keeping it out of the tree stops unrelated diffs and merge
noise on every lane.
@besaoct
besaoct merged commit 73aee70 into main Oct 17, 2026
6 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants