Architektur und Implementierungsleitfaden für Nutzereinstellungen

Auf dieser Seite finden Sie eine Anleitung zur Architektur des SDV User Preferences-Systems sowie eine Anleitung zur Implementierung eines nutzersteuerbaren Dienstes und Clients.

Architektur

Das System für Nutzereinstellungen entkoppelt die Speicherung und Verwaltung von Nutzereinstellungen von der Durchsetzung und Anwendung dieser Einstellungen. Die wichtigsten architektonischen Begriffe sind in der Tabelle zusammengefasst:

FunktionBeschreibungRolleVerantwortung
Vom Nutzer steuerbarer Dienst Ein Standard-SDV-Service-Bundle, das eine bestimmte Domain verwaltet (z. B. HLK, Autositze, Audio) Gibt den beabsichtigten Status der Funktionen und Einschränkungen der Hardware oder des Subsystems an, das es steuert.
  • Registrierung:Informiert den Agent für Nutzereinstellungen über die unterstützten Einstellungen (Metadaten, Standardwerte, Einschränkungen).
  • Durchsetzung und Autonomie:Empfängt Anfragen zum Ändern von Einstellungen, validiert sie anhand des aktuellen Status und der Sicherheitsregeln und wendet sie auf die Hardware an. Behält die volle Autonomie bei und gibt an, ob eine Einstellungsänderung akzeptiert oder abgelehnt wird.
Agent für Nutzereinstellungen Der zentrale Orchestrator Bietet zentralen Speicher, Nutzerprofilverwaltung und Benachrichtigungshub.
  • Speicher:Einstellungen werden pro Nutzer (z. B. Fahrer, Beifahrer) gespeichert.
  • Routing:Proxys leiten Anfragen von Clients (z. B. Mensch-Maschine-Schnittstelle (HMI)) an den entsprechenden vom Nutzer steuerbaren Dienst weiter.
  • Benachrichtigungen:Änderungen werden über die ChangeNotifier-Schnittstelle an Interessierte (Ansichten oder HMIs) gesendet.
  • Nutzerverwaltung:Hier wird der Nutzerwechsel verwaltet und der richtige persistente Status auf alle registrierten Dienste angewendet.
Client für Nutzereinstellungen Eine App oder ein Dienst, die bzw. der eine Benutzeroberfläche bietet, z. B. eine IVI-App mit einer HMI oder einer anderen Logik, die mit den Nutzereinstellungen interagieren muss Interagiert mit Nutzern, zeigt Einstellungen an und initiiert Änderungsanfragen.
  • Anzeige:Hier werden dem Nutzer die aktuellen Einstellungen und Einschränkungen angezeigt.
  • Änderungen anfordern:Sendet vom Nutzer initiierte Einstellungsänderungen an den Agent für Nutzereinstellungen.
  • Benachrichtigungen erhalten:Abonniert und reagiert auf Echtzeitaktualisierungen von Einstellungen.

Vom Nutzer steuerbaren Dienst implementieren

Damit der User Preferences-Agent weiß, welche Schlüssel vorhanden sind, welche Datentypen sie haben, welche Standardwerte und welche Einschränkungen (z. B. Mindest- und Höchstwerte) gelten, muss Ihr Service-Bundle mit der UserPreferencesRegistryService-Schnittstelle interagieren. Wenn Ihr Dienst gestartet wird, müssen die von ihm bereitgestellten Einstellungen registriert werden. Der Agent ruft RequestSettingsChange in Ihrem Dienst auf, wenn ein Nutzer versucht, eine Einstellung zu ändern (oder wenn er den Nutzer wechselt).

