TaskManagerClient AAR API Specification
이 페이지는 외부 System App이 DeviceAgent TaskManager를 사용할 때 참조하는 AAR API 명세다. 내부 Bundle 계약 전체는 DeviceAgent TaskManager API Contract를 기준으로 하고, 이 문서는 앱 개발자가 실제로 호출할 Java facade를 정리한다.
IoT/MQTT도 같은 field 의미를 사용한다. MQTT request.task 계약은 MQTT Task Contract를 기준으로 한다.
기준 소스:
~/work/1.A1_SoC_new/SoC/a1-packages-mr6/apps/TaskManagerClient
~/work/1.A1_SoC_new/SoC/a1-packages-mr6/apps/DeviceAgent/app/src/main/java/com/sk/airbot/deviceagent/task/TaskManager.java
~/work/1.A1_SoC_new/SoC/a1-packages-mr6/apps/DeviceAgent/app/src/main/java/com/sk/airbot/deviceagent/task/TaskPolicyRegistry.java
~/work/1.A1_SoC_new/SoC/a1-packages-mr6/apps/DeviceAgent/app/src/main/java/com/sk/airbot/deviceagent/task/TaskExecutorBootstrap.java
1. 역할
TaskManagerClient는 아래 호출 흐름의 앞단 facade다.
System App
-> TaskManagerClient
-> DeviceControlProxy.connect()
-> IDeviceControl.sendModuleCommand(indata, outdata)
-> DeviceAgent.MainApi.executeMethod()
-> TaskManager.handleControlMethod()
-> submitTask / submitWorkflow / query / cancel
System App은 method=submitTask, taskMethod=setMoveTo, subTasks=... 같은 Bundle 키를 직접 조립하지 않고 builder를 사용한다.
2. AAR 빌드
cd ~/work/1.A1_SoC_new/SoC/a1-packages/apps/TaskManagerClient
ANDROID_HOME=/home/silogood/Android/Sdk ANDROID_SDK_ROOT=/home/silogood/Android/Sdk \
../ICT/gradlew :taskmanagerclient:testDebugUnitTest :taskmanagerclient:assembleDebug
산출물:
apps/TaskManagerClient/taskmanagerclient/build/outputs/aar/taskmanagerclient-debug.aar
apps/TaskManagerClient/taskmanagerclient/build/outputs/aar/taskmanagerclient-release.aar
3. Connection API
TaskManagerClient client = new TaskManagerClient(context, "com.example.SystemApp");
client.connect(new TaskManagerClientCallback() {
@Override public void onConnected() {}
@Override public void onDisconnected() {}
@Override public void onTaskEvent(Bundle event) {}
});
onTaskEvent는 DeviceAgent TaskManager.notifyTaskEvent(...)가 만든 method=onTaskEvent Bundle이다.
4. 지원 API 전체
| Java API | DeviceAgent method | 설명 |
|---|---|---|
submitTask(TaskSubmitRequest) |
submitTask |
단일 task 등록 |
submitCloudDeviceTask(Bundle, source) |
submitTask |
Cloud/음성 Agent의 device_task_requests[]를 TaskManager task로 변환 등록 |
submitWorkflow(TaskWorkflowRequest) |
submitWorkflow |
순차/병렬 workflow 등록 |
scheduleTask(TaskSubmitRequest, trigger) |
scheduleTask |
단일 task 예약 record 등록 |
scheduleWorkflow(TaskWorkflowRequest, trigger) |
scheduleWorkflow |
순차/병렬 workflow 예약 record 등록 |
getScheduledTasks(state, source, limit) |
getScheduledTasks |
예약 record 목록 조회 |
cancelScheduledTask(scheduleId, reason) |
cancelScheduledTask |
실행 전 예약 record 취소 |
runDueScheduledTasks(nowMs, limit) |
runDueScheduledTasks |
due 예약 record admission |
runDueScheduledTask(scheduleId, nowMs) |
runDueScheduledTasks |
특정 예약 record admission |
getTaskStatus(taskId) |
getTaskStatus |
task 상세 조회 |
listTasks() |
listTasks |
최근 task 목록 조회 |
listTasks(state, queue, source, includeFinished, limit) |
listTasks |
필터 조회 |
getQueueStatus(queue) |
getQueueStatus |
queue running/pending 상태 조회 |
updateTaskProgress(taskId, progress, stage, message) |
updateTaskProgress |
외부 executor/proxy 진행률 갱신 |
cancelTask(taskId, reason) |
cancelTask |
특정 task 취소 |
clearPendingTasks(queue) |
clearPendingTasks |
queue의 pending task 비우기 |
cancelQueue(queue, includeRunning, reason) |
cancelQueue |
queue 단위 취소 |
getManagerStatus() |
getTaskManagerStatus |
enabled, metric, resource snapshot 조회 |
getDevicePlanningContext() |
getDevicePlanningContext |
plan 전 기기 context 조회 |
classifyIngress(taskMethod, params) |
classifyTaskIngress |
명령 성격 분류 |
sendRaw(Bundle) |
raw | 신규/임시 method 직접 호출 |
4.1 자동완성용 Public Constants
AAR은 SDK 사용자에게 문자열을 직접 입력하게 하지 않기 위해 아래 constants 클래스를 제공한다.
| Constants class | 용도 |
|---|---|
TaskMethods |
setMoveTo, returnToStation, startBasicAirClear, scheduleiot, interSchedule 등 task method |
TaskSources |
APP, IOT, PUI, VOICE, CLOUD, INTERNAL 등 source |
TaskParams |
positionId, areaId, cleanMinTimeMs, scheduleId, action, status, text, color 등 parameter key |
TaskQueues |
movement, cleaning, ai, routine, schedule, interaction, workflow 등 queue |
TaskCompletionTargets |
movement.arrived, cleaning.stopped, interaction.completed 등 완료 판단 target |
TaskExecutionModes |
direct, queued_wait, async |
TaskPriorities |
BACKGROUND, NORMAL, CONTROL, HIGH, EMERGENCY |
TaskPreemptPolicies |
append, clear_pending, replace_queue 등 선점 정책 |
TaskFailurePolicies |
fail_parent, partial_success, continue_on_failure |
TaskStates |
PENDING, RUNNING, COMPLETED, FAILED, CANCELLED |
TaskEvents |
STARTED, PROGRESS, WORKFLOW_STEP_STARTED, COMPLETED 등 event name |
TaskSignalTypes |
COMMAND_TASK, TASK_CONTROL, SENSOR_DATA 등 ingress 분류 |
TaskCleanActions / TaskCleanModes |
청정 action/mode 값 |
TaskScheduleTypes |
schedule type code. 예: interaction/welcome schedule |
TaskScheduleActionCodes |
interaction schedule action code |
TaskScheduleCommands |
scheduleiot command. 예: add, update, remove |
TaskInteractionScheduleActions |
interSchedule action. 예: start/stop/pause/resume/return |
TaskInteractionScheduleStatuses |
InterScheduleManager status code. 예: started/arrived/actionStarted/completed |
TaskSupportedCommands |
실제 policy/executor로 연결된 기능별 task catalog |
TaskRequestFields / TaskResultFields |
raw Bundle을 직접 다룰 때 쓰는 key |
TaskSupportedCommands는 외부 System App이나 테스트 UI가 “현재 TaskManager로 실제 보낼 수 있는 명령” 목록을 구성할 때 사용한다. 예: TaskSupportedCommands.MOVEMENT, TaskSupportedCommands.CLEANING, TaskSupportedCommands.SCHEDULE, TaskSupportedCommands.INTERACTION.
4.2 AAR / MQTT Field 동일성
외부 System App은 AAR builder를 사용하고, IoT/MQTT는 JSON envelope를 사용하지만 TaskManager가 해석하는 의미는 같아야 한다.
| 의미 | AAR / Bundle | MQTT |
|---|---|---|
| 실행할 기존 method | TaskMethods.*, taskMethod |
request.method 또는 payload.subTasks[].taskMethod |
| 호출 source | TaskSources.IOT, source=iot |
IotAgent가 고정 주입 |
| 추적 ID | requestId, traceId, correlationId |
correlationId |
| 기능 parameter | TaskParams.* |
request.payload.* |
| 실행 방식 | TaskExecutionModes.*, executionMode |
request.task.executionMode |
| queue | TaskQueues.*, queueKey |
request.task.queueKey |
| priority | TaskPriorities.*, priority |
request.task.priority |
| timeout | timeoutMs |
request.task.timeoutMs |
| 완료 기준 | TaskCompletionTargets.*, completionTarget |
request.task.completionTarget |
| 선점 정책 | TaskPreemptPolicies.*, preemptPolicy |
request.task.preemptPolicy |
| Cloud workflow 추적 | cloud_workflow_id, cloud_step_id, cloud_plan_id, cloud_output_key |
request.task.* 또는 Cloud device_task_requests[] |
| Cloud 개입 정책 | wait_policy, requires_cloud_decision |
request.task.wait_policy, task event payload |
MQTT에서 request.task가 생략되면 기존 DeviceAgent direct command로 유지한다. TaskManager에 등록하려면 request.task object를 명시한다. request.task: {}처럼 비어 있어도 TaskManager intent로 보고, 누락된 정책은 DeviceAgent TaskPolicyRegistry의 method별 기본 정책을 적용한다. request.task.managed=false는 task-like method라도 direct로 유지한다.
4.3 Cloud/Voice Agent Task Request Adapter
Cloud LLM Agent나 온디바이스 voice bridge가 Cloud 응답의 orchestration.device_task_requests[]를 그대로 받는 경우에는 CloudDeviceTaskRequestAdapter를 사용한다.
{
"taskMethod": "setAirCleanerOperation",
"executionMode": "async",
"contract_version": "a2a-task-orchestration-v1",
"cloud_workflow_id": "wf_voice_001",
"cloud_step_id": "step_clean_bedroom",
"cloud_plan_id": "plan_clean_house",
"cloud_output_key": "clean_result",
"wait_policy": "submitted",
"params": {
"action": "1",
"mode": "2",
"speed": "0",
"positionName": "안방"
}
}
TaskResult result = client.submitCloudDeviceTask(cloudTaskRequest, TaskSources.VOICE);
변환 결과는 method=submitTask, forceTaskManager=true, source=VOICE, taskMethod=<원래 method>이며, params 내부 값은 DeviceAgent executor가 읽을 수 있도록 Bundle 최상위로 flatten된다. cloud_workflow_id, cloud_step_id, cloud_plan_id, cloud_output_key, wait_policy는 submit 결과와 task event에 보존되어 Cloud Agent가 다음 step, cancel, replan을 판단할 수 있다.
관련 전체 흐름은 Voice Agent To SoC TaskManager Closed Loop를 참조한다.
4.4 Constants 상세 Catalog
아래 catalog는 apps/TaskManagerClient/taskmanagerclient/src/main/java/com/sk/airbot/taskmanagerclient의 public constants 기준이다. 외부 System App과 테스트 앱은 raw 문자열 대신 이 constants를 import해서 사용한다.
Control method
TaskManagerClient:
METHOD_SUBMIT_TASK=submitTask
METHOD_SUBMIT_WORKFLOW=submitWorkflow
METHOD_GET_TASK_STATUS=getTaskStatus
METHOD_LIST_TASKS=listTasks
METHOD_GET_QUEUE_STATUS=getQueueStatus
METHOD_UPDATE_TASK_PROGRESS=updateTaskProgress
METHOD_CANCEL_TASK=cancelTask
METHOD_CLEAR_PENDING_TASKS=clearPendingTasks
METHOD_CANCEL_QUEUE=cancelQueue
METHOD_GET_MANAGER_STATUS=getTaskManagerStatus
METHOD_GET_DEVICE_PLANNING_CONTEXT=getDevicePlanningContext
METHOD_CLASSIFY_INGRESS=classifyTaskIngress
Task method
TaskMethods:
GET_BATTERY_INFO=getBatteryInfo
GET_FIRMWARE_VERSION=getFirmwareVersion
GET_MAIN_STATE=getMainState
GET_DEVICE_STATUS=getDeviceStatus
GET_CONFIGURATION=getConfiguration
GET_AIR_CLEANER_OPERATION=getAirCleanerOperation
SET_MAIN_STATE=setMainState
SET_DEVICE_STATUS=setDeviceStatus
SET_LAUNCHER_SCREEN=setLauncherScreen
SET_MOVE_TO=setMoveTo
RETURN_TO_STATION=returnToStation
SET_MOVING=setMoving
STOP_MOVEMENT=stopMovement
SET_AIR_CLEANER_OPERATION=setAirCleanerOperation
SET_STATUS_CLEAN=setStatusClean
STOP_CLEANING=stopCleaning
AMP_STOP=ampStop
START_SIMPLE_AIR_CLEAR=startSimpleAirClear
START_BASIC_AIR_CLEAR=startBasicAirClear
START_FIXED_AIR_CLEAR=startFixedAirClear
START_ALL_AIR_CLEAR=startAllAirClear
START_SELECTIVE_AIR_CLEAR=startSelectiveAirClear
START_AIR_SENSOR_AIR_CLEAR=startAirSensorAirClear
STOP_AIR_CLEAR=stopAirClear
PAUSE_AIR_CLEAR=pauseAirClear
RESUME_AIR_CLEAR=resumeAirClear
RETURN_AIR_CLEAR_TO_STATION=returnAirClearToStation
RETURN_CLEANING_TO_STATION=returnCleaningToStation
SET_CHANGE_LLM_STATUS=setChangeLlmStatus
SET_LLM_TTS=setLlmTts
STOP_LLM=stopLlm
STOP_TTS=stopTts
SET_CONFIG=setConfig
GET_CONFIG=getConfig
SET_EYE_LED_COLOR=setEyeLedColor
SET_CURRENT_PUI_EYE_LED_COLOR=setCurrentPuiEyeLedColor
START_EYE_LED_SCENE=startEyeLedScene
ADD_SCHEDULE=addSchedule
EDIT_SCHEDULE=editSchedule
DELETE_SCHEDULE=deleteSchedule
SCHEDULE_IOT=scheduleiot
SET_ACTIVE_SCHEDULE=setActiveSchedule
PUI_EDIT_SCHEDULE=puiEditSchedule
CALL_SCHEDULE=callschedule
GET_SCHEDULE=getschedule
GET_UPCOMING_SCHEDULE=getUpComingSchedule
SET_SCHEDULE_EXECUTED=setScheduleExecuted
GPS_LOC_NEAR_BY=gpsLocNearBy
INTER_SCHEDULE=interSchedule
OTA_UPDATE_ARM_RESULT=OTAUpdateArmResult
OTA_UPDATE_MCU_RESULT=OTAUpdateMcuResult
SET_FIRMWARE_UPDATE_STATUS=setFirmwareUpdateStatus
Task parameter key
TaskParams:
POSITION_ID=positionId
POSITION_NAME=positionName
POSITION=position
POSITION_IDS=positionIds
AREA_ID=areaId
ROOM_ID=roomId
ROOM_NAME=roomName
TARGET_ROOM=targetRoom
SPACE_NAME=spaceName
POI_ID=poiId
POI_NAME=poiName
X=x
Y=y
DEGREE=degree
ACTION=action
MODE=mode
SPEED=speed
AI=ai
CLEAN_MIN_TIME_MS=cleanMinTimeMs
CUR_DESTINATION=cur_destination
TEXT=text
TTS=tts
TTS_TEXT=ttsText
MESSAGE=message
STATUS=status
VALUE=value
KEY=key
CONFIG_KEY=configKey
NAME=name
COLOR=color
SCENE=scene
SCREEN_NAME=screenName
SCREEN=screen
TARGET_SCREEN=targetScreen
EVENT_STATUS=eventStatus
EVENT_PARAM=eventParam
SCHEDULE_ID=scheduleId
SCHEDULE_ID_SNAKE=schedule_id
SCHEDULE_ID_LOWER=scheduleid
SCHEDULE_TYPE_CODE=scheduleTypeCode
START_TIME=startTime
END_TIME=endTime
SCANNING_CLEAN=scanningClean
MONDAY_YN=mondayYn
TUESDAY_YN=tuesdayYn
WEDNESDAY_YN=wednesdayYn
THURSDAY_YN=thursdayYn
FRIDAY_YN=fridayYn
SATURDAY_YN=saturdayYn
SUNDAY_YN=sundayYn
CLEAN_TYPE_CODE=cleanTypeCode
WIND_TYPE_CODE=windTypeCode
IS_ACTIVE=isActive
IS_ACTIVE_SNAKE=is_active
COMMAND=command
TYPE=type
SCHEDULE=schedule
SCHEDULE_LIST=scheduleList
SCHEDULE_TASK_LIST=scheduleTaskList
ACTION_CODE=actionCode
MAP_ID=mapId
THETA=theta
ACTION_PARAMS=actionParams
PARAM_KEY=paramKey
PARAM_VALUE=paramValue
GPS_YN=gpsYn
MUSIC_DURATION=musicDuration
MUSIC_ID=musicId
IS_EXECUTED=isExecuted
UPCOMING_SCHEDULE=upcomingSchedule
Request/result key
TaskRequestFields:
METHOD=method
FORCE_TASK_MANAGER=forceTaskManager
TASK_METHOD=taskMethod
WORKFLOW_NAME=workflowName
SUB_TASKS=subTasks
SOURCE=source
REQUEST_ID=requestId
TRACE_ID=traceId
QUEUE=queue
PRIORITY=priority
EXECUTION_MODE=executionMode
TIMEOUT_MS=timeoutMs
COMPLETION_TARGET=completionTarget
COMPLETION_TIMEOUT_MS=completionTimeoutMs
COMPLETION_STABLE_MS=completionStableMs
STRICT_VALIDATION=strictValidation
PREEMPT_POLICY=preemptPolicy
CANCELLABLE=cancellable
STATE_AWARE=stateAware
CANCEL_METHOD=cancelMethod
COMPENSATION_METHOD=compensationMethod
REQUIRE_MAIN_STATE=requireMainState
CHECK_BLOCKED_STATUS=checkBlockedStatus
BYPASS_CALLER_POLICY=bypassCallerPolicy
RESOURCE_POLICY_ENABLED=resourcePolicyEnabled
TASK_ID=taskId
STATE=state
INCLUDE_FINISHED=includeFinished
LIMIT=limit
PROGRESS=progress
STAGE=stage
MESSAGE=message
INCLUDE_RUNNING=includeRunning
SIGNAL_TYPE=signalType
TARGET_METHOD=targetMethod
TYPE=type
GROUP_ID=groupId
JOIN_POLICY=joinPolicy
FAILURE_POLICY=failurePolicy
TASKS=tasks
TaskResultFields:
ACCEPTED=accepted
UPDATED=updated
TASK_ID=taskId
TASK_ID_SNAKE=task_id
TASK_METHOD=taskMethod
TASK_METHOD_SNAKE=task_method
TASK_QUEUE=taskQueue
TASK_STATE=taskState
STATUS=status
EXECUTION_MODE=executionMode
PRIORITY=priority
SOURCE=source
CANCELLABLE=cancellable
RETRY_COUNT=retryCount
PROGRESS=progress
STAGE=stage
MESSAGE=message
CURRENT_STEP_INDEX=currentStepIndex
CURRENT_STEP_METHOD=currentStepMethod
WORKFLOW_NAME=workflowName
TASK_ERROR_CODE=taskErrorCode
ERROR_CODE=errorCode
TASK_REASON=taskReason
REASON=reason
REASON_CODE=reasonCode
REASON_CODE_SNAKE=reason_code
RECOVERABILITY=recoverability
SUGGESTED_ACTION=suggestedAction
SUGGESTED_ACTION_SNAKE=suggested_action
REQUIRES_CLOUD_DECISION=requiresCloudDecision
REQUIRES_CLOUD_DECISION_SNAKE=requires_cloud_decision
RESULT=result
TASKS=tasks
QUEUES=queues
SUB_TASKS=subTasks
SUB_TASK_STATES=subTaskStates
EVENT_NAME=eventName
값 상수
TaskSources: VOICE, APP, SCHEDULE, SENSOR, CLOUD, IOT, PUI, ONDEVICE, API, AUTONOMOUS, INTERNAL
TaskQueues: emergency, movement, cleaning, state, update, sound, settings, ai, routine, schedule, interaction, workflow, default
TaskExecutionModes: direct, queued_wait, async
TaskPriorities: BACKGROUND, NORMAL, CONTROL, HIGH, EMERGENCY
TaskPreemptPolicies: append, clear_pending, cancel_running, replace_queue, replace_all
TaskFailurePolicies: fail_parent, partial_success, continue_on_failure
TaskStates: PENDING, RUNNING, CANCELLING, COMPLETED, FAILED, PARTIAL_FAILED, CANCELLED
TaskEvents: STARTED, PROGRESS, COMPLETED, FAILED, CANCELLED, WORKFLOW_STEP_STARTED, WORKFLOW_STEP_COMPLETED
TaskSignalTypes: COMMAND_TASK, TASK_CONTROL, PROGRESS_UPDATE, RESULT_UPDATE, SENSOR_DATA, TRIGGER, EVENT_CALLBACK, UNKNOWN
TaskParallelTypes: parallelGroup, parallelChild
TaskCompletionTargets: movement.arrived, movement.stationCharging, cleaning.started, cleaning.stopped, cleaning.stepComplete, cleaning.reportDone, interaction.started, interaction.arrived, interaction.actionStarted, interaction.actionEnded, interaction.returning, interaction.completed
TaskCleanActions: STOP=0, START=1, PAUSE=2, RESUME=3, RETURN_TO_STATION=4
TaskCleanModes: BASIC=0, ALL=1, SELECTIVE=2, AIR_SENSOR=3
TaskScheduleTypes: HOME_ARRIVED=1, GO_OUT=2, MEAL=3, WELCOME=4, WAKEUP=5, RELAX=6, CLEAN=7, AIR_QUALITY_MAP=8
TaskScheduleActionCodes: BASIC=11, WELCOME_WEATHER=12, WELCOME_CLEAN=13, WAKEUP_WEATHER=14, WAKEUP_BASIC=15, RELAX=16
TaskScheduleCommands: ADD=add, UPDATE=update, REMOVE=remove
TaskInteractionScheduleActions: STOP=0, START=1, PAUSE=2, RESUME=3, RETURN_TO_STATION=4, PLAYER_PAUSE=112, PLAYER_RESUME=113
TaskInteractionScheduleStatuses: START_MOVE=0, ARRIVED=1, PERSON_DETECTED=2, START_ACTION=3, END_ACTION=4, RETURN=5, RETURNING=6, DOCKING=7, CHARGING=8
지원 명령 catalog
TaskSupportedCommands:
| 범주 | constants |
|---|---|
DEVICE_INFO |
GET_BATTERY_INFO, GET_FIRMWARE_VERSION |
STATE |
GET_MAIN_STATE, GET_DEVICE_STATUS, SET_MAIN_STATE, SET_DEVICE_STATUS, SET_LAUNCHER_SCREEN |
MOVEMENT |
SET_MOVE_TO, RETURN_TO_STATION, SET_MOVING, STOP_MOVEMENT |
CLEANING |
GET_AIR_CLEANER_OPERATION, SET_AIR_CLEANER_OPERATION, SET_STATUS_CLEAN, START_SIMPLE_AIR_CLEAR, START_BASIC_AIR_CLEAR, START_FIXED_AIR_CLEAR, START_ALL_AIR_CLEAR, START_SELECTIVE_AIR_CLEAR, START_AIR_SENSOR_AIR_CLEAR, STOP_AIR_CLEAR, PAUSE_AIR_CLEAR, RESUME_AIR_CLEAR, RETURN_AIR_CLEAR_TO_STATION, RETURN_CLEANING_TO_STATION, STOP_CLEANING, AMP_STOP |
AI |
SET_CHANGE_LLM_STATUS, SET_LLM_TTS, STOP_LLM, STOP_TTS |
SETTINGS |
SET_CONFIG, GET_CONFIG, GET_CONFIGURATION |
ROUTINE |
SET_EYE_LED_COLOR, SET_CURRENT_PUI_EYE_LED_COLOR, START_EYE_LED_SCENE |
SCHEDULE |
ADD_SCHEDULE, EDIT_SCHEDULE, DELETE_SCHEDULE, SCHEDULE_IOT, SET_ACTIVE_SCHEDULE, PUI_EDIT_SCHEDULE, CALL_SCHEDULE, GET_SCHEDULE, GET_UPCOMING_SCHEDULE, SET_SCHEDULE_EXECUTED, GPS_LOC_NEAR_BY |
INTERACTION |
INTER_SCHEDULE |
UPDATE |
OTA_UPDATE_ARM_RESULT, OTA_UPDATE_MCU_RESULT, SET_FIRMWARE_UPDATE_STATUS |
CONTROL |
METHOD_CANCEL_TASK, METHOD_CLEAR_PENDING_TASKS, METHOD_CANCEL_QUEUE |
DeviceAgent 내부 구현용 constants
DeviceAgent 내부에도 외부 public API와 별도로 package-private constants를 둔다.
apps/DeviceAgent/app/src/main/java/com/sk/airbot/deviceagent/task/TaskMethods.java
apps/DeviceAgent/app/src/main/java/com/sk/airbot/deviceagent/task/TaskFields.java
TaskMethods는 TaskPolicyRegistry, TaskBundleValidator, TaskExecutorBootstrap, executor 구현에서 같은 method 문자열을 공유한다. TaskFields는 method, taskMethod, taskAlias, action, mode, status, command, scheduleId, scheduleid, schedule_id, isActive, is_active, taskQueue, queue, source, requestId, traceId, message, tts, text, ttsText 같은 Bundle key를 공유한다.
5. 단일 Task 예시
TaskResult result = client.submitTask(
TaskSubmitRequest.builder(TaskMethods.SET_MOVE_TO)
.source(TaskSources.APP)
.requestId("move-bedroom-001")
.putString(TaskParams.POSITION_ID, "안방")
.timeoutMs(120_000)
.build()
);
생성 Bundle:
method=submitTask
forceTaskManager=true
taskMethod=setMoveTo
source=APP
positionId=안방
timeoutMs=120000
6. Workflow 예시
TaskWorkflowRequest request = TaskWorkflowRequest.builder("bedroom_livingroom_clean_return")
.source(TaskSources.APP)
.preemptPolicy(TaskPreemptPolicies.REPLACE_QUEUE)
.addStep(TaskStep.builder(TaskMethods.SET_MOVE_TO)
.putString(TaskParams.POSITION_ID, "안방")
.timeoutMs(120_000)
.build())
.addStep(TaskStep.builder(TaskMethods.START_BASIC_AIR_CLEAR)
.putString(TaskParams.AREA_ID, "안방")
.putString(TaskParams.CLEAN_MIN_TIME_MS, "600000")
.completionTarget(TaskCompletionTargets.CLEANING_STOPPED)
.timeoutMs(900_000)
.build())
.addStep(TaskStep.builder(TaskMethods.SET_MOVE_TO)
.putString(TaskParams.POSITION_ID, "거실")
.timeoutMs(120_000)
.build())
.addStep(TaskStep.builder(TaskMethods.START_BASIC_AIR_CLEAR)
.putString(TaskParams.AREA_ID, "거실")
.putString(TaskParams.CLEAN_MIN_TIME_MS, "600000")
.completionTarget(TaskCompletionTargets.CLEANING_STOPPED)
.timeoutMs(900_000)
.build())
.addStep(TaskStep.builder(TaskMethods.RETURN_TO_STATION)
.timeoutMs(180_000)
.build())
.build();
TaskResult result = client.submitWorkflow(request);
7. 병렬 Step 예시
TaskWorkflowRequest request = TaskWorkflowRequest.builder("routine_parallel")
.source(TaskSources.APP)
.addParallelGroup(TaskQueues.ROUTINE, TaskFailurePolicies.PARTIAL_SUCCESS,
TaskStep.builder(TaskMethods.SET_EYE_LED_COLOR)
.putString(TaskParams.COLOR, "blue")
.build(),
TaskStep.builder(TaskMethods.SET_LLM_TTS)
.putString(TaskParams.TEXT, "테스트 중입니다")
.build())
.build();
parallelGroup은 type=parallelGroup, groupId, failurePolicy, tasks를 가진 subTask다.
| failurePolicy | 의미 |
|---|---|
fail_parent |
child 실패 시 workflow 실패 |
partial_success |
parent를 PARTIAL_FAILED로 기록 |
continue_on_failure |
실패를 기록하고 다음 step 진행 |
8. Builder 공통 필드
| Builder | Bundle key | 설명 |
|---|---|---|
source(String) |
source |
APP, IOT, PUI, VOICE, CLOUD, INTERNAL 등 |
requestId(String) |
requestId |
호출자 요청 ID |
traceId(String) |
traceId |
E2E trace ID |
queueKey(String) |
queue |
TaskManager queue override |
priority(String/int) |
priority |
BACKGROUND, NORMAL, CONTROL, HIGH, EMERGENCY |
executionMode(String) |
executionMode |
direct, queued_wait, async |
timeoutMs(long) |
timeoutMs |
task timeout |
preemptPolicy(String) |
preemptPolicy |
기존 task 정리 정책 |
strictValidation(boolean) |
strictValidation |
schema validation 강제 |
cancellable(boolean) |
cancellable |
취소 가능 override |
stateAware(boolean) |
stateAware |
상태 조건 적용 |
cancelMethod(String) |
cancelMethod |
취소 lifecycle method |
compensationMethod(String) |
compensationMethod |
실패 보상 method |
resourcePolicyEnabled(boolean) |
resourcePolicyEnabled |
resource admission 적용 |
9. completionTarget 판단
completionTarget은 모든 task에 넣지 않는다. executor가 기본 완료 기준을 알고 있으면 생략한다.
| Task | 판단 기준 | 입력 |
|---|---|---|
setMoveTo |
movement.arrived + 이동 idle |
생략 |
returnToStation |
movement.stationCharging |
생략 |
| 청정 시작/정지 | cleaning.stopped, cleaning.reportDone 등 목적별 |
필요 시 지정 |
| LED/TTS/설정류 | 즉발/짧은 executor 완료 | 보통 생략 |
| 조회류 | 직접 응답 | 생략 |
| 인터랙션 스케줄 시작 | interaction.completed |
기본값. 중간 상태 관측은 interaction.started, interaction.arrived, interaction.actionStarted, interaction.actionEnded, interaction.returning 지정 가능 |
지원 target:
movement.arrived
movement.stationCharging
cleaning.started
cleaning.stopped
cleaning.stepComplete
cleaning.reportDone
interaction.started
interaction.arrived
interaction.actionStarted
interaction.actionEnded
interaction.returning
interaction.completed
9.1 예약 Task/Workflow API
scheduleTask와 scheduleWorkflow는 제품 스케줄 등록 API가 아니라, 외부 orchestrator가 만든 일회성 task/workflow를 “나중에 실행할 의도”로 저장하는 TaskManager runtime API다. Client는 scheduleKind=deferred_task를 자동으로 넣고, 등록 시점에는 executor를 호출하지 않고 SCHEDULED record만 저장한다.
| schedule kind | owner | TaskManager schedule API |
|---|---|---|
TaskScheduleKinds.DEFERRED_TASK |
DeviceAgent TaskManager | 허용 |
TaskScheduleKinds.NATIVE_PRODUCT |
제품 ScheduleManager | 거부 |
TaskScheduleKinds.EVENT_CONTINUATION |
active workflow dependency | 거부 |
Bundle trigger = new Bundle();
trigger.putLong("triggerAtMs", 1893456000000L);
TaskWorkflowRequest request = TaskWorkflowRequest.builder("night_clean_return")
.source(TaskSources.CLOUD)
.addStep(TaskStep.builder(TaskMethods.SET_MOVE_TO)
.putString(TaskParams.POSITION_ID, "공간4")
.build())
.addStep(TaskStep.builder(TaskMethods.START_BASIC_AIR_CLEAR)
.putString(TaskParams.AREA_ID, "공간4")
.completionTarget(TaskCompletionTargets.CLEANING_STOPPED)
.build())
.addStep(TaskStep.builder(TaskMethods.RETURN_TO_STATION).build())
.putBoolean(TaskRequestFields.REQUIRE_FRESH_DEVICE_CONTEXT, true)
.putBoolean(TaskRequestFields.BLOCK_WHEN_TASK_MANAGER_BUSY, true)
.putBoolean(TaskRequestFields.REQUIRES_CLOUD_DECISION, true)
.putLong(TaskRequestFields.MISSED_RUN_GRACE_MS, 1800000L)
.build();
TaskResult scheduled = client.scheduleWorkflow(request, trigger);
due 시점에는 아래 API가 기존 submitTask 또는 submitWorkflow 경로로 재진입시킨다.
TaskResult admitted = client.runDueScheduledTasks(System.currentTimeMillis(), 20);
TaskResult one = client.runDueScheduledTask("scheduled-1", System.currentTimeMillis());
주요 정책:
scheduleKind=deferred_task: TaskManager 지연 실행 소유권을 명시한다.requireFreshDeviceContext=true: admission 직전admissionDeviceContext를 포함한다.blockWhenTaskManagerBusy=true: queue가 busy면BLOCKED(reason=TASK_MANAGER_BUSY)로 보류한다.requires_cloud_decision=true: blocked 결과에 Cloud/A2A replan 필요 신호를 보존한다.missedRunGraceMs:nowMs - triggerAtMs가 grace를 넘으면 실행하지 않고missed_run_expired로 보류한다.
상대 시간 요청은 등록 시점에 triggerAtMs로 확정하고 원래 지연값은
relativeDelayMs로 보존할 수 있다. 반복 규칙은 제품 scheduler 계약을 사용한다.
9.1.1 A2A handoff 상태
Cloud SCH는 schedule_execution_payload.schedule_kind를 생성하고, case-2 응답은
이 payload를 on-device까지 보존한다. On-device ScheduleExecutionPayload도
scheduleKind를 읽는다.
다만 AAR client가 owner를 추론하지는 않는다. 호출자는 아래를 완료한 뒤 API를 선택해야 한다.
native_product는 제품 ScheduleManager API로 보낸다.deferred_task는 상대 시간을 절대triggerAtMs로 확정하고 이 절의scheduleTask또는scheduleWorkflow를 호출한다.event_continuation은 schedule API에 넣지 않고 active workflow의 completion dependency로 유지한다.
현재 MR6은 잘못된 owner가 TaskManager에 저장되는 것을 거부한다. 범용 capability-to-task 변환과 실기기 exact-alarm 검증은 on-device integration의 남은 release gate다.
10. Task 기능 분류
| 범주 | 대표 taskMethod | queue | executor |
|---|---|---|---|
| 상태/정보 | getBatteryInfo, getFirmwareVersion, getMainState, getDeviceStatus |
device_info, state |
FrameworkTaskExecutor |
| 이동 | setMoveTo, returnToStation, setMoving, stopMovement |
movement |
MovementTaskExecutor |
| 청정 | getAirCleanerOperation, setAirCleanerOperation, setStatusClean, startBasicAirClear, stopAirClear, ampStop |
cleaning |
FrameworkTaskExecutor, CleaningAmpTaskExecutor |
| LLM/TTS | setChangeLlmStatus, setLlmTts, stopLlm, stopTts |
ai |
LlmTtsTaskExecutor |
| 화면/IoT/설정 | setDeviceStatus, setLauncherScreen, setConfig, getConfig, getConfiguration |
state, settings |
FrameworkTaskExecutor, IotTaskExecutor |
| PUI/루틴 | setEyeLedColor, setCurrentPuiEyeLedColor, startEyeLedScene |
routine |
RoutineTaskExecutor |
| 스케줄 | addSchedule, editSchedule, deleteSchedule, scheduleiot, setActiveSchedule, getschedule |
schedule |
ScheduleTaskExecutor |
| 인터랙션 스케줄 실행 | interSchedule |
interaction |
ScheduleTaskExecutor + InterScheduleManager |
| 업데이트 | OTAUpdateArmResult, OTAUpdateMcuResult, setFirmwareUpdateStatus |
update |
UpdateTaskExecutor |
10.1 Interaction Schedule 등록/실행 예시
인터랙션 스케줄은 두 흐름을 분리한다.
scheduleiot또는addSchedule로 스케줄 데이터를 등록/수정한다.- 시스템이 실제 수행 시점에
interSchedule(action=1, scheduleId=...)를 TaskManager에 등록한다.
즉 UI나 예약 엔진이 실제 인터랙션 스케줄을 수행할 때는 interSchedule이 interaction queue에 들어가고, 완료 판정은 InterScheduleManager의 상태 callback을 TaskCompletionStateStore가 interaction.completed로 변환한 뒤 TaskManager가 받는다.
TaskResult register = client.submitTask(
TaskSubmitRequest.builder(TaskMethods.SCHEDULE_IOT)
.source(TaskSources.IOT)
.queueKey(TaskQueues.SCHEDULE)
.requestId("schedule-register-901001")
.putString(TaskParams.COMMAND, TaskScheduleCommands.ADD)
.putString(TaskParams.SCHEDULE_ID, "901001")
.putString(TaskParams.SCHEDULE_TYPE_CODE, TaskScheduleTypes.WELCOME)
.putString(TaskParams.IS_ACTIVE, "false")
.build()
);
TaskResult run = client.submitTask(
TaskSubmitRequest.builder(TaskMethods.INTER_SCHEDULE)
.source(TaskSources.SCHEDULE)
.queueKey(TaskQueues.INTERACTION)
.requestId("interaction-run-901001")
.putString(TaskParams.ACTION, TaskInteractionScheduleActions.START)
.putString(TaskParams.SCHEDULE_ID, "901001")
.completionTarget(TaskCompletionTargets.INTERACTION_COMPLETED)
.timeoutMs(1_200_000)
.build()
);
실행 Bundle 핵심:
method=submitTask
forceTaskManager=true
taskMethod=interSchedule
source=SCHEDULE
queue=interaction
action=1
scheduleId=901001
completionTarget=interaction.completed
timeoutMs=1200000
11. Air Clear Alias
아래 alias는 DeviceAgent 내부에서 taskMethod=setAirCleanerOperation으로 변환된다.
| Alias | action | mode |
|---|---|---|
startSimpleAirClear |
1 |
0 |
startBasicAirClear |
1 |
0 |
startFixedAirClear |
1 |
0 |
startAllAirClear |
1 |
1 |
startSelectiveAirClear |
1 |
2 |
startAirSensorAirClear |
1 |
3 |
stopAirClear |
0 |
유지 |
pauseAirClear |
2 |
유지 |
resumeAirClear |
3 |
유지 |
returnAirClearToStation |
4 |
유지 |
returnCleaningToStation |
4 |
유지 |
12. 운영 제어
client.cancelTask(taskId, "user_cancel");
client.clearPendingTasks(TaskQueues.MOVEMENT);
client.cancelQueue(TaskQueues.WORKFLOW, true, "replace_flow");
client.updateTaskProgress(taskId, 40, "movement_completion_wait", "안방 이동 중");
clearPendingTasks와 cancelQueue의 queue key는 movement, cleaning, state, update, sound, settings, ai, routine, workflow, default 중 하나를 사용한다.
13. 결과 해석
TaskResult는 outdata를 감싸는 얇은 결과 객체다.
boolean accepted = result.isAccepted();
String taskId = result.getTaskId();
String state = result.getState();
String errorCode = result.getErrorCode();
Bundle raw = result.getData();
Task summary 핵심 필드:
taskId / task_id
taskMethod / task_method
taskQueue
taskState / status
executionMode
priority
source
cancellable
retryCount
progress
stage
message
currentStepIndex
currentStepMethod
workflowName
taskErrorCode
taskReason
reason_code / reasonCode
recoverability
suggested_action / suggestedAction
requires_cloud_decision / requiresCloudDecision
14. 현재 검증
현재 AAR 검증 명령:
ANDROID_HOME=/home/silogood/Android/Sdk ANDROID_SDK_ROOT=/home/silogood/Android/Sdk \
../ICT/gradlew :taskmanagerclient:testDebugUnitTest :taskmanagerclient:assembleDebug
검증 결과:
BUILD SUCCESSFUL
검증 범위:
submitTaskBundle 생성submitWorkflow+subTasksBundle 생성parallelGroupBundle 생성- AIDL 포함 AAR 빌드