RIL 리팩터링

Android 7.0은 일련의 기능을 사용하여 RIL(Radio Interface Layer)을 리팩터링해 RIL 기능을 개선했습니다. 선택사항이지만 권장되는 이러한 기능을 구현하려면 파트너 코드를 변경해야 합니다. 리팩터링 변경사항은 이전 버전과 호환되므로 이전에 구현한 리팩터링된 기능이 계속 작동합니다.

RIL 리팩터링에는 다음 개선사항이 포함됩니다.

  • RIL 오류 코드. 기존 GENERIC_FAILURE 코드뿐만 아니라 특정 오류 코드를 사용 설정합니다. 오류 원인에 관한 더 구체적인 정보를 제공하여 오류 문제 해결에 도움이 됩니다.
  • RIL 버전 관리. 더 정확하고 구성하기 쉬운 버전 정보를 제공합니다.
  • wakelock을 사용하는 RIL 통신. 기기 배터리 성능을 개선합니다.

위 개선사항 중 일부 또는 전부를 구현할 수 있습니다. 자세한 내용은 다음 페이지에서 RIL 버전 관리에 관한 코드 설명을 참조하세요. https://android.googlesource.com/platform/hardware/ril/+/master/include/telephony/ril.h

개선된 RIL 오류 코드 구현

거의 모든 RIL 요청 호출이 오류에 응답하여 GENERIC_FAILURE 오류 코드를 반환할 수 있습니다. OEM에서 반환하는 요구된(solicited) 모든 응답과 관련된 문제로, 다른 이유로 동일한 GENERIC_FAILURE 오류 코드가 RIL 호출에서 반환되면 버그 신고에서 문제를 디버그하기가 어려워질 수 있습니다. 공급업체가 코드의 어떤 부분이 GENERIC_FAILURE 코드를 반환했을 수 있는지 식별하는 데도 상당한 시간이 걸릴 수 있습니다.

Android 7.x 이상에서 OEM은 현재 GENERIC_FAILURE로 분류된 다양한 각 오류와 연결된 명확한 오류 코드 값을 반환할 수 있습니다. 맞춤 오류 코드를 공개적으로 표시하지 않으려는 OEM은 OEM_ERROR_1~OEM_ERROR_X로 매핑된 명확한 정수 세트(예: 1~x)로 오류를 반환할 수 있습니다. 공급업체는 이러한 마스킹된 각 오류 코드가 반환되어 코드의 고유한 오류 이유에 매핑되도록 해야 합니다. 특정 오류 코드를 사용하면 OEM에서 일반 오류를 반환할 때마다 RIL 디버깅 속도를 높일 수 있습니다. GENERIC_FAILURE 오류 코드의 정확한 원인을 식별하는 데 너무 많은 시간이 걸릴 수 있고 때로는 파악하기가 불가능하기 때문입니다.

또한 ril.h는 enum RIL_LastCallFailCauseRIL_DataCallFailCause의 오류 코드를 더 많이 추가하므로 공급업체 코드는 CALL_FAIL_ERROR_UNSPECIFIEDPDP_FAIL_ERROR_UNSPECIFIED와 같은 일반 오류의 반환을 방지할 수 있습니다.

개선된 RIL 오류 코드 확인

새로운 오류 코드를 추가하여 GENERIC_FAILURE 코드를 대체한 후 새로운 오류 코드가 GENERIC_FAILURE 대신 RIL 호출에서 반환되는지 확인합니다.

개선된 RIL 버전 관리 구현

이전 Android 출시의 RIL 버전 관리에는 문제가 있었습니다. 버전 자체가 부정확했고 RIL 버전을 보고하는 메커니즘이 불분명했으며(이에 따라 일부 공급업체가 잘못된 버전을 보고함) 버전을 추정하는 해결 방법도 정확하지 않은 경향이 있었습니다.

Android 7.x 이상에서 ril.h는 모든 RIL 버전 값을 문서화하고 상응하는 RIL 버전을 설명하며 버전의 모든 변경사항을 나열합니다. RIL 버전에 상응하는 변경을 실행할 때 공급업체는 코드로 버전을 업데이트하고 RIL_REGISTER로 버전을 반환해야 합니다.

개선된 RIL 버전 관리 확인

ril.h에서 정의된 RIL_VERSION이 아니라 RIL 코드에 상응하는 RIL 버전이 RIL_REGISTER 중에 반환되는지 확인합니다.

wakelock을 사용하는 RIL 통신 구현

시간이 지정된 wakelock은 RIL 통신에서 부정확하게 사용되어 배터리 성능에 부정적인 영향을 미칩니다. Android 7.x 이상에서는 RIL 요청을 분류하고 코드를 업데이트하여 다양한 요청 유형에 따라 wakelock을 다르게 처리해 성능을 개선할 수 있습니다.

RIL 요청 분류

RIL 요청은 요구되거나(solicited) 요구되지 않을(unsolicited) 수 있습니다. 공급업체는 요구된 요청을 다음 중 하나로 추가 분류해야 합니다.

  • 동기. 응답하는 데 많은 시간이 걸리지 않는 요청. 예: RIL_REQUEST_GET_SIM_STATUS
  • 비동기. 응답하는 데 많은 시간이 걸리는 요청. 예: RIL_REQUEST_QUERY_AVAILABLE_NETWORKS

