본문으로 이동
SK-INTELLIX / ENGINEERING전체 모듈 Atlas ↗

기기 정책: 판단 순서·예외·실제 반환값

기준: a1-packages-mr6, quber/mr7, 7695c9a85fedf6d756490e51c07f6e09f568a4bd. 추적 소스의 정적 분석이다. 미추적 TaskManagerClient 및 작업 산출물은 포함하지 않는다. APK·AOSP 빌드나 기기 동작 검증은 이번 분석 범위가 아니다.

모든 축약 경로 DA/는 apps/DeviceAgent/app/src/main/java/com/sk/airbot/deviceagent/다. 이 표는 제품 요구사항을 새로 제안하는 문서가 아니라 지정 커밋의 실제 분기를 설명한다.

정책을 수정할 때

정책별 적용 범위표에서 일반 명령·예약·WSS의 차이를 먼저 비교한다. 아래 조건표의 조기 반환·주석·마스킹·재허용까지 현재 동작에 포함된다. 정책 소유 파일만 수정해도 공유 소비자가 영향을 받을 수 있으므로 변경 영향 지도와 함께 검토한다.

정책은 여러 단계에 분산되어 있다

MainApi → StateManager → 해당 API 분기 → CmdPolicyManager 또는 기능별 Policy → Manager/Controller가 대표 경로다. 예약 Receiver, WSS 전용 Binder, 설정 setter에는 별도 판단과 side effect가 있다. 모든 API가 하나의 직렬 정책 파이프라인을 통과한다고 해석하면 안 된다.

정책 단계

SVG 원본 · Mermaid 원본

1. MainApi와 제품 상태

판단 지점 활성 코드의 동작 근거
재부팅 명령 UPGRADE이면 거절. 일반 메서드 차단과 별도 분기 DA/main/api/MainApi.java:159–174, DA/event/StateManager.java:110
FACTORY FactoryState로 위임하고 결과에 따라 반환 DA/main/api/MainApi.java:179–183
ICT getFirmwareVersion/setA1Version 예외 외에는 ICTState로 위임 후 반환 DA/main/api/MainApi.java:184–191
SELFTEST SelfTestState로 위임 후 반환 DA/main/api/MainApi.java:193–195
UPGRADE / VITALSIGN setAMROperation, scheduleiot, setAirCleanerOperation, airSensorDetected, setstation, setMoveTo, setConfig, getConfig, gpsLocNearBy, control 차단 DA/event/StateManager.java:149–169
STREAMING_ALPHA setAMROperation, scheduleiot, setAirCleanerOperation, airSensorDetected, setMoveTo, gpsLocNearBy 차단 DA/event/StateManager.java:170–178

setMainState/getMainState에는 별도 stateMethod 예외가 있다. isProductOperationState()와 checkBlockedStatus()는 같은 검사도, 같은 차단 목록도 아니다. 전자는 FACTORY/ICT/UPGRADE/SELFTEST를 일반 운영에서 제외하고, 후자는 특정 상태에서 특정 메서드 이름을 막는다.

2. CmdPolicyManager의 공통 판단 순서

입력은 청정 파라미터, 수행 모드 mMode, checkOption이다. 판단 전 CleaningTransaction, InterScheduleManager, RobotMovementController, MovingController, AMRService, ErrorHandler, LlmManager를 읽는다. 아래 순서에서 조기 반환하면 뒷부분은 실행되지 않는다.

