Vision 카메라 — 서비스 내부 세션과 기존 앱의 경계
개요
카메라 사용 허가의 수명을 Vision 서비스가 소유하도록 만드는 단계다. 기존의 STREAM 공유·EXCLUSIVE 단독 사용 규칙은 보존하고, 누가 받은 허가인지, 서비스가 복구된 뒤에도 유효한지, 한 번만 반환되는지를 검사한다. 실제 카메라 열기·닫기나 영상 수신을 이번 내부 구현과 혼동하지 않는다.
코드 85d4984의 내부 구현과 검증을 설명한다. 제품 요청 경로의 전환 완료 문서가 아니다.
전체 구조 안에서의 위치
위 그림의 Vision · 카메라가 이 문서의 범위다. TaskManager는 여전히
server/execution/task/의 공통 작업 관리자다. 카메라 세션을 TaskManager로
옮기거나 Vision 안에 별도 TaskManager를 만드는 변경이 아니다.
| 폴더 / 구성요소 | 역할 | 이번 범위 밖 |
|---|---|---|
base/core/java/.../manager/SkixCameraManager |
기존 앱의 요청·반환·조회 API | 새 공개 Binder 연결 |
apps/DeviceAgent/.../domain/camera/CameraCommandHandler |
기존 제품 요청을 처리하는 static 정책 소유자 | 새 내부 세션으로 제품 요청 전환 |
services/core/.../domain/vision/VisionManagerService |
Vision 서비스 수명과 내부 카메라 세션 소유 | 기본 Runtime의 자동 활성화 |
domain/vision/session/CameraSessionService |
사용 허가 발급·검사·반환 및 복구 후 무효화 | 하드웨어 열기·닫기, 공통 자원 반환 |
domain/vision/policy/CameraAccessPolicy |
STREAM 공유와 EXCLUSIVE 승인 규칙 | 물리 카메라 사용 종료 증명 |
control/lifecycle/ServiceLifecycleSupervisor |
서비스 상태와 상태 전이 순번의 정본 | 영상 프레임·브로커 생존의 정본 |
기존 경로와 새 내부 서비스는 서로 다른 정책 인스턴스다. 같은 물리 카메라에 대해 두 경로를 동시에 권한자로 활성화하면 안 된다. 제품 연결 때 기존 handler를 단일 서비스 권한자로 연결하는 어댑터로 바꿔야 하며, 지금은 기존 앱 동작을 유지한다.
요청부터 종료까지
- 서비스 등록소가 Vision을 시작한다.
onStart시점은 STARTING이므로 아직 요청을 받지 않는다. - READY 상태가 되면 내부 세션 요청을 받을 수 있다. 승인된 요청마다 별도 불투명 세션을 발급한다.
- 세션은 정확한 서비스 인스턴스·소유자·READY 상태 순번에 귀속된다. 문자열 owner만 알아서는 다른 세션을 반환할 수 없다.
- 반환은 한 번만 성공한다. 오류 보고는 자기 유효 세션으로만 가능하며 허가를 자동 반환하지 않는다.
- 상태가 READY를 벗어나거나 전이 순번이 달라지면 이전 세션을 정리한다. 복구 중에 조회가 한 번도 없어도 다음 연산에서 이전 세션을 인정하지 않는다.
onStop은 최종 종료다. 다시 시작하려면 새 등록소·수명 관리자·서비스 인스턴스를 사용한다. 숫자 순번이 같아도 이전 인스턴스의 세션은 거부한다.
세션 검사와 변경은 세션 잠금 → 공통 수명 잠금 순서로 함께 처리한다. 따라서 동시에 들어온 단독 사용 요청이나 반환·종료가 내부 상태를 엇갈리게 바꾸지 않는다. 이 잠금 안에서는 외부 호출이나 하드웨어 I/O를 하지 않는다.
상태를 읽는 방법
| 값 / 규칙 | 의미 |
|---|---|
accepting |
이 시점에 서비스가 요청을 받을 수 있는가 |
| AVAILABLE / SHARED / EXCLUSIVE / ERROR | 내부 접근 정책의 논리 상태. 물리 카메라가 FREE라는 뜻이 아님 |
activeClients |
사용 중인 서로 다른 소유자 수 |
activeSessions |
아직 반환되지 않은 승인 요청 수. 같은 소유자가 여러 번 요청할 수 있음 |
| 같은 소유자의 STREAM·EXCLUSIVE 혼용 | 기존 정책처럼 마지막 참조가 반환될 때까지 단독 사용 권한을 유지 |
| 거부 사유 | 준비 안 됨·잘못된 입력·충돌·다른 서비스·이전 세대·다른 소유자·이미 반환됨을 타입으로 구분 |
상태 조회 결과는 불변 스냅샷이다. 조회 후 현재 상태가 바뀌어도 과거 결과는 바뀌지 않는다. 허가 결과는 승인 순간의 논리적 판정이지 계속 유지되는 물리 접근권 보증이 아니다.
검증
코드 85d4984의 격리된 정본 소스로 전체 빌드 작업 98개를 다시 실행했다.
- 신규 Vision 세션 계약 16개·등록소 수명 3개, 총 19개 통과.
- 전체 서버 655개·SDK 62개 테스트: 실패·오류·건너뜀 0. 프레임워크 release APK 생성 성공.
- 기존 DeviceAgent 22개 테스트와 debug APK 생성 성공, 빌드 작업 38개 전부 실행.
- 기본 Runtime 7개와 기존 정책·SDK·DeviceAgent 소스 경계는 유지했다. 미완 LLM/TTS 변경은 격리·보존했다.
- 전체 현황 SVG는 378개 요소의 좌표·구조를 유지하고 Vision 문구 3곳만 바꿨다.
실기기 카메라·브로커 재시작·제품 부팅·공개 IPC는 별도 검증 대상이다.
남은 제품 연결
- 기존 handler와 브로커 상태 수신의 단일 권한자 전환 및 계약 상수 적용.
- 실제 브로커·직접 카메라 접근자·원본 관측의 수명과 세션 연결.
- 공유 STREAM 구독과 물리 CAMERA 자원 점유를 구분한 공통 자원 계약.
- 공개 Manager/Binder·권한·제품 부팅 조립. 기본 Runtime 7개에 Vision을 자동 추가하지 않는다.