Folgen Sie der Anleitung in diesem Abschnitt, damit Nutzerpräferenzen (und ein Nutzer mit HMI) Ihren Dienst steuern können.

  1. Definieren Sie Dienstschnittstellen in der VSIDL-Datei:

    • Implementieren Sie als Server com.sdv.google.user_preferences.user_controllable.UserControllableService. So kann der KI‑Agent Ihnen Änderungsanfragen senden.
    • Als Kunde com.sdv.google.user_preferences.UserPreferencesRegistryService nutzen. Dadurch werden Ihre Einstellungen beim Start registriert.

    Das folgende Beispiel zeigt service_bundle.vsidl für einen vom Nutzer steuerbaren Dienst:

    service_bundle {
        name: "MyFeatureService"
        server {
            service: "com.sdv.google.user_preferences.user_controllable.UserControllableService"
        }
        client {
            service: "com.sdv.google.user_preferences.UserPreferencesRegistryService"
        }
    }
    
  2. Registrieren Sie die Einstellungen beim Start im Schlüssel-Proto user_preferences_registry_service.proto:

    1. Stellen Sie eine Verbindung mit UserPreferencesRegistryService her.
    2. Erstellen Sie eine Instanz von RegisterSettingsRequest.
    3. Definieren Sie eine Instanz von SettingsGroup (eine logische Sammlung von Einstellungen).
    4. Legen Sie für jede Einstellung Folgendes fest:

      *   **Key:** Unique string ID (for example, `TEMPERATURE`)
      *   **Kind:** `PER_USER` (stored per user profile) or `SHARED`
          (global)
      *   **Default value:** Initial value if no user preference exists
      *   **Constraints:** (optional) Validation rules (for example, Min
          16, Max 32 for HVAC).
      
    5. Rufen Sie RegisterSettings() an.

    Das folgende Beispiel ist in konzeptionellem Rust:

    let temperature_setting = SettingDefinition {
        name: "TEMPERATURE".to_string(),
        kind: SettingKind::PER_USER.into(),
        default_value: Value::Int64(22), // Default 22 degrees
        constraint: Some(Constraints::Int64Constraints(Int64Constraints {
            min_value: Some(16),
            max_value: Some(32),
            ..Default::default()
        })),
        ..Default::default()
    };
    
    registry_client.RegisterSettings(&RegisterSettingsRequest {
        group_name: "HVAC".to_string(),
        version: "1.0".to_string(),
        settings_definitions: vec![temperature_setting],
    }).await?;
    
  3. So bearbeiten Sie Anfragen zur Änderung von Einstellungen in user_controllable_service.proto:

    1. Implementieren Sie den RequestSettingsChange-RPC.
    2. Prüfen, ob die angeforderten Werte im aktuellen Kontext gültig sind (z. B. ob die Hardware bereit ist).
    3. Wenden Sie eine bestimmte Logik an, um die Änderung vorzunehmen (z. B. den Sitz zu verstellen oder die Lüftergeschwindigkeit zu ändern).
    4. Gibt die angewendeten Werte in RequestSettingsChangeResponse zurück:
    5. Wenn Sie die Änderung akzeptiert haben, geben Sie den neuen Wert zurück.
    6. Wenn Sie den Wert abgelehnt oder begrenzt haben, geben Sie den von Ihnen festgelegten (oder beibehaltenen) Wert zurück.

    Das folgende Beispiel ist in konzeptionellem Rust:

    async fn RequestSettingsChange(
        &self,
        _caller_id: ServiceFqin,
        request: &RequestSettingsChangeRequest
    ) -> SdvResult<RequestSettingsChangeResponse> {
        let mut applied_settings = Vec::new();
    
        for setting in &request.settings {
            if self.hardware.set_value(setting.key, setting.value).is_ok() {
                // Change accepted
                applied_settings.push(setting.clone());
            } else {
                // Change rejected, return current actual value
                let current_val = self.hardware.get_value(setting.key);
                applied_settings.push(create_setting(setting.key, current_val));
            }
        }
    
        Ok(RequestSettingsChangeResponse {
            settings: applied_settings,
        })
    }
    
  4. Implementieren Sie den FactoryReset-RPC, um das Subsystem in einen sauberen Zustand zurückzusetzen:

    1. Alle Einstellungen auf die Standardwerte zurücksetzen (wie in der Codekonfiguration definiert).
    2. Rufen Sie UpdateSettings für den Registrierungsdienst auf, um den Agenten darüber zu informieren, dass sich die Werte extern geändert haben (durch das Zurücksetzen, nicht durch eine Nutzeranfrage).

Abwärtskompatibilität und Schema-Evolution

