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

MR7 제품 구성·네이티브·권한 환경

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

제품 포함 및 빌드/설치

packages.mk는 LOCAL_USED_AIRBOT_PACKAGES_PREBUILT != n 및 LOCAL_USED_AIRBOT_PACKAGES == y 조건 안에서만 동작한다(1–6행). 이 조건이 참이면 BOARD_SEPOLICY_DIRS += $(TOP)/vendor/quber/packages/sepolicy를 추가하고(6행), ethernetagent, logwriter, AMRAgent, DeviceAgent, ErrorProvider, ICT, IotAgent, StartupService, PairingAgent, SmartFactory, SKMLauncher, UpdateAgent, VisionAgent를 PRODUCT_PACKAGES에 넣는다(12–25행). LOCAL_USED_AIRBOT_FOR_HQA == y일 때만 HQA가 추가된다(27–30행). privileged permission XML은 system etc에 privapp-permissions-quber_packages_1.xml로 복사된다(33–35행). 근거: packages.mk:1-37.

루트, apps, service, libs의 Android.mk는 all-subdir-makefiles를 재귀 include한다(각 Android.mk:1). 실제 선언은 다음과 같다.

모듈 선언/설치 사실 근거
DeviceAgent Java package DeviceAgent, /system/priv-app, platform cert, private platform APIs, AIDL 및 Java 전체 apps/DeviceAgent/app/src/main/Android.mk:15-61
AMRAgent Java package /system/priv-app, platform cert, private APIs, AIDL/Java, vendor device-manager Java/HAL 의존 apps/AMRAgent/Android.mk:16-64
IotAgent prebuilt IotAgent.apk, APPS, platform cert, /system/priv-app, ProGuard disabled apps/IotAgent/Android.mk:1-20
LLMAgent, MCUAgent Java package, /system/priv-app, platform cert/private APIs, AIDL/Java apps/LLMAgent/Android.mk:1-35, apps/MCUAgent/Android.mk:1-35
PairingAgent prebuilt PairingAgent.apk, platform cert, /system/priv-app apps/PairingAgent/Android.mk:1-15
ErrorProvider /system/priv-app, privileged module/private APIs; certificate assignment commented out apps/ErrorProvider/Android.mk:5-26
StartupService Java package /system/priv-app, platform cert/private APIs, manifest and Java sources apps/StartupService/Android.mk:8-35
UpdateAgent Java package /system/priv-app, platform cert/private APIs, AIDL/Java/assets apps/UpdateAgent/Android.mk:7-40
VisionAgent Java package /system/priv-app, platform cert/private APIs, AIDL/Java, facerecognize-sdk apps/VisionAgent/Android.mk:7-43
DeviceControlAPIJavaLib static Java library; imports DeviceAgent AIDL apps/DeviceControlAPI/Android.mk:1-18
devicecontrolapi_test test package; certificate line commented apps/devicecontrolapi_test/Android.mk:1-18
libserial_port prebuilt shared library, both ABIs, /system/lib and /system/lib64 libs/serial_port/Android.mk:1-14
ethernetagent, logwriter native executables, LOCAL_INIT_RC, BUILD_EXECUTABLE service/ethernetagent/Android.mk:1-29, service/logwriter/Android.mk:1-32
a1_decrypt prebuilt executable and external init rc service/decrypt/Android.mk:1-10

a1_decrypt의 실제 바이너리와 rc는 ../../../prebuilts/packages/decrypt/...를 가리키므로 현재 저장소 스냅샷의 service/decrypt만으로 내용/실행 조건은 알 수 없다(service/decrypt/Android.mk:4-10). libserial_port도 prebuilt .so를 지정한다(libs/serial_port/Android.mk:4-13).

부팅/프로세스/환경

DeviceAgent manifest는 패키지 com.sk.airbot.deviceagent, android.uid.system, persistent application이다(apps/DeviceAgent/app/src/main/AndroidManifest.xml:2-7,50-59). DeviceAgent, WssService, StreamingService가 exported service로 선언되어 각각 com.sk.airbot.devicecontrol.IDeviceControl, com.sk.airbot.wsscontrol.wss, com.sk.airbot.streamingcontrol.streaming action을 제공한다(72–97행). BootReceiver는 direct-boot-aware이며 locked boot를 받는다(99–110행). 별도 alarm/calibration receiver 4개는 exported이고 SEND_SMS permission을 요구한다(112–151행). Provider도 exported이다(153–156행).

