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

MR7 앱·SDK 모듈별 환경과 책임

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

범위는 git show 7695c9a8:path로 읽은 추적 파일이다. 아래 책임/입출력은 코드에 나타난 컴포넌트와 호출만 요약하며, APK 설치·서명 검증·실기기 동작은 확인하지 않았다.

이 모듈에서 개발을 시작한다면

기능별 수정 위치는 DeviceAgent뿐 아니라 Launcher2·IotAgent·UpdateAgent의 실제 파일/메서드를 연결한다. 아래 표는 환경과 책임을 설명하며, 영향 범위표는 다른 모듈과의 협업 범위를 정하는 데 사용한다.

모듈 인벤토리

모듈 종류·빌드/설치 사실 매니페스트·권한/엔트리 주요 코드와 관찰된 입출력
DeviceAgent 제품 제어 앱, system UID / persistent / privileged 구성 Binder·부팅·예약 Receiver 및 WSS/Streaming Service 실행 환경과 요소 책임, 51개 Manager 책임, 정책에서 상세 설명
AMRAgent Android.mk 패키지, system/priv-app, platform 서명, private API [apps/AMRAgent/Android.mk:19-21,61-64] system shared UID, 네트워크/Wi-Fi, alert window, keystore 권한; exported AMRAgent service와 boot receiver [apps/AMRAgent/AndroidManifest.xml:3-24,26-43] AMRAgent/AMRCmdDispatcher가 IAMRControl AIDL 명령을 받아 AMR 소켓 명령·상태 모델로 변환하고 callback/상태를 반환 [apps/AMRAgent/java/com/sk/airbot/amragent/AMRAgent.java:151-164]; 세부 command/model 다수 [git tree apps/AMRAgent]
AirbotSdkProject/app Gradle 샘플 앱, compile/min/target 33/33/33 [apps/AirbotSdkProject/app/build.gradle:6-12] manifest는 application만 있고 컴포넌트/권한 없음 [apps/AirbotSdkProject/app/src/main/AndroidManifest.xml:2-15] ExampleUnitTest와 ExampleInstrumentedTest만 존재 [apps/AirbotSdkProject/app/src/test/java/com/sk/airbot/airbotsdkproject/ExampleUnitTest.java; apps/AirbotSdkProject/app/src/androidTest/java/com/sk/airbot/airbotsdkproject/ExampleInstrumentedTest.java];
AirbotSdkProject/devicecontrolapi Gradle library, min/target 28/33 [apps/AirbotSdkProject/devicecontrolapi/build.gradle:6-11] 빈 library manifest [apps/AirbotSdkProject/devicecontrolapi/src/main/AndroidManifest.xml:2-4] AIDL IDeviceControl, streaming, WSS 인터페이스와 DeviceControlProxy, Front/Remote/Proxy 구현 [apps/AirbotSdkProject/devicecontrolapi/src/main/aidl; apps/AirbotSdkProject/devicecontrolapi/src/main/java]; DeviceAgent 서비스에 대한 클라이언트 API
DeviceControlAPI Make static Java library, private API [apps/DeviceControlAPI/Android.mk:4-18] 빈 manifest [apps/DeviceControlAPI/AndroidManifest.xml:1-8] DeviceControlProxy 및 DeviceControl AIDL의 정적 라이브러리; DeviceAgent AIDL 경로를 참조 [apps/DeviceControlAPI/Android.mk:10-14]
ErrorProvider privileged package, system/priv-app; platform 인증서 주석 처리, LOCAL_PRIVILEGED_MODULE [apps/ErrorProvider/Android.mk:5-18,28] exported provider/cleanup service/boot receivers; read/write/access 자체 권한(ACCESS는 signature 또는 privileged), QUERY_ALL_PACKAGES [apps/ErrorProvider/AndroidManifest.xml:20-54] Provider가 error data CRUD 경계, cleanup/OTA upgrade receiver가 lifecycle 입력 [apps/ErrorProvider/src: tracked source tree]
EventAssetAgent Gradle app, compile/min/target 33/31/33; release signing 설정, minify [apps/EventAssetAgent/app/build.gradle:7-12,20-37] system UID, INTERNET/record audio/foreground; exported landscape UI와 RecordingAidlService, internal upload service [apps/EventAssetAgent/app/src/main/AndroidManifest.xml:3-18,27-57] RecordingAidlService, RecordingManager, camera broker client, Room DB/repository/upload service가 녹화 요청을 받아 clip/thumbnail/ticket 저장 및 업로드 [apps/EventAssetAgent/app/src/main/java/com/sk/airbot/eventassetagent: service,recording,broker,data]
ICT Gradle app, compile/min/target 33/33/33 [apps/ICT/app/build.gradle:21-27] system UID; location/Wi-Fi/network, INTERNET, kill background, battery optimization [apps/ICT/app/src/main/AndroidManifest.xml:2-17]; exported MAIN activity [apps/ICT/app/src/main/AndroidManifest.xml:26-38] QApplication, repositories(Charging/Driving/Sensor/VoiceTest), DeviceControlResolver, Ict가 UI 테스트 입력을 DeviceControl API로 보내고 결과를 UI로 반환 [apps/ICT/app/src/main/java/com/sk/airbot/ict/data; apps/ICT/app/src/main/java/com/sk/airbot/ict/server/Ict.kt:1-40]
IotAgent Make는 이미 빌드된 IotAgent.apk를 prebuilt로 system/priv-app, platform 서명 [apps/IotAgent/Android.mk:4-22]; Gradle 소스 설정 compile/min/target 33/28/33 [apps/IotAgent/app/build.gradle:21-27] system UID, 광범위 네트워크/Wi-Fi/storage/alert/foreground/cache/wakelock/broadcast 권한 [apps/IotAgent/app/src/main/AndroidManifest.xml:4-33]; non-exported boot receiver와 IIotControl service [apps/IotAgent/app/src/main/AndroidManifest.xml:47-65] IotAgent는 MQTT/AWS client와 publish/subscribe helper를 사용 [apps/IotAgent/app/src/main/java/com/sk/airbot/iotagent/IotAgent.java:66-74,123-151]. IIotControl.Stub.sendModuleCommand의 method switch가 DeviceAgent로 전달할 입력·cloud publish를 선택 [apps/IotAgent/app/src/main/java/com/sk/airbot/iotagent/IotAgent.java:406-478]; DeviceAgent callback을 method별 처리해 cloud response/event로 publish [apps/IotAgent/app/src/main/java/com/sk/airbot/iotagent/IotAgent.java:741-838]
LLMAgent Android.mk system/priv-app, platform/private API [apps/LLMAgent/Android.mk:6-8,33-35] manifest system UID, exported service/boot receiver, network/storage/overlay/foreground 등 [apps/LLMAgent/AndroidManifest.xml:1-40] LLMAgent가 ILLMControl binder callback 등록 및 sendModuleCommand를 수신 [apps/LLMAgent/java/com/sk/airbot/llmagent/LLMAgent.java:54-95]; 현재 switch에는 빈 method면 반환하는 경로 [apps/LLMAgent/java/com/sk/airbot/llmagent/LLMAgent.java:90-94]
MCUAgent Android.mk system/priv-app, platform/private API [apps/MCUAgent/Android.mk:6-8,33-35] manifest system UID, MCU service/boot receiver 권한·엔트리 [apps/MCUAgent/AndroidManifest.xml:1-40] MCUAgent, Manager, Comm, Protocol, SerialPort가 binder/명령을 serial MCU로 보내고 수신 상태를 callback [apps/MCUAgent/java: tracked source tree]
PairingAgent Make prebuilt APK, system/priv-app, platform 서명 [apps/PairingAgent/Android.mk:4-16]; Gradle source compile/min/target 33/32/33 [apps/PairingAgent/app/build.gradle:6-12] system UID; keystore, Bluetooth/BLE, location, Wi-Fi, audio, secure settings/time; exported pairing service/boot receiver 및 intent receiver [apps/PairingAgent/app/src/main/AndroidManifest.xml:2-33,50-78] PairingAgentService binder method setBluetooth 등 수신, DeviceControlProxy 연결·callback [apps/PairingAgent/app/src/main/java/com/sk/airbot/pairingagent/PairingAgentService.java:37-44,87-123,228-270]. IntentReceiver는 key/auth/reset 입력을 package 지정 broadcast로 DeviceManager/GBAS에 전달 [apps/PairingAgent/app/src/main/java/com/sk/airbot/pairingagent/intent/IntentReceiver.java:11-64]
SKMLauncher Gradle app, compile/min/target 33/25/33, release signing config [apps/SKMLauncher/app/build.gradle:22-30,52-66] system UID, INTERNET/storage/custom permission/boot; exported MAIN 및 다수 activity, boot receiver [apps/SKMLauncher/app/src/main/AndroidManifest.xml:4-15,37-117] UI launcher가 DeviceControlResolver/DeviceControlProxy를 통해 DeviceAgent 명령을 만들고, mapping/self-diagnosis에서 명시적 component로 DeviceAgent activity 실행 [apps/SKMLauncher/app/src/main/java/com/sk/airbot/skmlauncher/data/common/DeviceControlResolver.java; apps/SKMLauncher/app/src/main/java/com/sk/airbot/skmlauncher/ui/init/InitMappingCompleteFragment.java:146-149; apps/SKMLauncher/app/src/main/java/com/sk/airbot/skmlauncher/ui/manage/ManageSelfDianosisFragment.java:70-75]
SKMLauncher2 Gradle app, 동일 applicationId com.sk.airbot.skmlauncher, compile/min/target 33/28/33 [apps/SKMLauncher2/app/build.gradle:25-31]; release signing config [apps/SKMLauncher2/app/build.gradle:53-67] system UID, SET_TIME/camera/network/storage/custom/location/Wi-Fi/boot; exported MAIN 및 다수 activity와 boot receiver [apps/SKMLauncher2/app/src/main/AndroidManifest.xml:4-23,49-141] DeviceControlResolver, WSS camera broker client, UI managers/repositories가 DeviceAgent/WSS/camera broker 호출 [apps/SKMLauncher2/app/src/main/java/com/sk/airbot/skmlauncher/data/common,ui,wss]. OTP는 serial+secret 기반 검증, 5회 실패 lock [apps/SKMLauncher2/app/src/main/java/com/sk/airbot/skmlauncher/ui/manage/OtpAuthViewModel.java:31-40,84-103,195-210,218-275]
StartupService Gradle compile/min/target 34/32/34, release signing 설정; Make는 system/priv-app, platform/private API [apps/StartupService/app/build.gradle:22-28,48-53; apps/StartupService/Android.mk:11-13,33-35] system UID, privileged phone/storage/foreground/boot; exported StartupService와 boot receiver [apps/StartupService/app/src/main/AndroidManifest.xml:4-15,27-45] StartupService.onCreate가 foreground 시작 후 OTA/factory-reset preferences를 읽고 popup을 만들며 delayed handler를 등록 [apps/StartupService/app/src/main/java/com/sk/airbot/startupservice/StartupService.java:35-53,58-99]
UpdateAgent Android.mk package, system/priv-app, platform/private API, SystemUpdaterSample override [apps/UpdateAgent/Android.mk:10-14,40-44] system UID, protected ACTION_OTA_UPDATE, cache/network/storage/overlay/wakelock/broadcast; exported UI/service/prepare service/boot receiver [apps/UpdateAgent/AndroidManifest.xml:3-31,34-78] UpdateAgent binder는 callback 등록과 method OTAUpdate를 받음 [apps/UpdateAgent/java/com/sk/airbot/updateagent/UpdateAgent.java:62-109], DeviceControl callback을 받고 broadcast함 [apps/UpdateAgent/java/com/sk/airbot/updateagent/UpdateAgent.java:120-161]. UpdateManager는 UpdateEngine 비동기 상태/진행/완료 callback을 관리 [apps/UpdateAgent/java/com/sk/airbot/updateagent/UpdateManager.java:43-78]
VisionAgent Android.mk system/priv-app, platform/private API [apps/VisionAgent/Android.mk:12-14,43-45] system UID, face recognition permission, overlay; protected vision ENABLE/REPORT/REQ/STATUS broadcasts; exported Vision/Face services·boot receiver [apps/VisionAgent/AndroidManifest.xml:3-20,22-60] VisionAgent는 vision_data와 enable/request/report/status broadcast 계약을 정의하고 DeviceAgent AIDL report/status 메서드를 사용 [apps/VisionAgent/java/com/sk/airbot/visionagent/VisionAgent.java:68-100]
devicecontrolapi_test Make 테스트 APK, private API, 인증서 주석 처리 [apps/devicecontrolapi_test/Android.mk:7-18] exported MAIN MainActivity, 별도 권한 없음 [apps/devicecontrolapi_test/AndroidManifest.xml:1-19] DeviceControlAPIJavaLib를 링크하는 수동 테스트 UI [apps/devicecontrolapi_test/Android.mk:13-18; apps/devicecontrolapi_test/java/net/quber/devicecontrolapi_test/MainActivity.java]
permissions 앱이 아닌 권한 설정 디렉터리 privapp-permissions-quber_packages.xml과 생성 보조 Python 파일 packages.mk:33–35에서 XML을 system permissions에 복사. 권한별 대상은 플랫폼 문서 참고