순서 조건 결과·예외 근거
1 일반 제품 운영 상태가 아님 거절 DA/policy/CmdPolicyManager.java:265–275
1b 특정 모드 상태 저전력 복귀 예외가 아닐 때 VITALSIGN·MULTI_AP 설정·예약 편집·WIZARD 상태를 거절. 저전력 복귀이면 이 switch를 건너뜀 DA/policy/CmdPolicyManager.java:282–296
2 LLM 처리 중 기본 거절. IGNORE_LLM 옵션 또는 AIR_SENSOR 새 청정은 예외 DA/policy/CmdPolicyManager.java:302–313
3 오류 분류 MAJOR는 청정·이동·인터랙션 모두, MOVING_EX_S02는 이동 관련, CLEANING은 청정 관련 block 필드 설정. 일부 저전력 복귀 예외 DA/policy/CmdPolicyManager.java:172–192, :318–366
4 station 위 BASIC 새 청정 여기서 허용 반환. 뒤의 배터리·준비·편집 조건까지 통과했다는 뜻은 아님 DA/policy/CmdPolicyManager.java:371–380
5 S03 임계 저전력 거절 DA/policy/CmdPolicyManager.java:385–388
6 AMR 연결/도킹 상태 준비 안 됨 이동 성격의 모드 차단. 시뮬레이션 예외 DA/policy/CmdPolicyManager.java:393–400
7 S02 저전력 새 청정·일반 이동·예약 차단 DA/policy/CmdPolicyManager.java:405–415
8 긴급 복귀 진행 중 일반 복귀·이동·예약 차단 DA/policy/CmdPolicyManager.java:420–427
9 프라이버시 이동 성격 명령 차단. 저전력 복귀 예외 DA/policy/CmdPolicyManager.java:432–440
10 A1 초기화 미완료 거절. TempSettings의 무시 옵션 존재 DA/policy/CmdPolicyManager.java:445–450
11 지도 편집 중 거절 DA/policy/CmdPolicyManager.java:456–459
12 WSS 진행 중 로그는 남기지만 거절 return이 주석 처리됨 DA/policy/CmdPolicyManager.java:461–468

오류 분류는 if/else-if 우선순위이므로 모든 오류의 block 집합을 단순 합산하는 형태가 아니다. 실제 동시 오류 조합은 이 순서로 읽어야 한다.

기능별 후속 판단과 실행

저전력 예외는 주석보다 실행값을 우선한다

allowedLowBatteryReturnToStation_ignoreOtherCond = true다. S02 + 일반 복귀 모드이면 일부 오류·프라이버시 차단을 우회한다. 그 위의 과거 주석은 다른 조건을 체크한다고 설명하지만 현재 flag와 활성 분기는 다르다. 그렇다고 모든 차단이 무시되는 것은 아니다. 제품 상태, S03 등 별도 선행·후행 검사는 남아 있다.

근거: DA/policy/CmdPolicyManager.java:118–132, :231–239, :318, :350, :432.

3. AirCleaningPolicy: 계산값과 반환값의 차이

BaseCleaningManager.set()은 새 START일 때 getPolicy()를 호출한다. 홈 잠금이면 POLICY_BLOCKED를 조기 반환하고, capacity가 0 이하라 AMR 미연결로 취급되면 즉시 허용을 반환한다. 그 이후 station/배터리/청정 범위 분기는 mPolicy를 계산하지만 함수 마지막 반환값은 POLICY_NOT_DEFINED(-1) 이다.

호출자는 BLOCKED / STOP_AND_START / WAIT_AND_START만 구분하고 나머지 값은 즉시 시작 허용으로 처리한다. 따라서 이 함수 내부의 15% 이하 계산만 보고 “배터리 차단이 실제 적용된다”고 주장할 수 없다. 새 청정의 MainApi 경로에는 별도로 CmdPolicyManager가 있으므로 전체 시스템에 배터리 차단이 없다는 뜻도 아니다.

근거: DA/cleaning/AirCleaningPolicy.java:60–113, :120, :127–201; DA/cleaning/BaseCleaningManager.java:223–257; DA/main/api/MainApi.java:636–665.

또한 self-test 검사는 TODO이고, 청정 진행 여부는 false로 강제한다. 이전 개요의 “self/line test 검사”, “계산한 정책에 따른 stop 후 재시작” 설명은 활성 구현을 과도하게 일반화했다. 이 상세 분석이 그 부분을 정정한다.

4. 예약 정책: 일반 조건과 Security 예외

단계 판단/연결 근거
알람 수신 DB의 존재·활성 확인, 요일/휴일/시간 검사. GPS는 시간 조건 예외 DA/schedule/ScheduleAlarmReceiver.java:71–100
중복 억제 마지막 실행 시각을 메모리에 기록. 시뮬레이션 우회 DA/schedule/ScheduleAlarmReceiver.java:91–108
최우선 OTA triggerScheduleAction의 UPGRADE 검사에서 즉시 반환 DA/schedule/ScheduleAlarmReceiver.java:291–298
일반 허용 조건 mapping, privacy, station BASIC 조건, night, home lock, area 유효성, 보안 실행 여부 검사 DA/schedule/ScheduleAlarmReceiver.java:134–229
Streaming 실행 중이라고 로그를 남기지만 이 if에는 return false가 없음 DA/schedule/ScheduleAlarmReceiver.java:231–233
복귀 중 예외 복귀/도킹 중이면 CmdPolicy.schedule와 주행 priority 검사를 건너뜀 DA/schedule/ScheduleAlarmReceiver.java:235–251
Security 재판정 일반 검사가 실패해도 canExecuteSafeCareSchedule가 true면 진행 DA/schedule/ScheduleAlarmReceiver.java:256–312
전달 setSchedule Bundle을 Main callback으로 송신 DA/schedule/ScheduleAlarmReceiver.java:334–349

