
Sill for Android 비공식 앱은 맥 화면을 휴대폰으로 스트리밍하는 무료 오픈소스 앱 Sill의 안드로이드 클라이언트다. 맥에 Sill을 설치하고 안드로이드폰에 이 앱을 설치하면, 앱이 맥을 찾아 코드로 페어링한 뒤 맥의 창을 보여 주고 제어한다.
이 앱은 비공식 프로젝트로 Sill 개발자가 만들거나 보증·지원하지 않는다. Sill의 자체 통신 프로토콜(Saffsanity/sill의 Sources/StreamProtocol)을 사용하므로 맥 쪽은 수정할 필요가 없다. 이 앱의 문제는 저장소 이슈에 보고해야 하며 Sill 쪽에 문의할 사안은 아니다.
설치와 연결
맥에는 getsill.app/download에서 Sill을 설치해 실행한다. 요청이 뜨면 화면 기록과 손쉬운 사용 권한을 허용해야 한다.
휴대폰에는 Releases에서 sill-android-<version>.apk를 내려받아 설치한다. 안드로이드가 요청하면 브라우저에서 받은 앱의 설치를 허용해야 하며, 안드로이드 11 이상이 필요하다. 업데이트 알림을 받으려면 이 저장소를 Obtainium에 추가할 수 있다.
두 기기를 같은 와이파이에 연결한 다음 휴대폰에서 Sill을 열고 맥을 탭한다. 맥에 표시되는 페어링 창의 12자리 코드를 휴대폰에 입력하면 연결된다. 이후에는 자동으로 다시 연결된다.
집 밖에서 연결하려면 맥의 Sill 설정에서 Remote Access를 켜고 두 기기를 Tailscale이나 다른 VPN에 연결한다. 휴대폰에서 Connect by address…를 선택하고 맥의 Tailscale 이름 또는 주소를 입력한다. 포트는 변경하지 않았다면 7455다. 먼저 집에서 페어링하거나, 맥의 Sill 메뉴에서 Pair iPhone or iPad…를 열어 표시된 코드를 입력할 수 있다. 맥의 페어링 QR 코드를 휴대폰 카메라로 스캔해도 Sill이 열리고 페어링된다.
맥에서 휴대폰을 잊도록 설정한 경우(Sill › Settings › Devices › Remove)나 Sill을 다시 설정한 경우, 휴대폰은 이를 알리고 새 코드를 요청한다. 계속해서 재접속을 시도하지는 않는다. 맥은 1분 안에 다섯 번 거부된 주소를 차단한다.
휴대폰의 키는 안드로이드 키스토어(Android Keystore)에서 생성되며 외부로 나가지 않는다.
조작과 미지원 기능
화면을 탭하면 맥에서 클릭하고, 한 손가락으로 끌면 관성 스크롤한다. 누른 상태에서 움직이면 텍스트를 선택하거나 창을 옮기는 드래그가 된다. 누르고 있다가 손을 떼거나 두 손가락으로 탭하면 오른쪽 클릭이다.
Draw를 켜면 한 손가락으로 마우스 버튼을 누른 채 끌 수 있어 tldraw, Figma, Preview에서 그림을 그릴 수 있다. Draw를 다시 탭하면 스크롤 모드로 돌아간다. 손가락을 오므리거나 두 손가락으로 움직이는 제스처는 휴대폰 화면의 그림만 확대·이동하며, Fit을 누르면 화면에 맞게 초기화된다.
창 선택 메뉴에서는 창, 데스크톱 또는 앱 열기를 선택할 수 있다. 키보드로 문자를 입력할 수 있으며, 키 행에는 esc, tab, ⌘, ⌃, ⌥, ⇧, 화살표와 Spotlight가 있다. 수정 키를 탭하면 다음 키 입력이나 클릭에 적용되도록 고정된다. 하드웨어 키보드의 입력은 맥으로 전달된다. 하드웨어 키보드에서 Ctrl은 ⌘로, Meta는 ⌃로 동작한다.
아직 트랙패드 모드, 세 손가락 제스처, 맥 메뉴, 클립보드, 맥 설정 패널, 휴대폰 화면에 맥 포인터를 그리는 기능은 없다. 하드웨어 키를 누르고 있어도 맥에서 키 반복 입력이 되지 않으며, 누를 때마다 한 번만 입력된다. 애플 전용인 AWDL을 이용한 직접 무선 연결과 USB 케이블 페어링도 지원하지 않는다. USB 연결에서는 맥이 아이폰과 아이패드만 인식하기 때문이다. 페어링은 코드로 해야 한다.
개인정보와 빌드
앱은 암호화된 연결로 사용자의 맥에만 통신하며, 개발자나 다른 곳으로 데이터가 전송되지 않는다고 안내한다. 자세한 내용은 PRIVACY.md에 있다.
빌드에는 JDK 17과 Android SDK의 플랫폼 36이 필요하다.
./gradlew :protocol:test # 프로토콜 단위 테스트(암호화 벡터, 프레이밍, JSON, HEVC)
./gradlew :app:assembleDebug # app/build/outputs/apk/debug/app-debug.apk (io.github.rahimnathwani.sill.debug)
디버그 빌드는 릴리스 버전과 나란히 설치할 수 있으며, 일반 TCP 테스트 호스트 목록도 표시한다. 이 호스트는 디버그 빌드에서만 표시된다.
릴리스와 실시간 테스트
릴리스 스크립트는 테스트와 린트를 실행하고, 서명된 APK와 Play 번들을 dist/에 만든 뒤 서명을 확인한다. --publish를 붙이면 이어서 v0.2.0 태그를 만들고 APK가 포함된 GitHub 릴리스를 생성한다.
scripts/release.sh 0.2.0 # tests, lint, signed APK and Play bundle in dist/, signature checked
scripts/release.sh 0.2.0 --publish # then tag v0.2.0 and create the GitHub release with the APK
먼저 CHANGELOG.md에 ## 0.2.0 항목을 추가해야 하며, 이 내용이 릴리스 노트가 된다. 업로드 키는 ~/.config/sill-android/upload.jks에 있고 비밀번호는 macOS 키체인의 sill-android-upload-key에 저장한다. 키는 저장소나 CI에 들어가지 않는다. Google Play 관련 내용은 play/checklist.md에 있다.
Saffsanity/sill 체크아웃에서 테스트 호스트를 실행하면 맥 호스트에 대한 실시간 테스트를 할 수 있다. 이 호스트는 루프백 연결만 허용하며 입력을 보내지 않는다.
SILL_TEST_LOOPBACK=1 SILL_TEST_SOFTWARE_ENCODER=1 SILL_TEST_NO_ROUTER=1 \
SILL_TEST_REMOTE_DIR=$T/host SILL_TEST_ASK_FROM_THIS_MAC=1 \
.build/release/SillHost --synthetic --pairing > $T/host.log
lsof -nP -iTCP -sTCP:LISTEN | grep SillHost로 포트를 확인한 뒤 다음 명령을 실행한다.
SILL_LIVE_HOST=127.0.0.1 SILL_LIVE_PORT=<port> SILL_LIVE_CODE_FILE=$T/host.log \
./gradlew :protocol:test --tests '*LiveHostTest*' --rerun
에뮬레이터에서는 Connect by address…에 10.0.2.2:<port>를 입력해 호스트에 연결할 수 있다.
저장소 구성과 라이선스
protocol/은 안드로이드에 의존하지 않는 순수 Kotlin/JVM 모듈이다. 프레이밍(Wire), Swift Codable 형태의 JSON(Json, Messages), 페어링 암호화(Crypto: PBKDF2 증명, Mac ID, 인식 태그, Damm), 기기의 P-256 키와 자체 서명 인증서(Identity), SPKI 고정 및 ALPN sill/1·sill-pair/1을 사용하는 TLS 1.3(Tls), 페어링 교환(Pairing), hello·뷰포트·ping·연결 상태·통계를 다루는 세션(Session), HEVC hvcC에서 Annex B로의 변환과 SPS 크기 처리(Hevc)가 포함된다.
app/은 안드로이드 앱 모듈이다. Bonjour 검색(Discovery, NsdManager), MediaCodec 디코딩(VideoDecoder), 터치와 키보드(StreamView, HidKeys), 화면과 흐름(MainActivity), 저장소(Store)를 포함한다. 일반 TCP 연결용 테스트 호스트는 개발용이며 디버그 빌드에서만 목록에 표시된다.
라이선스는 Apache-2.0이다. Sill과의 관계는 NOTICE에서 확인할 수 있다.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요