Das Schema der Einstellungen, die von einem vom Nutzer steuerbaren Dienst definiert werden, gilt als öffentliche Schnittstelle. Diese Schnittstelle wird vom Agent für Nutzereinstellungen und verschiedenen Clients (z. B. HMIs) verwendet, die möglicherweise unterschiedliche Release-Zeitpläne haben. Daher ist die Aufrechterhaltung einer strengen Abwärtskompatibilität unerlässlich, um Systeminstabilität und Clientfehler zu vermeiden.

Kompatible Änderungen

Bei einem vom Nutzer steuerbaren Dienst sollten nur kompatible Änderungen am Einstellungs-Schema vorgenommen werden. Diese Änderungen sorgen dafür, dass ältere Clients ohne Updates weiterhin korrekt funktionieren:

  • Fügen Sie eine neue, optionale Einstellung mit einem angemessenen Standardwert hinzu:

    • Diese Einstellung ist optional. Clients müssen also prüfen, ob sie vorhanden ist, um verschiedene Versionen des Dienstes zu unterstützen.
    • Clients ignorieren diese Einstellung, wenn sie nicht aktualisiert wurden, um sie zu erkennen.
    • Wenn keine Nutzereinstellung für die neue Einstellung vorhanden ist, verwendet der Kundenservicemitarbeiter den angegebenen Standardwert.

Inkompatible Änderungen

Die folgenden Änderungen gelten als schwerwiegend und sind verboten, da sie ältere Clients sofort beeinträchtigen:

  • Vorhandene Einstellung entfernen

  • Ändern Sie die Bedeutung, Einheit oder den Datentyp einer vorhandenen Einstellung (z. B. von einer Ganzzahl, die die Temperatur in Grad Celsius darstellt, zu einer Gleitkommazahl, die den Druck in Pascal darstellt).

  • Ändern Sie den Standardwert einer vorhandenen Einstellung. Der Hauptgrund für das Verbot von Änderungen an Standardwerten ist die potenzielle Komplikation bei der Migration persistenter Daten. Der Agent speichert Einstellungen basierend auf dem Registrierungsschema des Dienstes. Das Ändern eines Standardwerts würde eine komplexe Logik erfordern, um alle vorhandenen Nutzerprofile auf den neuen Standard zu migrieren. Andernfalls würde für Nutzer, die die Einstellung nie explizit festgelegt haben, ein technisch falscher Wert verwendet.

Erforderliche funktionsgefährdende Änderungen vornehmen

Wenn eine einschneidende Änderung erforderlich ist, darf der Dienst die vorhandene Einstellung nicht ändern. Die Vorgehensweise zur Verwaltung dieser Umstellung bei gleichzeitiger Aufrechterhaltung der Kompatibilität ist hauptsächlich in der vom Nutzer steuerbaren Dienstlogik zu finden:

  1. Erstellen Sie eine neue Einstellung mit der gewünschten neuen Definition, dem gewünschten neuen Schlüssel oder der gewünschten neuen Einheit.
  2. Stellen Sie die vorhandene Einstellung ein, indem Sie sie für die Kompatibilität registrieren. Verwenden Sie diese neue Einstellung, wenn Sie neue Clients entwickeln.
  3. Raten Sie neuen Kunden, Kompatibilitätslogik in die Geschäftslogik des vom Nutzer steuerbaren Dienstes zu implementieren.

Die RequestSettingsChange-Implementierung des Dienstes muss dafür sorgen, dass sich eine Änderung an einer Einstellung auf das zugehörige eingestellte Pendant auswirkt und umgekehrt.

Beispiel für Kompatibilitätslogik:

  1. Bei einem Dienst wird die alte Einstellung TEMPERATURE_C (Celsius) eingestellt und TEMPERATURE_K (Kelvin) eingeführt.

  2. Wenn der Agent eine Anfrage zum Aktualisieren der Einstellung new sendet:

    • Der Dienst empfängt eine Anfrage für TEMPERATURE_K (z. B. 295, 15 K).

    • Die Logik des Dienstes wandelt diesen Wert in Grad Celsius (22 °C) um und aktualisiert und speichert intern beide Werte, um die Konsistenz für Legacy-Clients aufrechtzuerhalten.

  3. Wenn der Agent eine Anfrage für die eingestellte Einstellung von einem Legacy-Client sendet:

    • Der Dienst empfängt eine Anfrage für TEMPERATURE_C (z. B. 24 °C).
    • Der Dienst rechnet diesen Wert in Kelvin (297,15 K) um und aktualisiert und speichert intern beide Werte.

