기기 동작 시나리오별 호출·정책·결과 연결
기준:
a1-packages-mr6,quber/mr7,7695c9a85fedf6d756490e51c07f6e09f568a4bd. 추적 소스의 정적 분석이다. 미추적 TaskManagerClient 및 작업 산출물은 포함하지 않는다. APK·AOSP 빌드나 기기 동작 검증은 이번 분석 범위가 아니다.
이 문서의 DA/는 apps/DeviceAgent/app/src/main/java/com/sk/airbot/deviceagent/다. 순서는 대표 경로를 설명하며 조건에 따른 분기를 생략하지 않는다.
시나리오를 변경할 때
시나리오 S1–S8 영향표에서 직접 수정 모듈과 연관 기능을 찾는다. 아래는 현재 동작의 근거이며, 기능별 수정 위치는 개발 작업 순서를 제시한다.
| 현재 흐름 | 변경 시작점 | 반드시 함께 분석할 경로 |
|---|---|---|
| 청정 시작 | 청정 작업표 | 예약·야간·복귀 중단 |
| 예약 도착 | 예약 작업표 | Launcher 실행 객체·Security 재판정 |
| 저전력 복귀 | 이동 작업표 | 오류 우선순위·주행 callback·선점 |
| 설정 변경 | 설정 작업표 | 저장과 즉시 적용, 세 정책 입구 |
| 보안 시작 | WSS 작업표 | 호출 역할·reason mask·녹화 |
1. 사용자가 청정을 시작할 때
| 단계 | 담당 요소 | 실제 동작·정책 | 코드 근거 |
|---|---|---|---|
| 요청 전달 | DeviceAgent Binder | Bundle.method를 추출해 MainApi로 전달 | DA/DeviceAgent.java:264–282 |
| 제품 모드 검사 | MainApi / StateManager | ICT/SELFTEST 등의 전용 처리 및 차단 목록 적용 | DA/main/api/MainApi.java:150–204 |
| 청정 요청 해석 | MainApi의 setAirCleanerOperation 분기 | action/range 등 파라미터 구성, 복귀 중 START의 선행 stop | DA/main/api/MainApi.java:523, :618–634 |
| 새 청정 허용 | CmdPolicyManager.newClean | 기존 cleanMode가 NONE이고 START일 때 호출. 거절한 이동형 청정은 IoT Failed 통지를 지연 전송 | DA/main/api/MainApi.java:636–656 |
| 기능 정책 | BaseCleaningManager.set / AirCleaningPolicy | 새 START 검사. 실제 반환값 차이는 정책표 참조 | DA/cleaning/BaseCleaningManager.java:213–258 |
| 기능 선택 | BaseCleaningManager | BASIC이면 BasicCleaningManager, 나머지는 MovingCleaningManager. 이동 위치가 비면 종료 | DA/cleaning/BaseCleaningManager.java:261–314 |
| 장치 동작 | Basic / Moving | fan·공기질 감시와 위치 이동·청정 반복을 별도 callback으로 진행 | DA/cleaning/BasicCleaningManager.java:49, DA/cleaning/MovingCleaningManager.java:31 |
| 상태·보고 | CleaningTransaction / CleaningReportManager / AppCmd | 상태와 보고서, 사용자/IoT 알림은 각 경로에서 갱신 | 청정·보고서 상세 |
여기서 sendModuleCommand의 반환값 0을 “청정 시작 성공”으로 해석하면 안 된다. MainApi의 조기 반환과 비동기 장치 명령을 구별해야 한다. 기존 청정 중의 속도 변경·STOP·PAUSE는 새 START와 정책 적용 조건이 다르다.
2. 예약 시간이 도달했을 때
ScheduleAlarmReceiver가 scheduleId로 DB를 다시 조회한다. 삭제·비활성 상태는 실행하지 않는다.- 요일/휴일/현재 시각을 검사하고 GPS 링크는 시간 조건의 예외로 처리한다. 마지막 실행 시각은 메모리 중복 억제에 사용한다.
triggerScheduleAction은 UPGRADE를 먼저 차단한다. 그 다음 mapping/privacy/night/home lock/area/보안 상태 등 일반 조건을 확인한다.- 일반 조건이 실패한 Security 예약은
canExecuteSafeCareSchedule에서 다시 판단한다. 실패 원인별 분기가 아니므로 일반 조건 전체가 절대 관문인 것처럼 도식화하지 않는다. - 허용 시
setSchedulecallback을 Launcher 쪽에 전달한다. Receiver가 여기서 곧바로 모든 동작을 수행하는 것은 아니다. - 다음 알람 재등록은 실행 요청 전달 단계와 연결돼 있다.
triggerScheduleAction은 void이므로 호출 뒤의 재등록만으로 실제 업무가 실행됐다고 판정할 수 없다.
근거: DA/schedule/ScheduleAlarmReceiver.java:71–114, :134–312, :334–374. Launcher의 실제 소비 요소는 모듈 책임 문서와 기존 Launcher 상세를 함께 본다.
3. S02 저전력 오류로 복귀할 때
배터리 측정값과 오류 이벤트는 구분한다. MainService는 AMR의 BatteryStatus를 BatteryManager에 반영한다. CmdPolicy는 raw battery 숫자를 매번 직접 비교하기보다 ErrorHandler의 LOW_BATTERY/CRITICAL_LOW_BATTERY 분류를 읽는다.
S02 오류 처리에서 이미 S03이면 복귀 예약을 생략한다. 그렇지 않으면 main handler에 3초 뒤 handleReturningByError("S02")를 게시한다. 이 함수는 CHK_OPT_IGNORE_LLM을 붙여 returnToStation을 호출한다. 복귀 함수는 공통 조건을 다시 검사하고 stopAllAction과 RobotMovementController로 연결된다. S02의 일부 오류/프라이버시 예외가 있어 단순히 “프라이버시이면 언제나 복귀 금지”라고 설명할 수 없다.
근거: DA/main/MainService.java:93–95; DA/device/manager/BatteryManager.java:195; DA/data/ErrorHandler.java:350, :721–746; DA/policy/CmdPolicyManager.java:168–170, :716–783, :841–884.
확인할 결과: 복귀 명령 전송 → 주행/도킹 상태 callback → 실제 충전 상태를 각각 구분한다. 3초 timer 만료나 명령 반환은 도킹 완료가 아니다.
4. 프라이버시·홈잠금·야간 모드를 바꿀 때
Privacy setter는 값을 정규화한 뒤 Vision stop/start, tilt 조건 재설정, property/Preferences 저장, SoundFlow mode, LLM 통지를 수행한다. 같은 설정을 이후 CmdPolicy, 예약 Receiver, WSS 정책이 각각 읽는다. 이것이 “설정 저장”과 “새 요청 판단”이 연결되는 지점이다.
Home lock은 Preferences 저장과 SoundFlow/LLM 통지를 수행하고 청정·예약·WSS 검사에서 소비된다. Night mode는 LCD·LED·volume·청정 상태와 IoT/PUI를 갱신하며 예약의 별도 차단 조건으로도 쓰인다. 설정별로 소비자가 다르므로 하나의 전역 enable 플래그로 치환해 설명할 수 없다.
근거: DA/settings/Settings.java:329–358, :433–447, :913–923; DA/policy/CmdPolicyManager.java:432; DA/schedule/ScheduleAlarmReceiver.java:146–201; DA/wss/policy/WssPolicyChecker.java:63–71.
5. 보안 모드를 시작할 때
| 단계 | 연결 | 책임 |
|---|---|---|
| Binder 호출 | WssService → WssControlStub.startWssMode | 전용 API 수신 |
| 호출자 검사 | WssPackageValidator.enforceCallerAccess | SYSTEM_UID 및 FRONT/REMOTE 역할 |
| 시작 요청 | WssManager.requestStartWssMode | 요청·상태·전용 queue 경로 관리 |
| 가용성 판단 | WssManager.checkWssAvailability → WssPolicyChecker | station basic/이동 patrol 구분, reason 비트 계산 |
| 트리거 예외 | LLM trigger 추가 처리 | 제외 reason mask와 allowed 재계산 |
| 세션 수행 | WssManager / WssTransaction / MovingWssManager / WssEventAssetManager | 보안 상태·이동·이벤트 자산을 각 담당 요소로 연결 |
| 외부 결과 | AMR / Vision / EventAsset / IoT | 이동·감지·녹화·업로드의 비동기 결과 |
근거: DA/ipc/WssControlStub.java:90–114, DA/wss/WssManager.java:520–558, DA/wss/policy/WssPolicyChecker.java:171–187; 세션 요소의 개별 근거는 Manager 책임표, 기존 WSS 상세에 있다.
reasonCodes에 오류 비트가 남았다고 곧바로 거절로 단정하지 않는다. 체크 단계가 허용 계산에서 일부 reason을 제외하며 LLM trigger에서 다시 계산할 수 있다. 실제 이동/녹화/업로드의 완료를 하나의 WSS 시작 반환값으로 합치지 않는다.
6. OTA와 일반 동작 차단
UpdateAgent의 UpdateManager는 UpdateEngine 진행·완료 경계를 담당하고, DeviceAgent OTAManager는 LLM/SoundFlow 모드 전환을 담당한다. 이름이 유사하지만 책임이 다르다. StateManager의 UPGRADE 차단, 예약 Receiver의 최우선 UPGRADE 반환, WSS의 UPGRADE reason도 각각 다른 입구의 정책이다.
근거: UpdateAgent 구성, DA/ota/OTAManager.java:8–31, DA/event/StateManager.java:149–169, DA/schedule/ScheduleAlarmReceiver.java:291–298, DA/wss/policy/WssPolicyChecker.java:142–145.
따라서 “OTA 플래그가 켜졌으니 모든 입구가 자동으로 보호된다”는 식의 설명 대신, 실제 업데이트 진입 코드에서 상태 전환과 각 입구 차단이 함께 적용되는지 추적해야 한다. 패키지 적용·재부팅 후 버전 확인은 별도 기기 검증이다.
Connections
상세 분석 목차 · 기존 전체 SVG 지도 · 정책 조건표 · 실행 시나리오