← Docs hub

Pairing·SDK·호출 시험 모듈 상세

기준: 1398d109c391c4044cae26d0e9aea4d3f08d9670. 지정 커밋의 추적 파일을 직접 확인한 정적 구조 분석이며, 현재 HEAD·후속 TaskManager·SKIX 구현을 포함하지 않는다.

PairingAgent: 등록 통신과 네트워크 설정

기준 루트 P/는 apps/PairingAgent/app/src/main/java/com/sk/airbot/pairingagent/다. Android.mk는 prebuilt APK를 선택하지만 이 커밋의 Java 소스 구조도 별도로 분석했다. 아래 내용은 소스 기준이며 prebuilt dex와의 일치는 미확인이다.

구성 구현 역할 근거
PairingAgentService IPairingControl Stub, foreground 시작, Bluetooth 상태 확인 Handler P/PairingAgentService.java:37–179
BLECentral BluetoothGattServerCallback 구현, 광고·GATT 서비스·read/write 요청·Wi-Fi 상태 응답 P/ble/BLECentral.java:87, :296, :648, :957
BLEProfile / AES128Config BLE characteristic 계약과 암복호화 지원 P/ble/
WifiConnectionManager 수신한 네트워크 설정을 WifiConfiguration으로 만들고 addNetwork·enableNetwork·reconnect 수행 P/wifi/WifiConnectionManager.java:300–371
BLEPeripheral / BLEScanner GATT client read/write와 scan 지원 P/ble/BLEPeripheral.java:27, :125, BLEScanner.java
classicbt Bluetooth 스캔·연결·A2DP 지원 P/classicbt/
IntentReceiver / IntentSender 외부 pairing·인증·reset broadcast 연결 P/intent/, Manifest
provider DB helper·계약·provider 소스 P/provider/; 현재 Manifest에 provider 등록은 없음

호출의 왕복

DeviceAgent → IPairingControl.sendModuleCommand(method=setBluetooth) → PairingAgentService.setBluetooth() → BLEStatusHandler → BLECentral.startAdvertiser()가 제어 방향이다. Handler는 Bluetooth 상태를 1초 간격으로 확인한다. off 요청은 광고를 중지한다.

스마트폰 등의 GATT 요청은 BLECentral에서 처리한다. 분할 payload 재조립·복호화·SSID/보안 정보 설정을 거쳐 WifiConnectionManager가 Android Wi-Fi 설정을 적용한다. 이후 네트워크 상태·GATT read 응답과 DeviceControl 명령으로 등록 진행 상태를 전달한다.

근거: P/PairingAgentService.java:51–147, P/ble/BLECentral.java:957 이후의 characteristic 처리와 ConnectSsidRebuilder 등 재조립 코드, P/wifi/WifiConnectionManager.java:350–372.

생명주기와 외부 의존

onCreate에서 receiver 등록, foreground, DeviceControlProxy 연결, EncryptionServiceManager 연결, Wi-Fi·Bluetooth 활성화를 요청한다. BLECentral도 DeviceAgent callback을 사용한다. 따라서 이 앱은 Bluetooth 전송만 하는 모듈이 아니라 기기 초기 설정과 제품 상태의 연결점이다.

검토할 경계: unregisterCallback()이 같은 메서드를 재귀 호출하는 코드가 있으며(PairingAgentService.java:98–104), 이는 정상적인 callback 해제 구현으로 설명할 수 없다. 실제 prebuilt에서 같은 코드가 실행되는지는 별도 확인해야 한다. onDestroy의 receiver 해제만으로 BLE·Handler·외부 연결 전체 정리가 증명되는 것도 아니다.

DeviceControlAPI: legacy 정적 Java client

모듈 DeviceControlAPIJavaLib의 핵심은 apps/DeviceControlAPI/java/com/sk/airbot/devicecontrol/DeviceControlProxy.java다. 호출자는 static connect와 getService를 통해 IDeviceControl을 얻고 raw Bundle 명령을 보낸다.

앱 connect(context, callback, className/rebind)
→ singleton에 context·caller 이름·callback 보관
→ action + 명시적 DeviceAgent package로 bindService
→ IDeviceControl.Stub.asInterface
→ callback 등록 및 binder death 연결
→ 호출자의 onServiceConnected / onModuleCallback

disconnect는 death recipient 해제, 이름 기반 callback 해제, unbind, 연결 flag 초기화를 수행한다. 이 proxy는 명령 의미를 typed 도메인 API로 모두 변환하는 SDK가 아니라 Binder 연결·callback 수명 관리가 중심이다.

