M1 공유 타겟(U1)+M2 저장 진행 알림: ACTION_SEND 인텐트 필터+ShareTarget/SharePayload(RED 7건)+루트 타이머 큐 전송(am start 인텐트 E2E로 서버 큐 반영 실증), 오프라인 저장 Android ProgressBar 노티(5% 스로틀)→폰 저장 완료 전환(34MB E2E, Report(1) 되덮어쓰기 방지). 154/154 GREEN

This commit is contained in:
Yun Chan 2026-08-15 18:45:51 +09:00
parent 69094595a5
commit 04ff0ff93d
7 changed files with 166 additions and 6 deletions

View file

@ -2,7 +2,7 @@
> **대상**: `BROWSER_FEATURES_PLAN.md` (v2) + `MOBILE_PLAN.md` (v1) 전 항목
> **감사일**: 2026-08-15 · **방법**: TDD(RED→GREEN) + E2E 검증
> **요약**: 전 솔루션 Release 빌드 **0 오류**, 단위/E2E 테스트 **147/147 GREEN**, Android 에뮬레이터·iOS 시뮬레이터·LAN 서버 E2E 완료
> **요약**: 전 솔루션 Release 빌드 **0 오류**, 단위/E2E 테스트 **154/154 GREEN**, Android 에뮬레이터·iOS 시뮬레이터·LAN 서버 E2E 완료
>
> **감사 중 발견·수정된 회귀**: `HlsDownloader` 3-인자 ctor가 `_muxer` 미할당(재구성 ② 누락) → 모든 HLS 리먹스 NUL 위험. RED 테스트(`HlsMuxerWiringTests`)로 재현 후 ctor 할당 수정. `DashDownloader`는 정상.
@ -101,6 +101,7 @@
| **M1** QR 스캔 페어링 + 수동 폴백 | ✅ ZXing(실기기) + 수동 IP:포트+토큰 | 에뮬레이터 E2E에서 수동 페어링으로 실증 (IME 제약) |
| **M1** 큐 목록 실시간 + 제어 | ✅ 2초 폴링(계획 허용안: "v1은 2초 폴링 가능"), 일시정지/재개/취소 버튼 | 에뮬 E2E: 라이브 서버 데이터 렌더 실증 |
| **M1** 링크 붙여넣기 추가 | ✅ URL 엔트리 + "PC에서 받기" | 페이지 UI + 서버 API E2E (POST 400 검증 포함) |
| **M1** 공유 타겟(U1) | ✅ ACTION_SEND 인텐트 필터("PC에서 받기") + MainActivity OnCreate/OnNewIntent → ShareTarget 채널 → 루트 2s 타이머가 SharePayload.ExtractUrl → POST /api/queue | `SharePayload` 단위 7건(RED→GREEN) · 에뮬 E2E: **`am start -a SEND --es EXTRA_TEXT "…https://youtu.be/E2ESHARE123"` → 서버 큐에 해당 URL 반영 확인** + dumpsys 로 인텐트 필터 등록 확인 |
| **M2** 라이브러리 목록 | ✅ 파일명/크기 | 에뮬 E2E: sample.mp4/415,253 bytes 렌더 |
| **M2** MediaElement 스트리밍 재생 | ✅ Range HTTP → 모달 플레이어 | 에뮬 E2E: **실제 MP4 프레임 렌더 실증**(testsrc 패턴 스크린샷) + 서버 ESTABLISHED |
| **M2-U3** 이어보기 위치 동기화 | ✅ `POST/GET /api/position/{id}` + PositionStore(positions.json 영속) + 플레이어 5초 주기·종료 시 저장, 재생 시작 시 시크 | RED→GREEN `이어보기_위치_동기화_E2E` · 에뮬 E2E: positions.json 13.3→24.2→**35.2초**(재오픈 시 저장 위치에서 이어 재생 실증) |
@ -124,6 +125,7 @@
| 재생중 미디어 알림 | ✅ 플레이어 열릴 때 ongoing 노티 "재생 중"(채널 vd_playback), 닫히면 취소 | 에뮬 E2E: 게시·소멸 lifecycle 실증(dumpsys). **FGS 미사용** — 재생은 앱 내(포그라운드) 한정이므로 ongoing 노티로 충족, 문서화 |
| 라이브러리 그리드(썸네일·해상도) | ✅ 서버 Thumbnailer(ffmpeg 1초 프레임 320px JPEG + 해상도 ffprobe, 사이드카 .thumb.jpg/.meta.json 캐시) + `GET /api/library/{id}/thumb` + DTO Resolution + 앱 2열 그리드 | `ThumbnailerTests` 4건(Fake 러너) + 서버 E2E(JPEG 매직/404/401) + 에뮬 E2E: **실제 ffmpeg 썸네일 렌더**(스크린샷)·해상도 "480x270" |
| 외부망 안내(§7) | ✅ ConnectionTroubleshoot(같은 네트워크/Tailscale 안내) → QueuePage 표시 | 단위 3건 + 에뮬 E2E: 죽은 포트 페어링 → "같은 네트워크… Tailscale 등 VPN" 문구 실증 |
| 오프라인 저장 진행 알림(M2) | ✅ 💾 저장 중 Android ProgressBar 노티(5% 스로틀 갱신) → 완료 시 "폰 저장 완료" 노티로 전환 | 에뮬 E2E: 34MB 저장 중 "폰에 저장 중 — N%" 라이브 관측(t=1~12s) → 완료 후 **"폰 저장 완료"(big.mp4) 레코드 실증**(진행→완료 전환, Report(1) 되덮어쓰기 방지 포함) |
| U4 저장소 로직 이관 | ✅ OfflineStore → Mobile.Core(디렉터리 주입, MAUI 비의존) | 재시작 매니페스트 유지 테스트 포함 |
### 명시적 미구현 (계획 허용/후순위)