AMRAgent, IotAgent, LLMAgent, MCUAgent, VisionAgent는 manifest에서 system shared UID와 persistent를 사용한다. 각 manifest의 service action은 각각 com.sk.airbot.amrcontrol.IAMRControl, com.sk.airbot.iotcontrol.IIotControl, com.sk.airbot.llmcontrol.ILLMControl, com.sk.airbot.mcucontrol.IMCUControl, com.sk.airbot.visioncontrol.IVisionControl이다(예: apps/AMRAgent/AndroidManifest.xml:4-7,23-40, apps/IotAgent/app/src/main/AndroidManifest.xml:4-7,42-64, apps/LLMAgent/AndroidManifest.xml:4-7,19-37, apps/MCUAgent/AndroidManifest.xml:4-7,19-37, apps/VisionAgent/AndroidManifest.xml:4-7,28-55). PairingAgent는 system UID지만 persistent=false이며 IPairingControl action을 제공한다(apps/PairingAgent/app/src/main/AndroidManifest.xml:2-8,47-76).

Native init 서비스는 둘 다 class main, root user, system group이다. ethernetagent는 /system/bin/ethernetagent(service/ethernetagent/ethernetagent.rc:1-4), logwriter는 /system/bin/logwriter(service/logwriter/logwriter.rc:1-4)로 실행된다. rc에 별도 seclabel, disabled, oneshot, on property 조건은 없다. 프로세스 분리 여부는 rc/manifest에 android:process가 없어 기본 앱/서비스 프로세스 정책과 init native 프로세스에 맡겨져 있다(각 manifest 및 rc 확인).

코드에서 직접 읽고 쓰는 대표 system property는 sys.amragent.enabled, sys.ddsconfig.start, sys.ddsrouter.start, sys.deviceagent.wss.enabled, sys.ethernet.enable, sys.factory.mode.enable, sys.initialized, persist.sys.quber.robot.ip/port, persist.sys.quber.robot.enc, persist.sys.airbot.autoreboot.dailytime, persist.sys.airbot.privacy.enabled, persist.sys.debug.deviceagent* 등이다. 추출 명령 결과상 전체 키 목록은 위 커밋의 Java/C/sh 파일에서 git grep -ho -E '"(persist|sys)\.[A-Za-z0-9_.-]+'로 확인된다. 예: AMR 시작 시 sys.amragent.enabled=1을 쓴다(apps/AMRAgent/java/com/sk/airbot/amragent/AMRAgent.java:163-170); AMR 연결 대기는 이 값을 1로 폴링한다(apps/DeviceAgent/app/src/main/java/com/sk/airbot/deviceagent/device/item/amr/AMRService.java:40-64); AMR 네트워크 목적지는 persist.sys.quber.robot.ip/port를 읽는다(apps/AMRAgent/java/com/sk/airbot/amragent/Setting.java:15-16).

Binder/AIDL: 등록 → 클라이언트 → 구현

핵심 DeviceAgent 계약은 IDeviceControl의 callback 등록/해제, Bundle 기반 sendModuleCommand, 이름 기반 callback 등록/해제이다(apps/DeviceAgent/app/src/main/aidl/com/sk/airbot/devicecontrol/IDeviceControl.aidl:1-16). 구현은 DeviceAgent의 IDeviceControl.Stub이며, 등록 시 calling PID와 callback을 death monitor에 넣고 callback 목록을 MainApi에 전달한다(apps/DeviceAgent/app/src/main/java/com/sk/airbot/deviceagent/DeviceAgent.java:127-143,180-222). onBind()는 이 stub을 반환한다(512–516행). 구현은 exported manifest service의 action과 연결된다(AndroidManifest.xml:72-79).