Security 재판정은 실패 원인을 전달받지 않는다. 따라서 “특정 일반 조건만 예외”라고 축소해서 설명하면 부정확하다. S02+station, 편집 모드, 일부 동작 진행 상태 등의 허용 분기에 들어가면 일반 검사 실패 뒤에도 Launcher 전달 단계로 진행할 수 있다. 이후 WSS 자체 정책과 실제 시작은 별도로 확인해야 한다.

5. WSS 정책과 호출자 권한

일반 명령 정책과 별도로, WSS Binder는 SYSTEM_UID와 FRONT/REMOTE 역할을 API마다 확인한다. 이것은 “누가 호출 가능한가”의 정책이고 WssPolicyChecker는 “현재 기기가 실행 가능한가”의 정책이다.

WssPolicyChecker는 camera/tilting error, privacy, home lock, PIN, 로컬 네트워크와 AWS 상태, 구독 상태, 배터리 오류를 reason bit에 누적한다. 이동형은 map/주행 오류를 추가하고 follow-me/vital/LLM/upgrade/self-test 상태도 검사한다.

근거: DA/ipc/WssControlStub.java:90–114; DA/wss/policy/WssPackageValidator.java:58–109; DA/wss/policy/WssPolicyChecker.java:48–167.

반환 해석: basic과 patrol 모두 허용 여부 계산에서 배터리 reason 두 개를 마스킹한다. reasonCodes에는 비트가 남아 있으므로 allowed=true와 battery reason이 공존할 수 있다. LLM trigger는 WssManager에서 추가 reason을 제외하고 허용 여부를 다시 계산하며 station 상태에 따른 예외도 있다. 단계별 boolean/reasonCodes를 함께 봐야 한다.

근거: DA/wss/policy/WssPolicyChecker.java:171–187; DA/wss/WssManager.java:520–558.

6. 설정 정책은 저장과 부수 동작으로 연결된다

설정 setter의 동작 소비 정책
Privacy Vision stop/start, tilt 조건 reset, system property·Preferences 저장, SoundFlow mode, LLM 통지 CmdPolicy 이동 검사, 예약, WSS
Home lock Preferences 저장, SoundFlow LOCK mode, LLM 통지 AirCleaningPolicy, 예약, WSS
Night 활성 값 저장, LCD/LED, 청정 ghost mode, volume refresh, IoT/PUI 갱신. 해제 시 calibration 호출 예약 차단 및 표시·청정 동작

근거: DA/settings/Settings.java:329–358, :433–447, :913–923.

설정 API 반환은 카메라/마이크/장치의 실제 정지 확인과 같은 의미가 아니다. 각 서비스 반영 callback·기기 로그가 있어야 완료를 판단할 수 있다.

7. OTA 입장 조건: IotAgent의 요청 유형별 차이

IotAgent.onDownloadUpdateAgent(downloadurl, jobid)는 jobid가 비어 있지 않은 요청에만 다음 조건을 검사한다. station에 없거나 배터리가 30% 미만이면 실패하고, vital sign·STREAMING·PATROL_SECURITY/FIXED_SECURITY 중에도 FAILED 사유를 반환한다. 빈 jobid는 주석상 Samba/local 요청이며 이 검사 블록을 건너뛴다. 따라서 “OTA는 항상 station과 배터리 조건을 검사한다”는 설명은 이 함수의 실제 분기와 다르다.

통과 후 mRobotStatus_update=true와 상태 송신을 수행하고 com.sk.airbot.updateagent/.ui.MainActivity를 명시적으로 실행한다. Intent에는 PATH, MODE=local, jobid, downloadurl을 전달한다. 다운로드·UpdateEngine 완료는 이 입장 판정과 별도다.

근거: apps/IotAgent/app/src/main/java/com/sk/airbot/iotagent/IotAgent.java:1748–1795.

Connections

상세 분석 목차 · 기존 전체 SVG 지도 · 정책 조건표 · 실행 시나리오