Diese Dual-Write-Strategie sorgt dafür, dass alle Clients, unabhängig von ihrem Release-Zeitplan, konsistente und genaue Daten lesen. So werden Fehler vermieden, die durch externe Release-Abweichungen verursacht werden.

Client implementieren

So implementieren Sie einen Client (z. B. ein HMI), der mit dem UserPreferences-Agent interagiert:

  1. Definieren Sie Ihr Client-Service-Bundle, um mit bestimmten Benutzeroberflächen für Nutzereinstellungen zu interagieren. In Ihrer VSIDL-Datei:

    • Implementieren Sie als Server com.sdv.google.user_preferences.view.ChangeNotifier, damit der Agent Ihrem Client Echtzeitbenachrichtigungen zu Einstellungsänderungen senden kann.
    • Als Client können Sie com.sdv.google.user_preferences.UserPreferencesManagementService verwenden, um Einstellungsänderungen anzufordern und Updates zu abonnieren.
    • Als Client können Sie com.sdv.google.user_preferences.UserPreferencesAdminService verwenden, um Nutzerprofile zu verwalten (z. B. erstellen, auswählen, löschen, auf Werkseinstellungen zurücksetzen).

    Das folgende Beispiel zeigt eine service_bundle.vsidl-Datei für einen Client:

    service_bundle {
        name: "MyHmiClient"
        server {
            service: "com.sdv.google.user_preferences.view.ChangeNotifier"
        }
        client {
            service: "com.sdv.google.user_preferences.UserPreferencesManagementService"
        }
        client {
            service: "com.sdv.google.user_preferences.UserPreferencesAdminService"
        }
    }
    

    Fügen Sie entsprechende Autorisierungsrichtlinien hinzu. Wenn Sie die Kommunikation für den Agenten für Nutzereinstellungen zulassen möchten, erstellen Sie einen Client für die angegebenen Server. Beispiel:

    server {
        service: "com.sdv.google.user_preferences.view.ChangeNotifier"
        allow_all_channels: true
    }
    client {
        service: "com.sdv.google.user_preferences.UserPreferencesManagementService"
        allow_all_channels: true
    }
    client {
        service: "com.sdv.google.user_preferences.UserPreferencesAdminService"
        allow_all_channels: true
    }
    
  2. Sie können die Anfrageeinstellungen in UserPreferencesManagementService ändern:

    1. Stellen Sie eine Verbindung mit UserPreferencesManagementService her.
    2. Erstellen Sie eine Instanz von RequestSettingsChangeRequest und geben Sie SettingsGroupId und die gewünschten Einstellungen an.
    3. Optional. Legen Sie ChangePersistencePolicy auf PERSISTENT_CHANGE (Standardeinstellung) oder NON_PERSISTENT_CHANGE fest.
    4. Rufen Sie RequestSettingsChange() an.

    Das folgende Beispiel ist in konzeptionellem Rust:

    management_client.RequestSettingsChange(&RequestSettingsChangeRequest {
        settings_group_id: Some(SettingsGroupId {
            service_fqin: hvac_service_fqin.to_string(),
            name: "HVAC".to_string(),
            ..Default::default()
        }).into(),
        settings: vec![Setting {
            key: "TEMPERATURE".to_string(),
            value: Some(Value::Int64(24)),
            ..Default::default()
        }],
        change_persistence_policy: ChangePersistencePolicy::PERSISTENT_CHANGE.into(),
        ..Default::default()
    }).await?;
    
  3. Mit user_preferences_management_service.proto und change_notifier.proto können Sie Änderungen an den Einstellungen abonnieren:

    1. Implementieren Sie den OnSettingsChange-RPC über die ChangeNotifier-Schnittstelle in Ihrem Dienstpaket. Der User Preferences-Agent ruft diese Methode auf, wenn eine Änderung erfolgt.
    2. Stellen Sie eine Verbindung mit UserPreferencesManagementService her.
    3. Erstellen Sie eine SubscribeToSettingsChangeAndGetSettingsRequest, in der Sie die SettingsGroupId angeben, die Sie überwachen möchten.
    4. Wenn Sie den Status der Einstellungen zurückgeben und zukünftige Updates über Ihre OnSettingsChange-Implementierung senden möchten, rufen Sie SubscribeToSettingsChangeAndGetSettings() auf.

    Das folgende Beispiel für die Implementierung der ChangeNotifier-Schnittstelle ist in konzeptionellem Rust:

    #[async_trait]
    impl ChangeNotifier for MyHmiServiceImpl {
        async fn OnSettingsChange(
            &self,
            _caller_id: ServiceFqin,
            request: &OnSettingsChangeRequest,
        ) -> SdvResult<OnSettingsChangeResponse> {
            // Process the active_settings, pending_changes, and persisted_settings
            // Update your UI or internal state accordingly.
            info!("Received settings change for group: {}", request.settings_group_id.name);
            // ...
            Ok(OnSettingsChangeResponse::new())
        }
    }
    

    Das folgende Beispiel für das Abonnieren ist in konzeptionellem Rust:

    management_client.SubscribeToSettingsChangeAndGetSettings(&SubscribeToSettingsChangeAndGetSettingsRequest {
        settings_group_id: Some(SettingsGroupId {
            service_fqin: hvac_service_fqin.to_string(),
            name: "HVAC".to_string(),
            ..Default::default()
        }).into(),
        ..Default::default()
    }).await?;
    
  4. Optional: Clients, die Nutzerprofile verwalten (z. B. eine spezielle Einstellungen-App), können user_preferences_admin_service.proto verwenden, um mit dem Administrator-Dienst zu interagieren:

    1. Stellen Sie eine Verbindung mit UserPreferencesAdminService her.
    2. Verwenden Sie RPCs wie CreateUser, SelectUser, DeleteUser, FactoryReset und ListUsers, um Nutzerprofile zu verwalten.

    Das folgende Beispiel für das Erstellen eines Nutzers ist in konzeptionellem Rust:

    admin_service_client.CreateUser(&CreateUserRequest {
        user: Some(User {
            id: 1,
            flags: UserFlags::DRIVER.value(),
            ..Default::default()
        }).into(),
        ..Default::default()
    }).await?;
    
  5. Mit user_preferences_admin_service.proto können Sie verfügbare Einstellungen und Nutzer über den Administrator-Dienst ermitteln:

    1. Rufen Sie ListUsers() auf der UserPreferencesAdminService auf, um eine Liste aller registrierten Nutzer zu erhalten.
    2. Rufen Sie GetUserSettings(user_id) für die UserPreferencesAdminService auf, um die Einstellungen für einen bestimmten Nutzer abzurufen.

    Das folgende Beispiel für das Auflisten von Nutzern und das Abrufen von Einstellungen ist in konzeptionellem Rust:

    // List all users
    let list_users_response = admin_service_client.ListUsers(&ListUsersRequest::new()).await?;
    info!("Available users: {:?}", list_users_response.users);
    
    // Get settings for a specific user (for example, user with ID 1)
    if let Some(user_id) = list_users_response.users.first().map(|u| u.id) {
        let get_settings_response = admin_service_client.GetUserSettings(&GetUserSettingsRequest {
            user_id,
            ..Default::default()
        }).await?;
        info!("Settings for user {}: {:?}", user_id, get_settings_response.groups);
    }
    