구체적 cross-agent 흐름은 DeviceAgent가 기동 시 action+package로 Pairing/Iot/Update에 bindService(..., BIND_AUTO_CREATE)한다(DeviceAgent.java:555-565). MainService의 연결 콜백은 각각 IPairingControl.Stub.asInterface, IIotControl.Stub.asInterface, IUpdateControl.Stub.asInterface로 proxy를 만들고, Iot에는 callback 등록 및 server type 조회를 수행한다(apps/DeviceAgent/app/src/main/java/com/sk/airbot/deviceagent/main/MainService.java:523-567,574-635). Iot 구현은 IIotControl.Stub을 반환한다(apps/IotAgent/app/src/main/java/com/sk/airbot/iotagent/IotAgent.java:403-405,1940-1943). AMR은 action을 AIDL package/name으로 만들고 package를 지정해 bind하며(AMRService.java:59-64), 연결 후 IAMRControl.Stub.asInterface 및 callback 등록을 한다(122–133행); AMR 구현은 mAMRControl stub을 반환한다(apps/AMRAgent/java/com/sk/airbot/amragent/AMRAgent.java:265-268,717-721). Vision도 action/package bind 후 IVisionControl.Stub.asInterface와 callback 등록을 한다(VisionAIManager.java:820-835,873-878), 구현은 mVisionControl을 반환한다(apps/VisionAgent/java/com/sk/airbot/visionagent/VisionAgent.java:109-112,384-387).

동일한 패턴의 계약은 AMR IAMRControl(mapping/driving/target/map/charging/sensor/OTA 등, apps/AMRAgent/aidl/com/sk/airbot/amrcontrol/IAMRControl.aidl:1-80), IoT IIotControl(apps/IotAgent/app/src/main/aidl/com/sk/airbot/iotcontrol/IIotControl.aidl:1-12), LLM ILLMControl(apps/LLMAgent/aidl/com/sk/airbot/llmcontrol/ILLMControl.aidl:1-12), MCU IMCUControl(apps/MCUAgent/aidl/com/sk/airbot/mcucontrol/IMCUControl.aidl:1-12), Update IUpdateControl(apps/UpdateAgent/aidl/com/sk/airbot/updatecontrol/IUpdateControl.aidl:1-12), Pairing IPairingControl(apps/PairingAgent/app/src/main/aidl/com/sk/airbot/pairingcontrol/IPairingControl.aidl:1-12), Vision IVisionControl/IFaceControl(apps/VisionAgent/aidl/com/sk/airbot/visioncontrol/IVisionControl.aidl:1-12, apps/VisionAgent/aidl/com/sk/airbot/visioncontrol/IFaceControl.aidl:1-15)이다. WSS/Streaming은 DeviceAgent 내부 exported service이며 IWssControl은 상태/시작·일시정지·중지/설정/얼굴검증 등(apps/DeviceAgent/app/src/main/aidl/com/sk/airbot/wsscontrol/IWssControl.aidl:1-55), IStreamingControl은 스트리밍/업로드/이동 제어(apps/DeviceAgent/app/src/main/aidl/com/sk/airbot/streamingcontrol/IStreamingControl.aidl:1-28)를 정의한다. Face/EventAsset 계약과 실제 외부 broker 구현은 EventAssetAgent tree에 존재하지만, 그 모듈은 이 커밋의 packages.mk 제품 목록에는 없다.

권한/정책 및 스크립트 인터페이스

DeviceAgent는 system alert/internal window, network/Wi-Fi, write settings, privileged phone state, external storage/manage external storage, exact alarm, camera, query all packages, dump, cross-user 권한을 선언한다(apps/DeviceAgent/app/src/main/AndroidManifest.xml:11-41). Alarm receiver의 SEND_SMS 컴포넌트 보호는 위 112–151행에 있다. sepolicy/system_app.te는 system_app이 ota_package_file 디렉터리를 rw하고 파일을 create할 수 있도록 허용한다(1–2행). 그 외 domain/type, service_manager, property, HAL allow rule은 이 저장소 sepolicy 파일에서 확인되지 않는다(sepolicy/system_app.te:1-2).

script/cmd_test.sh는 기본적으로 ADB dumpsys activity service com.sk.airbot.deviceagent/.DeviceAgent를 호출해 DeviceAgent 테스트 surface를 구동한다. 예로 error list/resolve는 test=error(약 500–560행), battery cap은 test=tempsettings setting=BATTERY_CAP_FORCE_VAL(564–585행), station/Wi-Fi/map 상태는 test=setStation, test=setWifiStatus, test=setMapStatus(624–669행), MCU packet dump는 test=mcu method=print_*(672–692행), pause/resume는 method=setDeviceStatus action=2/3(696–716행)이다. 명령 번호 매핑과 인자 sleep/실행 조건은 747–906행이다. script/build_DA.sh는 DeviceAgent 빌드 보조 스크립트이지만, 실제 AOSP lunch/product/toolchain 설정은 저장소 밖이다.

