← Docs hub

DeviceAgent Task Executor Wiring Wiki

Task Executor Wiring 구조

1. 목적

이 문서는 TaskExecutorBootstrap에 등록된 skeleton executor를 실제 DeviceAgent 제어 로직과 연결하는 구현 지침이다.

대상 파일:

2. 현재 skeleton 등록 상태

TaskExecutorBootstrap.registerSkeletonExecutors(boolean dryRun)는 다음 method를 등록한다.

Executor taskMethod
MovementTaskExecutor returnToStation, setMoveTo, setMoving, stopMovement
CleaningAmpTaskExecutor setAirCleanerOperation, setStatusClean, stopCleaning, ampStop
LlmTtsTaskExecutor setChangeLlmStatus, setLlmTts, stopLlm, stopTts
IotTaskExecutor setDeviceStatus, setConfig, getConfig
UpdateTaskExecutor OTAUpdateArmResult, OTAUpdateMcuResult, setFirmwareUpdateStatus

현재 TaskModuleExecutor.execute(...)dryRun이면 응답만 쓰고, 아니면 UnsupportedOperationException을 던진다. 따라서 제품 동작으로 쓰려면 반드시 wiring 구현이 필요하다.

3. Bootstrap 위치

DeviceAgent.onCreate()에서 MainCommon.set(...) 이후 등록한다.

MainCommon.set(...);
TaskExecutorBootstrap.registerSkeletonExecutors(false);

개발 중에는 다음 중 하나로 dry-run 검증이 가능하다.

TaskExecutorBootstrap.registerSkeletonExecutors(true);

또는 호출 Bundle에 다음을 넣는다.

indata.putBoolean("executorDryRun", true);

4. TaskModuleExecutor 변경 방향

권장 구조:

abstract class TaskModuleExecutor implements TaskExecutorRegistry.TaskExecutor {
    @Override
    public final void execute(Bundle indata, Bundle outdata) {
        String method = indata == null ? "" : indata.getString("method", "");
        if (dryRun || (indata != null && indata.getBoolean("executorDryRun", false))) {
            writeDryRunResult(method, outdata);
            return;
        }
        executeWired(method, indata, outdata);
    }

    protected abstract void executeWired(String method, Bundle indata, Bundle outdata);
}

공통 응답 필드:

key type 의미
executorWired boolean 실제 wiring 실행 여부
executorDomain String movement, cleaning_amp, llm_tts, iot, update
taskMethod String 실행한 method
accepted boolean 기존 제어 로직에 명령 접수 성공 여부
reason String 실패/거부 사유
errorCode String framework error code 또는 task error code

5. MovementTaskExecutor 연결

taskMethod 연결 대상 주의
returnToStation CmdPolicyManager.INSTANCE.returnToStation(...) 또는 FrameworkCommandBridge.tryHandle(...) 명령 접수와 도착 완료를 분리
setMoveTo CmdPolicyManager.INSTANCE.setMoveTo(Position, isAirSensor, isAppCall) positionIdMapManager로 resolve 필요
setMoving CmdPolicyManager.INSTANCE.setDeviceStatus(...) 기존 function/action 계약 유지
stopMovement RobotMovementController.getInstance().stopCurrentMove(true) cancel task와 연결

setMoveTo는 최소 다음 입력 중 하나를 지원해야 한다.

입력 처리
positionId MapManager에서 Area 조회 후 Position 생성
poiId, poiName, x, y, degree 직접 Area/Position 생성
positionIds workflow 또는 순차 이동으로 확장

6. CleaningAmpTaskExecutor 연결

taskMethod 연결 대상 후보 비고
setAirCleanerOperation CleanOperationCommandHandler.handleSetAirCleanerOperation(...) 또는 기존 MainApi 로직 분리 신규 handler가 있으면 handler 우선
setStatusClean CleanStatusCommandHandler.handleSetStatusClean(...) 청정 상태 변경
stopCleaning 기존 청정 stop/cancel 로직 adapter화 cancel 계약 필요
ampStop AMP/청정 관련 stop 로직 명령 정의 확인 필요

DeviceControlService.sendModuleCommand(...)로 자기 자신에게 다시 Binder 호출하는 방식은 피한다. TaskExecutor 안에서 self-call을 하면 MainApi.executeMethod -> TaskManager -> Executor -> MainApi 재진입이 발생할 수 있다.

7. LlmTtsTaskExecutor 연결

taskMethod 연결 대상 입력
setChangeLlmStatus LlmManager.INSTANCE.setChangeStatus(newStatus) newStatus
stopLlm setChangeStatus(CMD_STOP_TTS) 또는 별도 stop 정의 정책 확정 필요
stopTts setChangeStatus(CMD_STOP_TTS) newStatus=3 기본
setLlmTts LlmManager.INSTANCE.setTts(tts) tts

setLlmTts 완료 기준은 명령 전달 완료인지, TTS playback 완료인지 기획 정의가 필요하다.

8. IotTaskExecutor 연결

taskMethod 연결 대상 비고
setDeviceStatus CmdPolicyManager.INSTANCE.setDeviceStatus(indata) IoT/LLM/app 제어 공통 진입
setConfig ConfigCommandHandler.handleSetConfig(indata) framework command 패키지 사용 가능
getConfig ConfigCommandHandler.handleGetConfiguration(outdata) 조회는 direct 가능

IoT publish가 필요한 command는 AppCmd.INSTANCE.sendModuleCommand_iot(...) 호출 여부를 command별로 확정해야 한다.

9. UpdateTaskExecutor 연결

taskMethod 연결 대상 주의
setFirmwareUpdateStatus 기존 MainApi의 MCU OTA branch를 adapter로 분리 startMcuOta_hidl(...) 접근성 문제
OTAUpdateArmResult 기존 MainApi branch adapter화 ARM->MCU->SOC 단계 전이
OTAUpdateMcuResult 기존 MainApi branch adapter화 recovery 실패/성공 처리

Update는 MainApi private 메서드와 필드에 의존하므로, 단순 executor 직접 호출보다 UpdateCommandAdapter를 별도 생성하는 것이 안전하다.

10. 구현 완료 기준