Zusammenfassung des Ablaufs

  1. Der Client wird gestartet und stellt eine Verbindung zu den Verwaltungs- und administrativen Diensten des Agents her.
  2. Der Client ermittelt und abonniert Einstellungs-Gruppen und zeigt den ursprünglichen Status an.
  3. Der Client sendet ein RequestSettingsChange an den Kundenservicemitarbeiter.
  4. Der Agent sendet eine OnSettingsChange-Benachrichtigung mit aktualisierten Einstellungen und dem aktualisierten Status an den Client.

Ein vollständiges Praxisbeispiel finden Sie im HMIService in @samples/user_preferences/v1/.

Agent implementieren

Ein vom Orchestrator gestartetes Dienst-Bundle implementiert den Agent für Nutzereinstellungen. Zur Vereinfachung wird eine Referenzimplementierung bereitgestellt.

Außerdem wird die folgende user_preferences_sample.vsidl-Datei für das Beispiel-Dienstpaket für den Agent bereitgestellt:

package: "com.sdv.oem.user_preferences"

service_bundle {
    name: "UserPreferencesServiceBundle"
    server {
        service: "com.sdv.google.user_preferences.UserPreferencesAdminService"
    }
    server {
        service: "com.sdv.google.user_preferences.UserPreferencesManagementService"
    }
    server {
        service: "com.sdv.google.user_preferences.UserPreferencesRegistryService"
    }
    client {
        service: "com.sdv.google.user_preferences.view.ChangeNotifier"
    }
    client {
        service: "com.sdv.google.user_preferences.user_controllable.UserControllableService"
    }
}

