Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

Instrument Cluster

Instrument Cluster API(Android API)를 사용하여 Google 지도를 포함한 내비게이션 앱을 자동차의 보조 디스플레이(예: 핸들 뒤의 계기판)에 표시합니다. 이 문서에서는 보조 디스플레이를 제어하는 서비스를 만든 다음, 내비게이션 앱이 사용자 인터페이스를 표시할 수 있도록 서비스를 CarService와 통합하는 방법을 설명합니다.

용어

다음 용어는 이 문서 전체에서 사용됩니다.

용어 설명
CarInstrumentClusterManager 외부 앱이 Instrument Cluster에서 활동을 시작하고 Instrument Cluster가 활동을 표시할 수 있을 때 콜백을 수신하도록 하는 CarManager입니다.
CarManager 외부 앱이 CarService에서 구현되는 자동차 관련 서비스와 상호작용하는 데 사용되는 모든 관리자의 기본 클래스입니다.
CarService 외부 앱(Google 지도 포함)과 자동차 관련 기능(예: Instrument Cluster 액세스) 간에 통신을 제공하는 Android 플랫폼 서비스입니다.
목적지 차량이 이동할 최종 목적지입니다.
ETA 목적지의 예상 도착 시간입니다.
HU(헤드 단위) 자동차에 삽입된 기본 전산 단위입니다. HU는 모든 Android 코드를 실행하며 자동차의 중앙 디스플레이에 연결됩니다.
Instrument Cluster 핸들 뒤 자동차 계기 사이에 있는 보조 디스플레이입니다. 이는 자동차의 내부 네트워크(CAN 버스)를 통해 HU에 연결된 독립적인 전산 단위이거나 HU에 연결된 보조 디스플레이일 수 있습니다.
InstrumentClusterRenderingService Instrument Cluster 디스플레이와 상호연결하는 데 사용되는 서비스의 기본 클래스입니다. OEM은 OEM별 하드웨어와 상호작용하는 이 클래스의 확장 프로그램을 제공해야 합니다.
KitchenSink 앱 Android Automotive에 포함된 테스트 애플리케이션입니다.
경로 차량이 목적지에 도착하기 위해 이동하는 구체적인 경로입니다.
싱글톤 서비스 android:singleUser 속성이 있는 Android 서비스입니다. 언제든지 최대 1개의 서비스 인스턴스가 Android 시스템에서 실행됩니다.

사전 준비 사항

통합을 개발하려면 다음 요소가 있어야 합니다.

  • Android 개발 환경. Android 개발 환경을 설정하려면 빌드 요구사항을 참조하세요.
  • Android 소스 코드 다운로드. pi-car-release 분기의 최신 Android 소스 코드 버전(또는 이상)을 https://android.googlesource.com에서 가져옵니다.
  • HU(헤드 단위). Android 9 이상을 실행할 수 있는 Android 기기입니다. 이 기기에는 자체 디스플레이가 있어야 하며 새로운 Android 빌드로 디스플레이를 플래시할 수 있어야 합니다.
  • Instrument Cluster는 다음 중 하나입니다.
    • HU에 연결된 물리적 보조 디스플레이. 기기 하드웨어 및 커널이 여러 디스플레이의 관리를 지원하는 경우입니다.
    • 독립적인 단위. 자체 디스플레이에서 동영상 스트림을 수신하고 표시할 수 있는 네트워크 연결을 통해 HU에 연결된 전산 단위입니다.
    • 에뮬레이션된 디스플레이. 개발 중에 다음 에뮬레이션된 환경 중 하나를 사용할 수 있습니다.
      • 시뮬레이션된 보조 디스플레이. AOSP Android 배포에서 시뮬레이션된 보조 디스플레이를 사용 설정하려면 설정 시스템 애플리케이션의 개발자 옵션 설정으로 이동한 다음, 보조 디스플레이 시뮬레이션을 선택합니다. 이 구성은 물리적 보조 디스플레이를 연결하는 것과 같으며, 이 디스플레이가 기본 디스플레이에 중첩된다는 제한이 있습니다.
      • 에뮬레이션된 계기판. Android Automotive에 포함된 Android Emulator는 Android 에뮬레이터 _qemu-pipes를 통해 계기판을 표시하는 옵션을 제공합니다. DirectRenderingClusterSample 참조 계기판 구현을 사용하여 에뮬레이션된 외부 디스플레이에 연결합니다.