정책 검사(코드에 실제로 보이는 것)

대상 근거와 동작
IotAgent manifest가 service/boot receiver를 exported=false로 선언하고 system UID·privileged 수준 권한을 요구한다 [apps/IotAgent/app/src/main/AndroidManifest.xml:4-33,47-65]. Binder sendModuleCommand는 null/빈 method를 반환하고 method switch로 허용된 동작을 분기한다 [apps/IotAgent/app/src/main/java/com/sk/airbot/iotagent/IotAgent.java:441-478]. 외부 intent는 UpdateAgent UI 등 대상 package/component를 명시하는 호출이 있다 [apps/IotAgent/app/src/main/java/com/sk/airbot/iotagent/IotAgent.java:1791; apps/IotAgent/app/src/main/java/com/sk/airbot/iotagent/mqtt/topic/CmdTopic.java:3653-3690].
UpdateAgent manifest에 protected OTA broadcast가 있고 service는 exported지만 별도 component permission은 없다 [apps/UpdateAgent/AndroidManifest.xml:10-11,62-75]. Binder는 callback null과 빈 method를 검사하고 OTAUpdate만 처리한다 [apps/UpdateAgent/java/com/sk/airbot/updateagent/UpdateAgent.java:71-109]. SelectActivity는 storage runtime permission을 checkSelfPermission으로 확인한다 [apps/UpdateAgent/java/com/sk/airbot/updateagent/ui/SelectActivity.java:54-107,145-155].
PairingAgent service exported=true이며 component permission 선언은 없다 [apps/PairingAgent/app/src/main/AndroidManifest.xml:50-57]. Binder는 callback null/빈 method를 검사하고 setBluetooth를 분기한다 [apps/PairingAgent/app/src/main/java/com/sk/airbot/pairingagent/PairingAgentService.java:87-123]. BLECentral은 Bluetooth Connect의 self permission을 확인한다 [apps/PairingAgent/app/src/main/java/com/sk/airbot/pairingagent/ble/BLECentral.java:303-310]. IntentReceiver는 수신 후 대상 package를 setPackage로 제한한다 [apps/PairingAgent/app/src/main/java/com/sk/airbot/pairingagent/intent/IntentReceiver.java:45-64].
SKMLauncher / 2 manifest가 자체 CUSTOM_PERMISSION을 선언·uses하지만 activity들에는 component-level permission이 없다 [apps/SKMLauncher/app/src/main/AndroidManifest.xml:4-15,37-117; apps/SKMLauncher2/app/src/main/AndroidManifest.xml:4-23,49-141]. Launcher2에는 UI OTP 정책(입력 형식/장비 serial·secret 결합, 5회 실패 lock)이 실제 코드로 존재한다 [apps/SKMLauncher2/app/src/main/java/com/sk/airbot/skmlauncher/ui/manage/OtpAuthViewModel.java:31-40,218-275]. SHA-1 helper와 PIN hash 사용도 있다 [apps/SKMLauncher2/app/src/main/java/com/sk/airbot/skmlauncher/data/common/SecurityUtil.java:11-22; apps/SKMLauncher2/app/src/main/java/com/sk/airbot/skmlauncher/ui/manage/ManageViewModel.java:179-180,253-254].

빌드·설치 환경과 확인 범위

런타임 모듈별 상태·환경 계약

Make의 prebuilt 선언과 같은 디렉터리의 Gradle 소스는 구분해야 한다. 이 소스가 제품 이미지 속 prebuilt APK와 일치하는지는 해시·빌드 이력 대조가 필요하다.

Connections

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