근거: 같은 파일 connect() overload, 내부 IDeviceControlSingleton, ServiceConnection, connectService():211, disconnectService():220 이후; apps/DeviceControlAPI/Android.mk:5–18.

AirbotSdkProject: 일반 제어·WSS·Streaming client library

Gradle 프로젝트의 devicecontrolapi 모듈에는 일반 DeviceControlProxy 외에 WSS와 Streaming 전용 proxy가 있다. app 모듈 Manifest에는 별도 Activity가 없어 이 커밋만으로 완성된 사용자용 sample UI라고 설명하지 않는다.

계층 클래스·파일 역할
일반 제어 devicecontrol/DeviceControlProxy.java IDeviceControl 연결·callback
WSS 공통 wsscontrol/WssManagerProxy.java bind timeout, event observer, death recipient, 재연결
WSS 역할 WssManagerFront / WssManagerRemote front와 remote별 API 표면
Streaming 공통 streamingcontrol/StreamingManagerProxy.java 세션 상태·movement·error·request 이벤트 전달
Streaming 역할 StreamingManagerFront / StreamingManagerRemote 로컬 표현 쪽과 원격 요청 쪽 API 표면
값·IPC deviceagent/wss/data/, deviceagent/data/, src/main/aidl/ parcelable·구역·위치 및 interface 사본

기준 루트: apps/AirbotSdkProject/devicecontrolapi/src/main/java/com/sk/airbot/.

WssManagerProxy.initWssManager는 bindService 결과를 확인하고 CountDownLatch로 지정 timeout까지 기다린다. 연결 시 IWssControl 변환·linkToDeath·registerWssCallback을 수행한다. 끊김·death 경로와 재연결 루프가 별도로 있다. 따라서 호출 스레드와 timeout·destroy 처리는 API 사용 시 확인해야 한다. UI thread에서 안전하다는 검증은 이번 분석에 포함하지 않는다.

근거: wsscontrol/WssManagerProxy.java:223–270, :328–416. Streaming의 RESULT_SUCCESS·RESULT_ERR_TIMEOUT·RESULT_ERR_BIND_FAILED와 running-state/event 상수는 streamingcontrol/StreamingManagerProxy.java:28–100.

Front/Remote 클래스가 있다고 server 인증을 대체하는 것은 아니다. server의 WssPackageValidator와 SDK API 표면은 서로 다른 책임이다. AIDL·parcelable 사본의 호환성은 IPC 문서를 참조한다.

devicecontrolapi_test: 수동 호출 시험 앱

apps/devicecontrolapi_test/java/.../MainActivity.java는 화면 위젯을 바인딩하고 DeviceControlProxy로 연결한다. callback은 method와 Bundle을 로그에 출력한다. 일부 화면명은 display/audio/LED 시험 이름을 유지하지만 실제 버튼 동작은 수정되어 있다. 예를 들어 한 버튼은 setLlmStatus Bundle을 전송하고 다른 버튼은 EXIT 표시로 바뀐다.

따라서 이 모듈은 API 회귀 suite나 자동 품질 gate가 아니다. UI 라벨만 보고 현재 검증 범위를 판정하면 안 된다. 실제 수행 method와 출력·장치 결과를 확인해야 한다.

근거: MainActivity.java:60–120, :128–135, :185 이후, apps/devicecontrolapi_test/Android.mk의 정적 library 의존.

permissions: 설치 권한 지원 모듈

이는 실행 앱이 아니다. privapp XML이 package별 권한을 선언하고 생성 도구가 실제 image의 APK와 framework permission을 비교한다. 앱 manifest에서 요청한 권한, allowlist, UID·서명, SELinux는 각기 다른 층이다. 상세 파일과 조건은 플랫폼·권한에 모았다.

확대 구조도와 연결별 근거

Connections

전체 목차 · 앱 구성 · DeviceAgent 내부 · IPC · 실행 흐름 · 플랫폼·빌드 · 근거·확인 범위

Keyboard shortcuts

⌘K / Ctrl+KOpen command palette
/Focus search
g hGo to home
g pGo to projects
g sGo to sessions
j / kNext / prev row (tables)
?Show this help
EscClose dialogs

Structured queries

Mix key:value filters with free text in the palette:

type:sessionOnly session pages
project:llm-wikiFilter by project name (substring)
model:claudeFilter by model name (substring)
date:>2026-03-01Sessions after a date
date:<2026-04-01Sessions before a date
tags:rustPages mentioning a tag/topic
sort:dateSort results by date (newest first)

Example: type:session project:llm-wiki date:>2026-04 sort:date