통합 아키텍처

통합 구성요소

Instrument Cluster API 통합은 다음 3개 구성요소로 구성됩니다.

  • CarService
  • 내비게이션 앱.
  • OEM Instrument Cluster 서비스

통합 구성요소

CarService

CarService는 내비게이션 앱과 자동차 간에 중재하여 언제든지 하나의 내비게이션 앱만 활성화되고 android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL 권한이 있는 앱만 자동차에 데이터를 보낼 수 있도록 합니다.

CarService는 모든 자동차 관련 서비스를 부트스트랩하고 일련의 관리자를 통해 관련 서비스에 액세스할 수 있는 권한을 제공합니다. 서비스와 상호작용하기 위해 자동차에서 실행되는 애플리케이션은 이러한 관리자에 액세스할 수 있습니다.

계기판 구현의 경우 자동차 OEM은 InstrumentClusterRendererService의 맞춤 구현을 만들고 이 맞춤설정된 구현을 가리키도록 config.xml 파일을 업데이트해야 합니다.

Instrument Cluster를 렌더링할 때 부팅 프로세스 중에 CarService는 config.xml의 InstrumentClusterRendererService 키를 읽어서 InstrumentClusterService 구현을 찾습니다. AOSP에서 이 항목은 Navigation State API 샘플 클러스터 구현 렌더링 서비스를 가리킵니다.

<string name="instrumentClusterRendererService">
android.car.cluster/.ClusterRenderingService
</string>

이 항목에서 참조된 서비스는 초기화되고 CarService에 바인드됩니다. Google 지도 같은 내비게이션 앱이 CarInstrumentClusterManager를 요청하면 CarService는 바인드된 InstrumentClusterRenderingService에서 Instrument Cluster 상태를 업데이트하는 관리자를 제공합니다. 이 경우 바인드Android 서비스를 나타냅니다.

Instrument Cluster 서비스

OEM은 InstrumentClusterRendererService의 서브클래스가 포함된 APK(Android PacKage)를 만들어야 합니다. 샘플은 ClusterRenderingService를 참조하세요.

이 클래스는 다음 두 가지 목적으로 사용됩니다.

  • Android와 Instrument Cluster 렌더링 기기 간에 인터페이스를 제공합니다(이 문서의 목적).
  • 세부 경로 안내 탐색 안내와 같은 탐색 상태 업데이트를 수신하고 렌더링합니다.

첫 번째 목적으로, InstrumentClusterRendererService의 OEM 구현은 차량 실내에서 화면에 정보를 렌더링하고 InstrumentClusterRendererService.setClusterActivityOptions()InstrumentClusterRendererService.setClusterActivityState() 메서드를 호출하여 이 정보를 CarService에 전달하는 데 사용되는 보조 디스플레이를 초기화해야 합니다.

두 번째 기능을 위해 Instrument Cluster 서비스는 eventType으로 인코딩되는 탐색 상태 업데이트 이벤트 및 번들로 인코딩된 이벤트 데이터를 수신하는 NavigationRenderer 인터페이스의 구현을 제공해야 합니다.

통합 시퀀스

다음 다이어그램은 업데이트를 렌더링하는 탐색 상태의 구현을 보여 줍니다.

통합 시퀀스

범례:

  • 노란색. Android 플랫폼에서 제공하는 CarService 및 CarNavigationStatusManager입니다.
  • 녹청색. OEM이 구현하는 InstrumentClusterRendererService입니다.
  • 자주색. Google 및 타사 개발자가 구현하는 내비게이션 앱입니다.
  • 녹색. CarAppFocusManager입니다.