Bei der Implementierung kann die generierte Middleware verwendet werden. Sie sollte in eine rust_ffi_shared kompiliert werden, auf die vom Dienstpaket verwiesen wird, das den Agent für Nutzereinstellungen implementiert:

sdv_service_bundle_metadata {
  # This name must match the agent's Bundle Name
  name: "UserPreferencesServiceBundle"
  version_number: 1
  version_name: "1"

  native_library_path: "lib64/<USER-PREFERENCES-FFI-LIB>.so"

  orchestration_config_path: "etc/user_preferences_service_bundle/<USER-PREFERENCES-ORCHESTRATION>.textproto"

  authorization_policy_path: "etc/user_preferences_service_bundle/permissions.textproto"
}

Für die Autorisierungsrichtliniendatei .textproto des Clients sind die erforderlichen Berechtigungen erforderlich:

client {
    service: "com.sdv.google.user_preferences.UserPreferencesManagementService"
    allow_all_channels: true
}

client {
    service: "com.sdv.google.user_preferences.UserPreferencesRegistryService"
    allow_all_channels: true
}

client {
    service: "com.sdv.google.user_preferences.UserPreferencesAdminService"
    allow_all_channels: true
}

Anhang: Wichtige Konzepte

In diesem Abschnitt werden einige wichtige Konzepte beschrieben.

Nutzer

Jeder Fahrzeugnutzer (User-Klasse) kann ein Konto erstellen, in dem er seine Einstellungen speichern kann. Die Funktion „Nutzereinstellungen“ unterstützt nur Konten für Autofahrer. Gastfahrer können temporäre Konten erstellen, die nach einmaliger Nutzung automatisch gelöscht werden.

message User {
  // Required.
  // A unique ID for the user.
  int32 id = 1;

  // Bit flags that define properties of user. Integer values have to be powers of 2 as they are used as
  // a bit mask.
  enum UserFlags {
    // Due to Protobuff requirement to have the first enum option set to 0,
    // Assign 0 to an unused flag
    UNSET = 0x0;
    // Marks the user as vehicle driver
    DRIVER = 0x01;
    // Ephemeral users have non-persistent state, once another user is selected
    // the profile is deleted automatically
    EPHEMERAL = 0x02;
  }

  // Required.
  // Bitmask for the user flags defined above
  int32 flags = 2;
}

Einstellungsgruppen

Mit Einstellungs-Gruppen (SettingsGroup-Klasse) können Sie zusammengehörige Einstellungen organisieren und verwalten. Jede konfigurierbare Komponente im Fahrzeug definiert ihre Einstellungen als Gruppen, die aus einer Liste von Einstellungen bestehen, die als Schlüssel/Wert-Paare dargestellt werden. Beispiel: Bei Fahrzeugen mit elektrischen Sitzen kann eine Einstellungsgruppe für den Fahrersitz und eine weitere für den Beifahrersitz definiert werden. Beide Gruppen enthalten Einstellungen mit identischen Namen.

message SettingsGroup {
  // Required.
  // The identifier for this group.
  SettingsGroupId id = 1;

  // Required.
  // The version number of schema used by this setting group.
  string version = 2;

  // Required.
  // The list of settings within the setting group.
  repeated Setting settings = 3;
}

Einstellungen

Die Einstellung „message“ (Klasse Setting) stellt eine einzelne Einstellung in SettingsGroup dar. Diese Nachricht besteht aus einem Schlüssel, dem Namen der Einstellung, und einem Wert, der einen von mehreren Typen annehmen kann.

