댓글 검색 목록

[Reactjs] React Native를 사용하여 LightOS 빌드

페이지 정보

작성자 운영자 작성일 20-01-27 15:11 조회 589 댓글 0

Light Phone 2는 2019 년 Time Magazine 최고의 발명품 중 하나로 선정 된 미니멀리스트 휴대폰입니다. 

OS가 React Native로 구축되었음을 알고 있습니까? 다음은 이야기, React Native가 선택된 이유 및 구축 방법입니다.


https://medium.com/sanctuary-computer-inc/building-lightos-with-react-native-4b6e4ad1cd7f 


우리가 아는 한, LightOS는 React Native로 구축 된 최초의 운영 체제입니다.

이 게시물은 장치의 작동 방식, React Native를 선택한 이유 및 개발 과정에서 직면 한 몇 가지 과제에 대한 세부 정보를 제공합니다.


칩셋 및 기본 OS 


하드웨어를 개발할 때 가장 큰 소프트웨어 제약 중 하나는 칩셋입니다. 

일반적으로 칩셋에 포함 된 기본 운영 체제 (일반적으로 Linux의 풍미 또는 Android의 풍미)의 바닐라 빌드이기 때문입니다.


이 시점에서 변경하려면 대체 OS에 대한 모든 사용자 지정 드라이버를 다시 작성해야 할 수 있으므로 일반적으로 큰 작업입니다.


LightOS는 Qualcomm Snapdragon (MSM8909)을 정확하게 실행합니다. 보급형 스마트 폰 칩셋입니다 (웨어러블 기기에 적합).


The Light Phone 2가 "가능한 한 적게 사용되도록 설계되어 있음"을 감안할 때 MSM8909는 유연성과 가격간에 훌륭한 균형을 이루고 있습니다.


이와 같이, LightOS는 Android 운영 체제 프로젝트 (여기서는 AOSP라고 함)를 기반으로 합니다. 원래 Qualcomm에서 제공 한 칩셋 인 Android 8.1의 포크입니다.


즉, LightOS를 언급 할 때 "플랫폼 서명 된 React Native 앱을 기본 런처로 포함하는 Android 8.1의 사용자 정의 포크"(다른 드라이버 및 저수준 사용자 정의 중)를 말합니다.


Eink 화면 


