Files
tdc114plus/docs/review_android_physical_device_transition_2026-07-08.md

9.4 KiB

Android 공기계 로컬 USB 테스트 전환 검토

작성일: 2026-07-08 상태: 검토 완료

1. 목적

기존 Windows Android Studio emulator + WSL/Docker Flutter 기반 테스트는 유지하되, 앞으로의 기본 수동/통합 테스트 경로를 "집에서 가져온 Android 공기계 + 로컬 PC USB 연결" 방식으로 전환할 수 있는지 검토한다.

이번 검토의 범위는 아래와 같다.

  • 현재 저장소에서 emulator 전용 가정이 어디에 있는지 확인
  • 공기계 연결 방식으로 바꿀 때 유지 가능한 코드와 추가 필요한 보강점을 구분
  • 실제 전환 시 가장 작은 변경 경로를 제안

2. 결론 요약

  • 앱 코드 자체는 공기계 테스트로 전환 가능한 구조다. 실행 시점에 TDC114_API_BASE--dart-define으로 주입하는 방식이라 target만 안정적으로 잡히면 emulator와 device를 공용으로 사용할 수 있다.
  • 현재 가장 강하게 emulator에 묶여 있는 부분은 앱 로직이 아니라 운영 스크립트와 문서다.
  • 공기계 전환의 핵심 이점은 Windows emulator portproxy, Docker local ADB, remote ADB server, VM service dynamic port 문제를 대부분 피할 수 있다는 점이다.
  • 다만 실기기에서는 emulator 전용 주소 10.0.2.2를 쓸 수 없고, 로컬 HTTP 접근은 Android cleartext 정책에 막힐 가능성이 높다.
  • 따라서 "기존 emulator 코드는 유지"하면서도, 앞으로는 실기기용 env/체크 스크립트/실행 절차를 별도로 추가하는 방식이 가장 안전하다.

3. 현재 코드/스크립트 구조에서 확인한 사항

3.1 target 선택 자체는 이미 공용화되어 있음

  • scripts/integration_tests.sh
    • TDC114_FLUTTER_DEVICE_ID 또는 TDC114_ADB_CONNECT_ADDRESS가 있으면 해당 target으로 실행한다.
    • 즉, Flutter가 실기기를 인식하기만 하면 integration test 명령 자체는 재사용 가능하다.
  • scripts/manual-postlogin-run.sh
    • TDC114_FLUTTER_DEVICE_ID 또는 TDC114_ADB_CONNECT_ADDRESS 기반으로 flutter run -d <device>를 실행한다.
    • 수동 점검 경로도 공기계 전환에 재사용 가능하다.
  • scripts/flutter-docker.sh
    • ADB_SERVER_SOCKET, TDC114_ADB_CONNECT_ADDRESS를 Docker에 전달한다.
    • 구조상 device 연결 경로도 수용할 수 있다.

3.2 실제로는 preflight와 운영 정책이 emulator 기준임

  • scripts/check-android-emulator-env.sh
    • 이름부터 emulator 전용이다.
    • Windows Android Studio, Device Manager, portproxy, emulator GUI 복구 절차를 전제로 한다.
  • scripts/startup.sh
    • 기본 Android precheck 스크립트가 check-android-emulator-env.sh로 고정돼 있다.
  • 문서 다수
    • docs/checklist_morning_startup_runtime_2026-07-03.md
    • docs/policy_android_studio_wsl_adb_2026-07-03.md
    • docs/scenario_android_emulator_device_integration_test_2026-07-03.md
    • 위 문서들은 현재 운영 중심축이 emulator임을 보여준다.

3.3 emulator 전용 API 주소 가정이 남아 있음

  • scripts/integration_tests.sh
    • bootstrap용 base URL에서 10.0.2.2 -> 127.0.0.1 치환을 수행한다.
  • scripts/manual-postlogin-run.sh
    • 동일하게 10.0.2.2 -> 127.0.0.1 치환을 수행한다.
  • 문서 전반
    • emulator env는 TDC114_API_BASE=http://10.0.2.2:5000을 표준으로 본다.

이 부분은 "실기기에서 무엇을 쓸지"만 정하면 큰 문제는 아니다. 실기기는 아래 둘 중 하나면 된다.

  • adb reverse tcp:5000 tcp:5000http://127.0.0.1:5000
  • 같은 LAN에서 http://<PC_LAN_IP>:5000

4. 공기계 전환 시 기대 효과

4.1 사라지거나 크게 줄어드는 문제

  • Windows emulator GUI 상태 의존
  • 5037 ADB server 공유 문제
  • 5555/5557/5559 같은 emulator adbd portproxy 관리
  • Docker 내부 local ADB key와 Windows ADB key 불일치
  • remote Windows ADB server가 만든 VM service dynamic port가 Docker localhost와 어긋나는 문제

즉, 지금까지 반복된 문제의 상당수는 "앱" 문제가 아니라 "Windows emulator를 WSL/Docker Flutter에서 원격으로 다루는 구조"에서 생겼다. USB 실기기는 이 복잡도를 상당히 낮춘다.

4.2 새로 관리해야 하는 문제

  • 공기계의 USB 디버깅/RSA 승인 상태
  • adb reverse 재설정 필요 여부
  • 단말과 PC가 같은 네트워크인지 여부(LAN IP 방식일 때)
  • Android의 cleartext HTTP 허용 여부

5. 가장 중요한 기술 리스크

5.1 Android cleartext HTTP 차단 가능성

현재 app/android/app/src/main/AndroidManifest.xml에는 아래가 없다.

  • android:usesCleartextTraffic="true"
  • debug용 network_security_config

