Inicio rápido: Crea y ejecuta paquetes de servicios de SDV

En esta página, se muestra cómo crear un paquete de servicios de SDV, empaquetarlo en el formato de archivo APEX y ejecutarlo en un dispositivo virtual Cuttlefish. Las unidades principales de ejecución de código en el sistema de SDV son los paquetes de servicios. Los paquetes de servicios proporcionan métodos de ciclo de vida que el sistema ejecuta cuando cambia su estado.

  1. Cómo configurar tu entorno de compilación

    Desde tu directorio de trabajo, obtén la secuencia de comandos envsetup.sh para configurar el entorno de compilación, establece Cuttlefish como destino de compilación y compila el generador de código vsidlc:

    source build/envsetup.sh
    lunch sdv_core_cf-aosp_current-userdebug
    m vsidlc
    
  2. Define tu arquitectura creando una carpeta llamada my_catalog con estos archivos:

    • tire.proto: Define la estructura de datos que envías:

      syntax = "proto3";
      
      package com.android.sdv.sample.quickstart;
      
      import "google/protobuf/empty.proto";
      import "sdv/vsidl/v1/annotations.proto";
      
      message TirePressure {
        uint32 pressure = 1;
      }
      
      message TireInfoResponse {
        string serial_number = 1;
        uint32 max_pressure = 2;
      }
      
      service TireService {
        rpc GetTireInfo(google.protobuf.Empty) returns (TireInfoResponse);
      }
      
    • architecture.vsidl: Define los paquetes de servicios y su comunicación (para ver el resaltado de sintaxis, la validación y el autocompletado en Android Studio para Platform, consulta Cómo editar archivos VSIDL):

      package: "com.android.sdv.sample.quickstart"
      
      service_bundle {
        name: "Manager"
      
        publisher {
          message: "TirePressure"
          topic: "pressure"
          capacity: 8
        }
      
        server {
          service: "TireService"
          channel: "tire-service"
        }
      }
      
      service_bundle {
        name: "Monitor"
      
        subscriber {
          message: "TirePressure"
          topic: "pressure"
        }
      
        client {
          service: "TireService"
          channel: "tire-service"
        }
      }
      
    • Android.bp: Define el proceso de compilación:

      rust_protobuf {
          name: "libquickstart_sample_tire_proto",
          crate_name: "quickstart_sample_tire_proto",
          protos: [
              "tire.proto",
          ],
          source_stem: "quickstart_sample_tire_proto_source",
          rustlibs: [
              "libvsidl_v1_stdlib_proto_rs",
          ],
          proto_flags: [
              "-I external/protobuf/src",
          ],
          vendor_available: true,
          product_available: true,
          apex_available: [
              "//apex_available:platform",
              "//apex_available:anyapex",
          ],
          min_sdk_version: "35",
      }
      
      filegroup {
          name: "vsidl_quickstart_catalog",
          srcs: ["**/*"],
      }
      
  3. Genera una implementación de esqueleto y archivos de configuración ejecutando lo siguiente:

    vsidlc -c /path/to/catalog -o /path/to/output --services --apex
    
  4. Para cada paquete de servicios, busca la implementación de Rust en /path/to/output/services/ServiceBundleName/src/main.rs.

  5. De forma predeterminada, la implementación generada crea mensajes con valores predeterminados y los envía entre publicadores y suscriptores o clientes y servidores de RPC. Para modificar este comportamiento, busca los comentarios de TODO en main.rs y ajústalos según tus preferencias. Por ejemplo:

    rust async fn handle_tire_pressure_pressure_publisher(publisher: sdv::mw::Publisher<TirePressure>) { loop { // TODO: Modify the frequency of publishing messages here. sleep(Duration::from_secs(1)).await; // TODO: Modify the message content here. let message = TirePressure::default(); info!("Publishing on TirePressure#PRESSURE"); publisher.publish(&message).unwrap(); } }

  6. Para incluir tu paquete en la imagen del sistema, agrega el nombre del módulo APEX generado al archivo makefile de tu producto.

    1. Abre el archivo makefile de tu producto (por ejemplo, device/google/sdv/sdv_core_base/sdv_samples_core_services.mk).

    2. Agrega el módulo a PRODUCT_PACKAGES con lo siguiente:

      PRODUCT_PACKAGES += com.android.sdv.sample.quickstart
      PRODUCT_PACKAGES += com_android_sdv_sample_quickstart_orchestration_configurations
      
  7. Compila la imagen:

    m
    

    Después de que la imagen del sistema incluya el APEX (o la clave que se usa para firmarlo), también puedes compilar e implementar cambios iterativos directamente desde el ícono de margen apex/Android.bp en Android Studio for Platform. Para obtener más información, consulta Implementa paquetes de servicios de SDV.

  8. Ejecuta y verifica la ejecución del paquete de servicios:

    1. Inicia un dispositivo virtual de Cuttlefish:

      sdv-cf create --instance_name=instance1
      
    2. Ejecuta el paquete de servicios cuando se inicie el sistema:

      • De forma manual:

        adb wait-for-device
        adb root
        adb shell sdv_service_bundle start local-vm:com.android.sdv.sample.quickstart.Manager/instance
        adb shell sdv_service_bundle start local-vm:com.android.sdv.sample.quickstart.Monitor/instance
        
      • Usa el organizador:

        adb wait-for-device
        adb root
        # Apply global orchestration configuration by setting system property
        adb shell setprop persist.sdv.orchestrator_config_path "etc/orch/vm_quickstart_orch_config.textproto"
        adb reboot
        
    3. Verifica la ejecución del paquete de servicios:

      adb logcat *:F com_android_sdv_sample_quickstart_Manager_instance:* com_android_sdv_sample_quickstart_Monitor_instance:*
      

      Este comando muestra registros que indican que los paquetes de servicios intercambian mensajes:

      03-30 13:41:31.505   967   976 I com_android_sdv_sample_quickstart_Manager_instance: sdv_lm_manager: Publishing on TirePressure#PRESSURE
      03-30 13:41:31.505   983   991 I com_android_sdv_sample_quickstart_Monitor_instance: sdv_lm_monitor: Received message on TirePressure#PRESSURE: [TirePressure { pressure: 0, special_fields: SpecialFields { unknown_fields: UnknownFields { fields: None }, cached_size: CachedSize { size: 0 } } }]
      03-30 13:41:31.626   983   991 I com_android_sdv_sample_quickstart_Monitor_instance: sdv_lm_monitor: Sending request on Monitor/TireService
      03-30 13:41:31.627   967   976 I com_android_sdv_sample_quickstart_Manager_instance: sdv_lm_manager: Received request on Manager/TireService: Empty { special_fields: SpecialFields { unknown_fields: UnknownFields { fields: None }, cached_size: CachedSize { size: 0 } } }
      03-30 13:41:31.627   983   991 I com_android_sdv_sample_quickstart_Monitor_instance: sdv_lm_monitor: Received response on Monitor/TireService: TireInfoResponse { serial_number: "", max_pressure: 0, special_fields: SpecialFields { unknown_fields: UnknownFields { fields: None }, cached_size: CachedSize { size: 0 } } }
      

¿Qué sigue?

Obtén más información sobre el lenguaje de definición de interfaz de servicios para vehículos (VSIDL) y cómo definir tus propios paquetes de servicios desde cero.