Light Phone 2에는 주변 장치가 많이 있지만 가장 흥미로운 것은 Eink Screen입니다 (대각선 2.84 ", 회색 16 개, 해상도 600x480).


익숙하지 않은 경우 (I't was!), Eink 화면은 수백만 개의 마이크로 캡슐로 구성되어 있으며 각 캡슐에는 양 또는 음전하를 적용하여 Z 축으로 이동할 수 있는 흑백 입자가 있습니다.


0*xtIWrCAayRW6V0l5.png 

실제로 eink가 작동하는 방식


이 품질로 인해 이 장치는 눈의 피로를 덜어줍니다. 늦은 밤에 안구에 파란색 (LCD) 빛이 비추지 않으며 독서를 위한 자연스러운 표면처럼 느껴집니다.


그러나 Eink와 같은 물리적 인 화면 자료로 작업 할 때 몇 가지 어려움이 있습니다.


1. Eink는“고스트”가 발생하기 쉽다 


고 스팅은 내부 Eink 입자가 업데이트 사이에 "고착"되는 효과입니다. 작고 빠른 현지화 된 업데이트는 사용자 경험에 좋을 수 있지만, 이러한 입자를 더 빨리 구동하기 때문에 전력 부족으로 인해 이전 위치에 멈춰 새 프레임이 있을 때 이전 프레임의 인공물을 보여줍니다. 프레임이 활성화되었습니다.


또한, 이들 입자는 "드리프트"될 수 있다. 캡슐에 떠 있고 전하에 의해서만 제자리에 고정되어 있으면 입자가 때때로 제자리에서 표류합니다. 이것은 스크린이 색 변화 차이를 계산할 때, 수학은 입자의 실제 위치가 아니라 가정 된 위치를 기반으로 한다는 것을 의미합니다. 종종 잘못된 업데이트가 발생합니다.


2. Eink가 업데이트 속도가 느릴 수 있음 


0*a0PE8CB8pE75NKdA.gif 


이러한 고 스팅을 줄이려면“전체 화면, 깜박이는 업데이트”를 수행해야 합니다.


그렇기 때문에 Eink 장치는 시그니처 반전 컬러 플래시로 잘 알려져 있습니다. 반전 된 플래시는 각 잉크 캡슐의 알려진 위치를 재설정 하여 본질적으로 이미지가 무결성을 업데이트하도록 강제하기 때문에 필요합니다.


그러나 불행히도 이러한 전체 화면 플래시는 완료하는 데 주변 온도에 따라 600–1200ms가 소요될 수 있습니다.


이를 통해 초당 최대 1-2 회의 전체 화면 업데이트 빈도를 얻을 수 있습니다.


하지만 왜 React 네이티브인가? 


React Native는 펌웨어 개발 프로젝트에 내장 된 네이티브 플랫폼에서 이상한 선택이라고 생각할 수도 있습니다.


시작하기 전에 : 예 — Flow를 통해 형식 확인 자바 스크립트를 사용합니다 (현재 스튜디오에서는 전체적으로 Typescript를 사용합니다).


1. Eink 화면의 Sane 렌더링주기 


대만의 Eink 팀과 만나서 수용해야 할 모든 화면 문제를 이해 한 후에는 뷰 트리 업데이트 문제를 완전히 분리 할 수 있는 UI 프로그래밍 모델을 찾아야 한다는 것을 깨달았습니다. 배치, 폴딩 및 업데이트를 Eink 화면 자체에 배치


따라서 우리는 다음과 같은 것을 찾고 있었습니다.

  • 명령에 대한 선언적 : 그림과 돌연변이를 수동으로 관리하는 대신 UI를 한 번 명확하게 배치하고 싶었습니다.
  • 반응성과 불변 : 우리는 기본 시스템 상태의 변화에 ​​따라 자체 렌더 라이프 사이클을 관리 할 수 있는 시스템을 원했습니다.
  • 추상화 가능 : UI 개발자가 프레임 워크 수준의 화면 API를 관리하는 것을 원하지 않았습니다. 이는 "플러그 가능"하위 수준 계층이어야 했습니다.
  • 컴포저 블 : 우리는 결국 OS를 위한 UI 프레임 워크를 구축하고 있습니다!

놀랍게도 Java / Kotlin * 용 Reactive UI 프레임 워크에는 많은 방법이 없으며 이전에 소수의 React Native 앱을 빌드 했기 때문에 선택의 여지가 분명했습니다.


Eink 화면에 2 ~ 3fps의 병목 현상이 있다고 가정하면 60fps를 달성하는 것이 목표가 아닙니다. 또한 LightOS는 동적 세그먼트가 거의 없고 애니메이션이 거의 없는 "프레임 단위"로 설계되었으므로 업데이트는 종종 접히고 배치됩니다 (아래에서 자세히 설명).


* 리토 (Litho)는 효과가 있었지만 기존의 XML 레이아웃은 반드시 관리해야 하므로 피하고 싶었습니다. 우리가 시작한 후 Jetpack Compose가 릴리스되었지만 꽤 좋아 보입니다!


2. React 중심 앱 SDK (2020 년 출시 예정) 


일반 Light Phone 사용자는 정통한 소비자입니다. 그들은 일반적으로 기술을 선도하는 해커이며, 자신의 기기에서 자유롭게 해방시킬 방법을 찾기 위해 끊임없이 노력하고 있습니다.


  • SMS를 사용하여 임시 CLI를 해킹 한이 사용자를 살펴보십시오.


React Native를 사용하면 곧 광범위한 개발자 커뮤니티에 SDK를 열어 해커와 자바 스크립트 개발자가 LightOS 용 사용자 정의 도구를 제공 할 수 있습니다.


0*Zd5zVQDi_r_jtQgj.jpg 


React x Eink 아키텍처 


물론 React의 "단방향 데이터 흐름"패턴에 의존하고 싶었습니다. 또한 React에서 렌더링을 차단하고 싶지 않았습니다. 이렇게 하면 UI가 크롤링 되는 속도가 느려집니다.


대신, 렌더링을 위해 "최종적으로 일관된"모델을 정했습니다. 이 패턴은 VOS 서버 전략에 착수하여 LightOS v56- 릴리스 최종 사용자에게 제공 될 때까지 몇 번의 반복을 거쳤습니다.


1*3hLTLimS7EnIKW5CogQyJw.jpeg 


React Native의 장점은 UI 개발자가 각 렌더링이 Eink 화면으로 어떻게 전파 되는지에 대해 걱정할 필요 없이 일상적인 기능을 구축하고 새로운 화면을 제공 할 수 있다는 것을 의미했습니다.


컴포넌트를 "동적 컨텐츠 사용"으로 표시하기 위해 Eink.js 컴포넌트의 렌더링 소품으로 작업을 래핑 하기 만하면 됩니다. 설정 패널의 상단 정보 표시 줄 중앙에 있는 TimeDisplay 위젯은 다음과 같습니다.


const TimeDisplay = withTime(props => (
<Eink
mode={Modes.DU}
render={memo(() => (
<Layout width={12}>
<UIText variant="copy" align="center" lineHeight={FONT_SIZES['copy']}>
{props.time}
</UIText>
</Layout>
))}
/>
));


Java 측면에서, React Native 렌더가 뷰 트리에서 "숨겨진"렌더 태그로 나타납니다.이 태그는 업데이트 모드 (위의 Modes.DU)를 설명하고 화면을 업데이트하는 데 필요한 다른 휴리스틱은 거의 없습니다.


새로운 렌더링 태그가 발견 되 자마자 커널 드라이버는 Linux 프레임 버퍼 (/ devices / virtual / graphics / fb0)와 Eink 화면 동기화 작업을 진행합니다.


화면이 업데이트 되는 동안 ~ 600–1200ms 간격으로 작업자 스레드에서 React Native의 렌더를 계속 수집하여 (UI를 차단하지 않음) 일괄 처리하여 단일 업데이트로 접습니다. 보류중인 화면 업데이트가 완전히 전파되는 순간 커널 드라이버는 uEvent를 사용자 공간으로 보냅니다. 폴딩을 멈추고 다음에 대기 중인 업데이트를 즉시 적용하기 시작하라는 신호입니다.


실제 장치에 대한 개발 


처음 몇 달 동안 Android 에뮬레이터를 개발할 수 있었습니다. 우리는 Eink 화면과 동일한 화면 크기로 Android 8.1 가상 장치를 설정하고 플랫폼 앱의 기본 UI 인프라를 완성했습니다.


타이밍은 현명한 데, 아직 제조 파트너로부터 개발 보드를 받지 않았기 때문에 훌륭했습니다.


그러나 곧 플랫폼 수준 API를 사용해야 했으며 (아래에 더 자세히 액세스 할 수 있도록) "실제"펌웨어를 기반으로 개발해야 했습니다.


이는 대상 펌웨어에 플랫폼 키 (소프트웨어 구성 요소가 무엇보다도“퍼스트 파티”임을 AOSP에 알리는 비밀 서명 키)가 포함되어 있기 때문입니다. 대상 펌웨어의 플랫폼 키로 APK에 서명하지 않으면 개인 Android 플랫폼 API에 액세스 할 수 없습니다.


따라서 최초의 개발 장치를 받고 제조 파트너로부터 플랫폼 키를 얻은 후에는 로컬 .keystore를 설정하여 APK를 개발에 서명했습니다.


빙고! 이제 개발 기기에 APK를 구축하여 숨겨진 모든 Android 플랫폼 API에 법적으로 액세스 할 수 있습니다.


그럼에도 불구하고 — Android Studio는 여전히 컴파일 할 수 없었지만 (읽기를 계속) 적어도 리플렉션을 사용하여 대부분을 얻을 수 있었습니다.


개발 중인 Android 플랫폼 API에 대한 컴파일 


대부분의 Android 앱은 제조 된 장치의 펌웨어에 내장되어 있지 않습니다. 대신 타사 개발자가 코드 서명하고 Android의 권한 모델에 따라 해당 앱은 권한이 낮은 하위 수준에 액세스 할 수 없습니다 아피스.


표준 타사 Android 앱을 개발할 때 Android Studio는 애플리케이션이 타사라고 가정합니다. 즉, android.telephony.TelephonyManager의 여러 메소드와 같이 숨겨진 API에 액세스하려고 하면 컴파일 되지 않습니다.


그러나 여기서 OS를 구축하고 있습니다! Android 코드베이스의 모든 메소드에 액세스하고 컴파일 할 수 있어야 합니다. 나중에 AOSP 플랫폼 키를 사용하여 빌드에 코드 서명하면 해당 권한이 부여되지만 이를 개발할 수 없으면 스타터가 아닙니다.


Android Studio가 이러한 API에 액세스 할 수 있도록 하려면 소스에서 AOSP를 빌드하고 프레임 워크 스텁을 .jar 파일로 추출해야 했습니다.


Android API는 버전마다 변경되며 펌웨어 빌드에는 AOSP에 대한 추가 사용자 정의가 있을 수 있으므로 플랫폼 앱의 정확한 펌웨어 대상을 사용하여 프레임 워크 스텁을 컴파일해야 합니다.


AOSP 컴파일은 잘 문서화 되어 있으므로 여기에 남겨 두겠습니다. 그러나 성공적인 빌드 후 target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar와 같은 출력 파일이 있습니다.


1*yM0qDWaUFWfWJpCWIuHF5Q.png 


이 파일을 가져 와서 (framework_all.jar로 이름 변경) android / app / libs 폴더 아래의 Android 코드베이스에 추가했습니다.


참고 : AOSP 빌드에서 메소드를 추가하거나 제거하는 경우 이 파일을 다시 빌드해야 합니다.


다음으로, android / app / build.gradle 파일에서 폴더가 첫 번째 라인으로 컴파일 되는지 확인하십시오.


dependencies {
//... Ensure your framework_all.jar is compiled first:
compileOnly fileTree(dir: "libs", include: ["*.jar"])
//... your other dependencies here
implementation project(':react-native-svg')
}


마지막으로 프로젝트를 정리하고 이제 전체 Android SDK의 모든 숨겨진 API를 가져 와서 사용하고 컴파일 할 수 있었습니다!


불안정한 화면 (및 커널)에 대한 작업 


개발 초기 단계에서 제조 파트너는 "하드웨어 추상화 계층"(또는 HAL)을 작성했습니다. 이것은 칩셋의 전기 신호를 연결하여 주변 장치 (진동 모터 또는 스피커와 같은)의 신호를 제어하는 ​​C ++ 드라이버 세트의 이름입니다.


이러한 사용자 정의 드라이버 중 하나는 Eink 커널 드라이버입니다. 우리가 설정 한 아키텍처는 앞에서 언급 한 것처럼 프레임 버퍼에서 직접 읽는 Linux 커널 드라이버입니다.


참고 : 뒤늦게 보면 더 나은 아키텍처는 Android의 인 메모리 표면 깜박임을 활용했을 것입니다 (프레임 버퍼에서 직접 읽는 것이 까다로웠으며 추가 해결 방법이 필요했습니다). 그러나 현재 우리는 대부분 운전자 엔지니어 (프레임 워크 엔지니어가 FOTA와 같은 미션 크리티컬 한 부분을 작업하고 있음)에 액세스 할 수 있었으므로 모든 것이 고려 된 최고의 경로였습니다.


1*4pJq7OhkDUXA_O2DnFXCpg.png 

아시다시피, 초기에 Eink 화면은 거의 작동하지 않았습니다. 커널 드라이버는 버그로 가득 차 있었고 커널 패닉으로 전체 장치가 자주 충돌합니다.


따라서 개발 속도를 좋은 클립으로 유지하기 위해 Android의 컴포 지터에서 직접 읽고 사용자가 컴퓨터에서 직접 기기와 상호 작용할 수 있는 환상적인 오픈 소스 스크린 미러링 소프트웨어 인 Vysor를 사용했습니다.


이것은 우리의 불안정한 화면이 초기에 개발을 차단하지 않았음을 의미했습니다! Vysor는 무료로 사용할 수 있으며 Vysor Pro는 평생 라이센스로 $ 40입니다.

댓글목록 0

등록된 댓글이 없습니다.

웹학교 로고

온라인 코딩학교

코리아뉴스 2001 - , All right reserved.