In diesem Beispiel wird gezeigt, wie eine Einstellung mit einem Schlüssel und einem Wert dargestellt wird:

// A key value pair representing a setting within a UserControllableService SettingsGroup.
message Setting {
  // Required.
  // A name that uniquely identifies a setting within a SettingsGroup.
  string key = 1;

  // Required.
  // New value of the setting.
  oneof value {
    bool bool = 2;
    float float = 3;
    int32 int32 = 4;
    int64 int64 = 5;
    bytes blob = 6;
    int32 enum = 7;
  }
}

Definitionen von Einstellungen

Einstellungsdefinitionen (SettingDefinition-Klasse) dienen als Vorlagen für einzelne Einstellungen in einer Einstellungsgruppe. Sie geben die grundlegenden Eigenschaften der Einstellung an, z. B. ob die Einstellung für alle Nutzer freigegeben ist, für jeden Nutzer spezifisch ist oder extern verwaltet wird (Passthrough).

Wichtig: Mit den Einstellungsdefinitionen werden auch alle Einschränkungen für den Wert der Einstellung definiert, z. B. Mindest- und Höchstwerte, zulässige Inkremente oder eine eingeschränkte Auswahl an Optionen. Diese Einschränkungen führen zu Datenintegrität und ‑konsistenz für jede Einstellung.

// The definition of a setting, along with its properties such as type and constraints
message SettingDefinition {
  // Required.
  SettingKind kind = 1;

  // Required.
  SettingWithConstraints setting_with_constraints = 2;
}

enum SettingKind {
  // A setting which is applied for all vehicle users.
  SHARED = 0;
  // Store the value of the setting for each vehicle user separately.
  PER_USER = 1;
  // UserControllableService is fully responsible for the storage of PASSTHROUGH setting.
  // User Preferences only notifies UserControllableService when the value is explicitly set by
  // user. User Preferences does not attempt to request changes based on user change or service
  // registration.
  PASSTHROUGH = 2;
};

message SettingWithConstraints {
  // Required
  Setting setting = 1;

  // Required.
  // Defines restrictions on the setting's value
  oneof constraints {
    FloatConstraints float_constraints = 2;
    Int32Constraints int32_constraints = 3;
    Int64Constraints int64_constraints = 4;
    EnumConstraints enum_constraints = 5;
  }
}

message Int32Constraints {
  // The minimum value that a setting can have.
  optional int32 min_value = 1;
  // The maximum value that a setting can have.
  optional int32 max_value = 2;
  // The step by which a setting's value can be increased or decreased.
  optional int32 step = 3;
}

message Int64Constraints {
  // The minimum value that a setting can have.
  optional int64 min_value = 1;
  // The maximum value that a setting can have.
  optional int64 max_value = 2;
  // The step by which a setting's value can be increased or decreased.
  optional int64 step = 3;
}

message FloatConstraints {
  // The minimum value that a setting can have.
  optional float min_value = 1;
  // The maximum value that a setting can have.
  optional float max_value = 2;
  // The step by which a setting's value can be increased or decreased.
  optional float step = 3;
}

message EnumConstraints {
  // Required.
  // List of unique values sorted in ascending order.
  repeated int32 possible_values = 1;
}

Beispiel für eine Abfolge von Ereignissen, wenn ein Nutzer eine Einstellung aktualisiert

In diesem Beispiel wird die Abfolge der Ereignisse veranschaulicht, die auftreten, wenn ein Nutzer das In-Vehicle Infotainment-System (IVI) von Android Automotive OS (AAOS) verwendet, um eine Einstellung zu aktualisieren:

Ereignisse, wenn Nutzer eine Einstellung ändern

Abbildung 1. Ereignisse, wenn ein Nutzer eine Einstellung ändert.

Beispiel für eine Ereignissequenz beim Starten eines Fahrzeugs

Dieses Beispiel veranschaulicht, wie die Nutzerpräferenzen von SDV die bevorzugten Einstellungen eines Nutzers anwenden, wenn ein Fahrzeug gestartet wird:

Ereignisse beim Starten des Fahrzeugs

Abbildung 2: Ereignisse beim Starten eines Fahrzeugs.