탐색 상태 정보 흐름은 다음 시퀀스를 따릅니다.

  1. CarService는 InstrumentClusterRenderingService를 초기화합니다.
  2. 초기화 중에 InstrumentClusterRenderingService는 CarService를 다음으로 업데이트합니다.
    1. 뚜렷한 경계와 같은 Instrument Cluster 디스플레이 속성입니다(나중에 뚜렷한 경계에 관한 자세한 내용 참조).
    2. Instrument Cluster 디스플레이 내부에서 활동을 시작하는 데 필요한 활동 옵션입니다(ActivityOptions에서 자세한 내용 참조).
  3. 내비게이션 앱(예: Android Automotive용 Google 지도 또는 필요한 권한을 가진 지도 앱):
    1. car-lib에서 Car 클래스를 사용하여 CarAppFocusManager를 가져옵니다.
    2. 세부 경로 안내가 시작되기 전에 CarAppFocusManager.requestFocus()를 호출하여 CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATIONappType 매개변수로 전달합니다.
  4. CarAppFocusManager는 이 요청을 CarService에 전달합니다. 권한이 부여된 경우 CarService는 내비게이션 앱 패키지를 검사하고 android.car.cluster.NAVIGATION 카테고리로 표시된 활동을 찾습니다.
  5. 찾은 경우 내비게이션 앱은 InstrumentClusterRenderingService에서 보고한 ActivityOptions를 사용하여 활동을 시작하고 Instrument Cluster 디스플레이 속성을 인텐트에 extras로 포함합니다.

API 통합

InstrumentClusterRenderingService 구현은 다음을 충족해야 합니다.

  • AndroidManifest.xml에 다음 값을 추가하여 싱글톤 서비스로 지정되어야 합니다. 초기화 및 사용자 전환 중에도 Instrument Cluster 서비스의 단일 복사본이 실행되도록 하려면 이 작업이 필요합니다.
    android:singleUser="true"
  • BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE 시스템 권한을 보유해야 합니다. 이렇게 하면 Android 시스템 이미지의 일부로 포함된 Instrument Cluster 렌더링 서비스만 CarService에 바인드됩니다.
    <uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>

InstrumentClusterRenderingService 구현

서비스를 빌드하려면:

  1. InstrumentClusterRenderingService에서 확장되는 클래스를 작성한 다음, AndroidManifest.xml 파일에 상응하는 항목을 추가합니다. 이 클래스는 Instrument Cluster 디스플레이를 제어하며 Navigation State API 데이터를 (필요한 경우) 렌더링할 수 있습니다.
  2. onCreate() 중에 이 서비스를 사용하여 렌더링 하드웨어와의 통신을 초기화합니다. 다음과 같은 옵션이 있습니다.
    • Instrument Cluster에 사용할 보조 디스플레이를 결정합니다.
    • Instrument Cluster 앱이 이미지를 렌더링하고 렌더링된 이미지를 외부 단위에 전송(H.264와 같은 동영상 스트리밍 형식 사용)하도록 가상 디스플레이를 만듭니다.
  3. 위에 표시된 디스플레이가 준비되면 이 서비스는 InstrumentClusterRenderingService#setClusterActivityLaunchOptions()를 호출하여 Instrument Cluster에서 활동을 표시하는 데 사용해야 하는 정확한 ActivityOptions를 정의해야 합니다. 다음 매개변수를 사용합니다.
    • category. CarInstrumentClusterManager#CATEGORY_NAVIGATION
    • ActivityOptions. Instrument Cluster에서 활동을 시작하는 데 사용할 수 있는 ActivityOptions 인스턴스입니다. 예를 들어 AOSP의 샘플 Instrument Cluster 구현에서 시작합니다.
      getService().setClusterActivityLaunchOptions(
         CATEGORY_NAVIGATION,
         ActivityOptions.makeBasic()
            .setLaunchDisplayId(displayId));
      
    • Instrument Cluster가 활동을 표시할 준비가 되면 이 서비스는 다음을 호출해야 합니다.
      InstrumentClusterRenderingService#setClusterActivityState()

      다음 매개변수를 사용합니다.
      • category. CarInstrumentClusterManager#CATEGORY_NAVIGATION
      • state. ClusterActivityState를 사용하여 생성된 번들입니다. 다음 데이터를 제공해야 합니다.
        • visible. Instrument Cluster를 공개 가능 및 콘텐츠 표시 가능으로 지정합니다.
        • unobscuredBounds. 콘텐츠를 안전하게 표시할 수 있는 Instrument Cluster 디스플레이 내 영역을 정의하는 직사각형입니다. 다이얼 및 게이지가 적용되는 영역을 예로 들 수 있습니다.
    • Service#dump() 메서드를 재정의하고 디버깅에 유용한 상태 정보를 보고합니다(자세한 내용은 dumpsys 참조).