비동기로 요구된 RIL 요청에는 상당한 시간이 걸릴 수 있습니다. 공급업체 코드에서 확인을 수신하면 RIL 자바는 wakelock을 해제하므로 애플리케이션 프로세서가 유휴 상태에서 정지 상태로 전환될 수 있습니다. 공급업체 코드에서 응답이 제공되면 RIL 자바(애플리케이션 프로세서)는 wakelock을 다시 획득하고 응답을 처리한 다음 유휴 상태로 돌아갑니다. 이와 같이 유휴 상태에서 정지 상태로 전환했다가 다시 유휴 상태로 전환하면 많은 전력이 소비될 수 있습니다.

응답 시간이 충분히 길지 않다면 응답에 걸리는 전체 시간 동안 wakelock을 유지하면서 유휴 상태로 있는 것이 응답이 도착할 때 wakelock을 해제하고 절전 모드를 해제하여 정지 상태가 되는 것보다 전력 효율성이 높을 수 있습니다. 전체 시간 T 동안 유휴 상태를 유지하면서 소비한 전력이 동일한 시간 T 동안 유휴 상태에서 정지 상태로, 다시 유휴 상태로 전환하면서 소비한 전력보다 크다면 공급업체는 플랫폼별 전력 측정값을 사용하여 시간 T의 기준값을 결정해야 합니다. 시간 T가 알려진 경우 시간 T보다 오래 걸리는 RIL 명령어는 비동기로 분류되고 나머지 명령어는 동기로 분류될 수 있습니다.

RIL 통신 시나리오

다음 다이어그램은 일반적인 RIL 통신 시나리오를 보여주고 코드 수정 솔루션을 제공하여 요구된 RIL 요청 및 요구되지 않은 RIL 요청을 처리합니다.

참고: 다음 다이어그램에 사용된 함수에 관한 구현 세부정보는 ril.cppacquireWakeLock(), decrementWakeLock(), clearWakeLock( 메서드를 참조하세요.

시나리오: RIL 요청 및 요구된 비동기 응답

이 시나리오에서 요구된 RIL 응답(RIL_REQUEST_GET_AVAILABLE_NETWORKS에 관한 응답)에 상당한 시간이 걸릴 것으로 예상된다면 wakelock은 애플리케이션 프로세서 측에서 오랫동안 유지됩니다. 모뎀 문제로 인해 대기 시간이 길어질 수도 있습니다.

그림 1. 요구된 RIL 비동기 응답

솔루션 1: 모뎀은 RIL 요청 및 비동기 응답의 wakelock을 유지합니다.

그림 2. 모뎀에서 유지되는 wakelock
  1. RIL 요청이 전송되고 모뎀은 wakelock을 획득하여 요청을 처리합니다.
  2. 모뎀이 확인을 전송합니다. 이에 따라 자바 측에서 wakelock 카운터를 감소시키고 카운터값이 0일 때 해제합니다.

    참고: 요청 확인 시퀀스의 wakelock 시간 제한 기간은 현재 사용된 시간 제한 기간보다 짧습니다. 확인이 상당히 빨리 수신되어야 하기 때문입니다.

  3. 요청을 처리한 후 모뎀은 wakelock을 획득하고 ril.cpp에 응답을 전송하는 공급업체 코드에 인터럽트를 전송합니다. ril.cpp는 결과적으로 wakelock을 획득하여 자바 측에 응답을 전송합니다.
  4. 응답이 자바 측에 도달하면 wakelock이 획득되고 응답이 호출자에게 반환됩니다.
  5. 응답이 모든 모듈에서 처리되면 소켓을 통해 확인이 ril.cpp에 다시 전송되고 3단계에서 획득한 wakelock이 해제됩니다.

솔루션 2: 모뎀이 wakelock을 유지하지 않고 응답이 빠릅니다(동기 RIL 요청 및 응답). 동기 대 비동기 동작은 특정 RIL 명령어에 하드코딩되고 호출별로 판단됩니다.

그림 3. 모뎀에서 유지하지 않는 wakelock
  1. RIL 요청은 자바 측에서 acquireWakeLock()을 호출하여 전송됩니다.
  2. 공급업체 코드는 wakelock을 획득할 필요가 없으며 요청을 처리하고 신속하게 응답할 수 있습니다.
  3. 자바 측에서 응답을 수신하면 decrementWakeLock()이 호출되어 wakelock 카운터가 감소하고 카운터값이 0이면 wakelock이 해제됩니다.

시나리오: 요구되지 않은 RIL 응답

이 시나리오에서 요구되지 않은 RIL 응답에는 공급업체 응답을 위해 wakelock을 획득해야 하는지 여부를 표시하는 wakelock 유형 플래그가 있습니다. 플래그가 설정되면 시간이 지정된 wakelock이 설정되고 응답은 소켓을 통해 자바 측에 전송됩니다. 타이머가 만료되면 wakelock이 해제됩니다. 시간이 지정된 wakelock은 요구되지 않은 다양한 RIL 응답에 너무 길거나 너무 짧을 수 있습니다.

그림 4. 요구되지 않은 RIL 응답

솔루션: 요구되지 않은 응답을 전송하는 동안 시간이 지정된 wakelock을 네이티브 측에 유지하지 않고 자바 코드에서 네이티브 측(ril.cpp)으로 확인이 전송됩니다.

그림 5. 시간이 지정된 wakelock 대신 확인 사용

새로운 wakelock 확인

RIL 호출이 동기 또는 비동기로 식별되는지 확인하세요. 배터리 전력 소모는 하드웨어/플랫폼에 따라 달라질 수 있으므로 공급업체는 내부 테스트를 실행하여 비동기 호출에 새로운 wakelock 시맨틱을 사용하면 배터리 전력 소비가 줄어드는지 확인해야 합니다.