로컬 Baron API는 현재 문서와 스크립트 기준으로 주로 http://127.0.0.1:5000, http://10.0.2.2:5000, http://<PC_LAN_IP>:5000를 사용한다. 실기기에서 debug APK를 띄웠을 때 Android 버전에 따라 cleartext가 차단될 수 있다.

따라서 공기계 전환 전에 가장 먼저 확인할 항목은 이것이다.

  1. 공기계에서 flutter run --dart-define=TDC114_API_BASE=http://127.0.0.1:5000 또는 LAN IP로 실행
  2. 로그인/디렉토리 API 호출이 실제로 되는지 확인
  3. 차단되면 debug 전용 cleartext 허용 설정 추가

5.2 adb reverse와 Docker 컨테이너 내부 ADB의 관계

실기기에서 가장 단순한 API 접근 방식은 adb reverse tcp:5000 tcp:5000이다. 다만 현재 테스트 명령은 scripts/flutter-docker.sh를 통해 Docker 컨테이너 안에서 실행되는 경우가 많다.

검토 시점 기준으로 확인된 점:

  • flutter drive/flutter run은 Docker 내부에서 수행된다.
  • adb reverse를 누가 실행하느냐에 따라 적용 대상이 달라질 수 있다.

따라서 실무상 가장 안전한 기준은 아래 순서다.

  1. 먼저 Windows 또는 WSL host에서 adb devices로 공기계가 device 상태인지 확인
  2. 같은 ADB 경로에서 adb reverse tcp:5000 tcp:5000 실행
  3. 이후 Docker Flutter가 동일 device를 보는지 확인

만약 Docker 내부 ADB와 host ADB가 서로 다른 서버/세션을 쓰면 adb reverse가 예상대로 먹지 않을 수 있다. 그 경우에는 LAN IP 방식을 백업 경로로 잡는 것이 안전하다.

6. 변경 영향 검토

6.1 그대로 재사용 가능한 것

  • app/ 내부 Dart 앱 코드 대부분
  • app/integration_test/app_smoke_test.dart
  • app/test_driver/integration_driver.dart
  • scripts/api-smoke.sh
  • scripts/check-baron-api-env.sh
  • scripts/integration_tests.sh의 기본 실행 구조
  • scripts/manual-postlogin-run.sh의 post-login seed 구조

6.2 공기계 기준으로 별도 추가하는 편이 좋은 것

  • 실기기 전용 env 예시
    • scripts/.env.android-device.local는 이미 문서상 가정만 있고 tracked example은 부족하다.
  • 실기기 preflight 스크립트
    • 예: scripts/check-android-device-env.sh
  • 실기기 실행 가이드 문서
    • USB 디버깅, RSA 승인, adb reverse, LAN IP fallback 포함

6.3 나중에 일반화하면 좋은 것

  • check-android-emulator-env.sh를 유지한 채, 상위 래퍼 check-android-target-env.sh를 만들어
    • TDC114_ANDROID_TARGET_KIND=emulator|device
    • 또는 env 유무 기준으로 분기
  • startup.sh에서 precheck script를 교체 가능하게 유지하되, 기본 정책 문구를 "Android target" 기준으로 일반화

7. 권장 전환 방식

기존 emulator 코드는 그대로 두고 아래 순서로 가는 것을 권장한다.

  1. 이번 테스트까지만 기존 emulator 경로 사용
  2. 그 다음부터는 공기계를 기본 target으로 사용
  3. 초기에는 manual-postlogin-run.sh 중심으로 수동 기능점검부터 안정화
  4. 그 다음 integration_tests.sh를 공기계 target으로 재사용
  5. 충분히 안정화된 뒤에만 startup.sh 기본 Android precheck를 실기기 기준으로 확장

8. 최소 실행 초안

8.1 공기계 수동 점검

# 1) 공기계 USB 연결 후 host에서 device 확인
adb devices

# 2) reverse 방식 선택 시
adb reverse tcp:5000 tcp:5000

# 3) 실기기용 env 준비
# scripts/.env.android-device.local
TDC114_API_BASE=http://127.0.0.1:5000
TDC114_SMOKE_PHONE=010xxxxxxxx

# 4) 앱 실행
TDC114_SMOKE_ENV_FILE=scripts/.env.android-device.local \
TDC114_FLUTTER_DEVICE_ID=<physical_device_id> \
./scripts/manual-postlogin-run.sh

8.2 공기계 integration test

TDC114_SMOKE_ENV_FILE=scripts/.env.android-device.local \
TDC114_FLUTTER_DEVICE_ID=<physical_device_id> \
./scripts/integration_tests.sh

LAN IP 방식을 쓰는 경우 env의 TDC114_API_BASEhttp://<PC_LAN_IP>:5000로 바꾼다.

9. 최종 판단

공기계 전환은 타당하다. 현재 막힌 문제의 대부분은 emulator 자체보다도 "Windows emulator + WSL/Docker Flutter + 원격 ADB/portproxy" 조합에서 발생했다.

따라서 다음 기본 방침은 합리적이다.

  • emulator 경로는 보존
  • 앞으로의 기본 테스트는 공기계 USB 연결 방식으로 전환
  • 초기 목표는 "수동 post-login 점검 안정화"
  • 그 다음 "integration_tests.sh 공기계 재사용"

단, 실전 전환 전에 반드시 먼저 확인할 항목은 아래 2개다.

  1. 공기계에서 local HTTP API가 cleartext 차단 없이 실제 호출되는가
  2. adb reverse가 Docker Flutter 실행 경로에서도 안정적으로 유지되는가

이 2개가 통과하면 emulator 대비 운영 복잡도는 확실히 낮아질 가능성이 높다.