샘플 InstrumentClusterRenderingService 구현

다음 예에서는 원격 물리적 디스플레이에 Instrument Cluster 콘텐츠를 표시할 VirtualDisplay를 만드는 InstrumentClusterRenderingService 구현을 개략적으로 보여 줍니다.

또는 위의 설명대로 이 코드는 HU에 연결된 물리적 보조 디스플레이의 displayId를 전달할 수 있습니다(사용 가능한 것으로 알려진 경우).

/**
* Sample {@link InstrumentClusterRenderingService} implementation
*/
public class SampleClusterServiceImpl extends InstrumentClusterRenderingService {
   // Used to retrieve or create displays
   private final DisplayManager mDisplayManager;
   // Unique identifier for the display that will be used for instrument
   // cluster
   private final String mUniqueId = UUID.randomUUID().toString();
   // Format of the instrument cluster display
   private static final int DISPLAY_WIDTH = 1280;
   private static final int DISPLAY_HEIGHT = 720;
   private static final int DISPLAY_DPI = 320;
   // Area not covered by instruments
   private static final int DISPLAY_UNOBSCURED_LEFT = 40;
   private static final int DISPLAY_UNOBSCURED_TOP = 0;
   private static final int DISPLAY_UNOBSCURED_RIGHT = 1200;
   private static final int DISPLAY_UNOBSCURED_BOTTOM = 680;
   @Override
   public void onCreate() {
      super.onCreate();
      // Create a virtual display to render instrument cluster activities on
      mDisplayManager = getSystemService(DisplayManager.class);
      VirtualDisplay display = mDisplayManager.createVirtualDisplay(
          mUniqueId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_DPI, null,
          0 /* flags */, null, null);
      // Do any additional initialization (e.g.: start a video stream
      // based on this virtual display to present activities on a remote
      // display).
      onDisplayReady(display.getDisplay());
}
private void onDisplayReady(Display display) {
    // Report activity options that should be used to launch activities on
    // the instrument cluster.
    String category = CarInstrumentClusterManager.CATEGORY_NAVIGATION;
    ActionOptions options = ActivityOptions.makeBasic()
        .setLaunchDisplayId(display.getDisplayId());
    setClusterActivityOptions(category, options);
    // Report instrument cluster state.
    Rect unobscuredBounds = new Rect(DISPLAY_UNOBSCURED_LEFT,
        DISPLAY_UNOBSCURED_TOP, DISPLAY_UNOBSCURED_RIGHT,
        DISPLAY_UNOBSCURED_BOTTOM);
    boolean visible = true;
    ClusterActivityState state = ClusterActivityState.create(visible,
       unobscuredBounds);
    setClusterActivityState(category, options);
  }
}

부록: 샘플 애플리케이션 사용

AOSP는 Navigation State API를 구현하는 샘플 애플리케이션을 제공합니다.

이 샘플 애플리케이션을 실행하려면:

  1. 지원되는 HU에서 Android Auto를 빌드하고 플래시합니다. 사용 중인 기기와 관련된 Android 빌드 및 플래시 안내를 사용합니다. 자세한 내용은 참조 보드 사용을 참조하세요.
  2. 물리적 보조 디스플레이를 HU(지원되는 경우)에 연결하거나 가상 보조 HU를 사용 설정합니다.
    1. 설정 앱에서 개발자 모드를 선택합니다.
    2. 설정 > 시스템 > 고급 > 개발자 옵션 > 보조 디스플레이 시뮬레이션으로 이동합니다.
  3. HU를 재부팅합니다. ClusterRenderingService 서비스가 보조 디스플레이에 연결됩니다.
  4. KitchenSink 앱을 시작하려면:
    1. 창을 엽니다.
    2. Instrument Cluster로 이동합니다.
    3. 메타데이터 시작을 클릭합니다.

KitchenSink는 NAVIGATION 포커스를 요청합니다. 이 포커스는 DirectRenderingCluster 서비스가 Instrument Cluster에서 모의 사용자 인터페이스를 표시하도록 지시합니다.