privapp XML은 실제로 비어 있지 않다. IotAgent와 UpdateAgent에는 cache/privileged phone/reboot/package-replaced/sticky broadcast 권한(3–17행), PairingAgent에는 Bluetooth·네트워크·위치·오디오·foreground 및 설정 권한(19–39행), DeviceAgent에는 privileged phone state(41–44행), com.sk.airbot.factory에는 MAC/time(46–49행), StartupService와 SKMLauncher에는 관련 권한(51–59행)이 지정되어 있다(apps/permissions/privapp-permissions-quber_packages.xml:1-61). packages.mk는 이를 system permissions 디렉터리로 복사한다(packages.mk:33-35).

네이티브 동작은 다음과 같다. ethernetagent는 sys.factory.mode.enable 및 sys.boot_completed를 읽고(service/ethernetagent/ethernetStatic.c:62-84), 링크 상태 변화 때 ioctl/netlink로 인터페이스·주소·route를 조정하고 sys.ethernet.enable을 1/0으로 쓴다(246–323, 487–519행). raw ICMP ping 함수도 존재한다(174–227행); 코드에 포함된 주소 상수나 외부 endpoint 값은 재기록하지 않는다. main()은 부트 완료이고 factory mode가 아닐 때 반복 감시한다(523–560행).

logwriter는 SIGINT/SIGTERM/SIGPIPE 처리 후 entryLogWriter()를 호출하고 계속 대기한다(service/logwriter/main.cpp:21-42). /mnt/data3/logs 하위 logwriter/current/events/comm 경로와 파일을 사용한다(service/logwriter/logwriter.cpp:61-76). /system/bin/logcat을 fork/exec해 파일로 수집하고(service/logwriter/logwriter.cpp:425-515,575-603,753-812), logcat/logwriter 파일을 삭제·rename하며 회전한다(644–710, 870–908행). logcat.1 이동 시 gzip 압축 파일을 생성하고 원본을 unlink한다(1066–1092행).

libserial_port의 실제 소비자는 MCUAgent이다. JNI 빌드를 막고 prebuilt를 적용한다는 주석은 apps/MCUAgent/Android.mk:37-41, System.loadLibrary("serial_port")와 native open(path, baudrate, flags), close(), flow_1control() 선언은 apps/MCUAgent/java/com/sk/airbot/mcuagent/comm/SerialPort.java:27-60에 있다. 실제 .so 내용과 ABI 동작은 prebuilt라 저장소에서 검증할 수 없다.

이 Binder 경로는 앱 component binding이다. 저장소에서 확인되는 것은 manifest action, Context.bindService, ServiceConnection, Stub.asInterface, onBind이며, system_server 소스나 ServiceManager.addService() 등록은 이 저장소에 없다. 따라서 이를 framework native Binder service 등록으로 해석할 근거는 없다.

저장소 밖에서 확인해야 하는 미확인 사항

  1. prebuilts/packages/decrypt/a1_decrypt 및 decrypt.rc, 각 APK/AAR/JAR/.so prebuilt의 실제 내용·서명·ABI.
  2. vendor.quber.hardware.* Java/HIDL stub의 실제 HAL 서비스 이름과 vendor manifest/VINTF 등록 및 service registration 상태.
  3. vendor/quber/packages/sepolicy가 product 빌드에서 실제 포함되는지와 최종 merged policy/privapp-permissions 유효성.
  4. Android product makefile에서 packages.mk 조건 변수가 실제 어떤 값인지, listed package 중 누가 최종 system image에 들어가는지.
  5. exported service에 선언된 별도 permission이 없는 항목의 실기기 접근 주체/SELinux 결과, 실제 PID/process 및 boot ordering.
  6. script/cmd_test.sh 명령은 dumpsys 요청 수락 경로만 보여 주며 실제 장치 동작·완료·물리 정지는 이 문서에서 입증하지 않는다.

Connections

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