คู่มือสถาปัตยกรรมและการติดตั้งใช้งานค่ากำหนดของผู้ใช้

หน้านี้มีคำแนะนำเกี่ยวกับสถาปัตยกรรมของระบบค่ากำหนดของผู้ใช้ SDV และวิธีการติดตั้งใช้งานบริการและไคลเอ็นต์ที่ผู้ใช้ควบคุมได้

ภาพรวมสถาปัตยกรรม

ระบบค่ากำหนดของผู้ใช้จะแยกการจัดเก็บและการจัดการการตั้งค่าของผู้ใช้ออกจาก การบังคับใช้และการใช้การตั้งค่าเหล่านั้น คำศัพท์สำคัญ ด้านสถาปัตยกรรมสรุปไว้ในตารางต่อไปนี้

ฟีเจอร์คำอธิบายบทบาทความรับผิดชอบ
บริการที่ผู้ใช้ควบคุมได้ แพ็กเกจบริการ SDV มาตรฐานที่จัดการโดเมนที่เฉพาะเจาะจง (เช่น HVAC, คาร์ซีท, เสียง) ระบุสถานะที่ต้องการของความสามารถและข้อจำกัดของฮาร์ดแวร์หรือระบบย่อยที่ควบคุม
  • การลงทะเบียน: แจ้งตัวแทนค่ากำหนดของผู้ใช้เกี่ยวกับการตั้งค่าที่รองรับ (ข้อมูลเมตา ค่าเริ่มต้น ข้อจำกัด)
  • การบังคับใช้และการควบคุมตนเอง: รับคำขอเปลี่ยนการตั้งค่า ตรวจสอบคำขอเทียบกับสถานะปัจจุบันและกฎความปลอดภัย แล้วใช้คำขอกับฮาร์ดแวร์ คงความเป็นอิสระอย่างเต็มที่และระบุว่าจะยอมรับหรือปฏิเสธการเปลี่ยนแปลงการตั้งค่า
ตัวแทนค่ากำหนดของผู้ใช้ ตัวจัดสรรส่วนกลาง มีพื้นที่เก็บข้อมูลส่วนกลาง การจัดการโปรไฟล์ผู้ใช้ และฮับการแจ้งเตือน
  • พื้นที่เก็บข้อมูล: คงการตั้งค่าต่อผู้ใช้ (เช่น คนขับ ผู้โดยสาร)
  • การกำหนดเส้นทาง: พร็อกซีจะเปลี่ยนคำขอจากไคลเอ็นต์ (เช่น อินเทอร์เฟซระหว่างมนุษย์กับเครื่อง (HMI)) เป็นบริการที่ผู้ใช้ควบคุมได้ที่เหมาะสม
  • การแจ้งเตือน: กระจายการเปลี่ยนแปลงไปยังผู้ที่สนใจ (วิวหรือ HMI) โดยใช้อินเทอร์เฟซ ChangeNotifier
  • การจัดการผู้ใช้: จัดการการสลับผู้ใช้และใช้สถานะแบบถาวรที่ถูกต้องกับบริการที่ลงทะเบียนทั้งหมด
ไคลเอ็นต์ค่ากำหนดของผู้ใช้ แอปหรือบริการที่แสดงอินเทอร์เฟซผู้ใช้ เช่น แอป IVI ที่มี HMI หรือตรรกะอื่นๆ ที่ต้องโต้ตอบกับค่ากําหนดของผู้ใช้ โต้ตอบกับผู้ใช้ แสดงการตั้งค่า และเริ่มคำขอเปลี่ยนแปลง
  • แสดง: แสดงการตั้งค่าและข้อจำกัดปัจจุบันต่อผู้ใช้
  • ขอเปลี่ยนแปลง: ส่งการแก้ไขการตั้งค่าที่ผู้ใช้เริ่มต้นไปยังตัวแทนค่ากำหนดของผู้ใช้
  • รับการแจ้งเตือน: ติดตามและตอบสนองต่อข้อมูลอัปเดตแบบเรียลไทม์ของการตั้งค่า

ใช้บริการที่ผู้ใช้ควบคุมได้

หากต้องการแจ้งให้ตัวแทนค่ากำหนดของผู้ใช้ทราบว่ามีคีย์ใดบ้าง ประเภทข้อมูล ค่าเริ่มต้น และข้อจำกัด (เช่น ค่าต่ำสุดและสูงสุด) บริการ ของคุณต้องโต้ตอบกับอินเทอร์เฟซ UserPreferencesRegistryService เมื่อบริการเริ่มทำงาน บริการจะต้องลงทะเบียนการตั้งค่าที่แสดง เอเจนต์จะเรียกใช้ RequestSettingsChange ในบริการของคุณเมื่อผู้ใช้พยายามแก้ไขการตั้งค่า (หรือเมื่อเปลี่ยนผู้ใช้)

ทำตามขั้นตอนในส่วนนี้เพื่อให้ค่ากําหนดของผู้ใช้ (และผู้ใช้ที่มี HMI) ควบคุมบริการของคุณ

  1. กำหนดอินเทอร์เฟซบริการในไฟล์ VSIDL ดังนี้

    • ในฐานะเซิร์ฟเวอร์ ให้ใช้ com.sdv.google.user_preferences.user_controllable.UserControllableService ซึ่งจะช่วยให้ตัวแทนส่งคำขอเปลี่ยนแปลงให้คุณได้
    • ในฐานะไคลเอ็นต์ ให้ใช้ com.sdv.google.user_preferences.UserPreferencesRegistryService การดำเนินการนี้ จะลงทะเบียนการตั้งค่าเมื่อเริ่มต้น

    ตัวอย่างต่อไปนี้แสดง service_bundle.vsidl สำหรับบริการที่ผู้ใช้ควบคุมได้

    service_bundle {
        name: "MyFeatureService"
        server {
            service: "com.sdv.google.user_preferences.user_controllable.UserControllableService"
        }
        client {
            service: "com.sdv.google.user_preferences.UserPreferencesRegistryService"
        }
    }
    
  2. ลงทะเบียนการตั้งค่าเมื่อเริ่มต้นในคีย์โปรโต user_preferences_registry_service.proto:

    1. เชื่อมต่อกับ UserPreferencesRegistryService
    2. สร้างอินสแตนซ์ของ RegisterSettingsRequest
    3. กำหนดอินสแตนซ์ของ SettingsGroup (ชุดการตั้งค่าเชิงตรรกะ)
    4. สําหรับการตั้งค่าแต่ละรายการ ให้กําหนดค่าต่อไปนี้

      *   **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. โทร RegisterSettings()

    ตัวอย่างต่อไปนี้เป็น 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. จัดการคำขอเปลี่ยนแปลงการตั้งค่าใน user_controllable_service.proto โดยทำดังนี้

    1. ติดตั้งใช้งาน RequestSettingsChange RPC
    2. ตรวจสอบว่าค่าที่ขอถูกต้องในบริบทปัจจุบันหรือไม่ (เช่น หากฮาร์ดแวร์พร้อม)
    3. ใช้ตรรกะที่เฉพาะเจาะจงเพื่อใช้การเปลี่ยนแปลง (เช่น ย้ายที่นั่ง เปลี่ยนความเร็วพัดลม)
    4. แสดงค่าที่ใช้ใน RequestSettingsChangeResponse
    5. หากคุณยอมรับการเปลี่ยนแปลง ให้ส่งคืนค่าใหม่
    6. หากคุณปฏิเสธหรือจำกัดค่า ให้แสดงค่าที่คุณตั้งไว้ (หรือเก็บไว้)

    ตัวอย่างต่อไปนี้เป็น 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. ใช้ FactoryReset RPC เพื่อเปลี่ยนกลับระบบย่อยเป็นสถานะที่สะอาด

    1. รีเซ็ตการตั้งค่าทั้งหมดเป็นค่าเริ่มต้น (ตามที่กำหนดไว้ในการกำหนดค่าโค้ด)
    2. เรียกใช้ UpdateSettings ในบริการรีจิสทรีเพื่อแจ้งให้ตัวแทนทราบว่า ค่ามีการเปลี่ยนแปลงภายนอก (โดยการรีเซ็ต ไม่ใช่โดยคำขอของผู้ใช้)

ความเข้ากันได้แบบย้อนหลังและการพัฒนาสคีมา

สคีมาของการตั้งค่าที่กำหนดโดยบริการที่ผู้ใช้ควบคุมได้ถือเป็น อินเทอร์เฟซสาธารณะ เอเจนต์ค่ากำหนดของผู้ใช้และไคลเอ็นต์ต่างๆ (เช่น HMI) จะใช้อินเทอร์เฟซนี้ ซึ่งอาจมีกำหนดการเปิดตัวที่แตกต่างกัน ดังนั้นการรักษาความเข้ากันได้แบบย้อนหลังอย่างเคร่งครัดจึงเป็นสิ่งจำเป็นเพื่อ ป้องกันไม่ให้ระบบไม่เสถียรและไคลเอ็นต์ใช้งานไม่ได้

การเปลี่ยนแปลงที่เข้ากันได้

บริการที่ผู้ใช้ควบคุมได้ควรทำการเปลี่ยนแปลงที่เข้ากันได้เท่านั้นกับสคีมาการตั้งค่า การเปลี่ยนแปลงเหล่านี้ช่วยให้มั่นใจว่าไคลเอ็นต์รุ่นเก่าจะยังคงทำงานได้อย่างถูกต้องโดยไม่ต้องอัปเดต

  • เพิ่มการตั้งค่าใหม่ที่ไม่บังคับโดยมีค่าเริ่มต้นที่เหมาะสม ดังนี้

    • การตั้งค่านี้เป็นตัวเลือกแบบไม่บังคับ ดังนั้นไคลเอ็นต์จึงต้องตรวจสอบว่ามีการตั้งค่านี้หรือไม่เพื่อรองรับบริการเวอร์ชันต่างๆ
    • ไคลเอ็นต์จะข้ามการตั้งค่านี้หากยังไม่ได้อัปเดตให้รู้จัก การตั้งค่านี้
    • หากไม่มีค่ากำหนดของผู้ใช้สำหรับการตั้งค่าใหม่นี้ เอเจนต์จะใช้ ค่าเริ่มต้นที่ระบุ

การเปลี่ยนแปลงที่ใช้ร่วมกันไม่ได้

การเปลี่ยนแปลงต่อไปนี้ถือเป็นการเปลี่ยนแปลงที่ทำให้เกิดข้อขัดข้องและไม่อนุญาตเนื่องจากจะ ส่งผลต่อไคลเอ็นต์รุ่นเก่าทันที

  • นำการตั้งค่าที่มีอยู่ออก

  • เปลี่ยนความหมาย หน่วย หรือประเภทข้อมูลของการตั้งค่าที่มีอยู่ (เช่น เปลี่ยนจากจำนวนเต็มที่แสดงอุณหภูมิเป็นเซลเซียสเป็นทศนิยมที่แสดงแรงดันเป็นปาสคาล)

  • เปลี่ยนค่าเริ่มต้นของการตั้งค่าที่มีอยู่ สาเหตุหลักที่ ห้ามเปลี่ยนค่าเริ่มต้นคือความซับซ้อนที่อาจเกิดขึ้นกับการย้ายข้อมูลที่ บันทึกไว้ เอเจนต์จะจัดเก็บการตั้งค่าตามสคีมาการลงทะเบียนของบริการ การเปลี่ยนค่าเริ่มต้นจะต้องใช้ตรรกะที่ซับซ้อนเพื่อ ย้ายข้อมูลโปรไฟล์ผู้ใช้ที่มีอยู่ทั้งหมดไปยังค่าเริ่มต้นใหม่ หรือเสี่ยงที่จะใช้ค่าที่ไม่ถูกต้องในทางเทคนิคสำหรับผู้ใช้ที่ไม่เคยตั้งค่ากำหนดอย่างชัดแจ้ง

จัดการการเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบที่จำเป็น

หากจำเป็นต้องมีการเปลี่ยนแปลงที่ทำให้เกิดข้อขัดข้อง บริการต้องไม่แก้ไขการตั้งค่าที่มีอยู่ แนวทางในการจัดการการเปลี่ยนผ่านนี้ในขณะที่ยังคงความเข้ากันได้ ส่วนใหญ่อยู่ในตรรกะของบริการที่ผู้ใช้ควบคุมได้ ดังนี้

  1. สร้างการตั้งค่าใหม่โดยใช้คำจำกัดความ คีย์ หรือหน่วยใหม่ที่ต้องการ
  2. เลิกใช้งานการตั้งค่าที่มีอยู่โดยการลงทะเบียนเพื่อความเข้ากันได้ ใช้ การตั้งค่าใหม่นี้เมื่อพัฒนาไคลเอ็นต์ใหม่
  3. แนะนําให้ลูกค้าใหม่ใช้ตรรกะความเข้ากันได้ภายในตรรกะทางธุรกิจของบริการที่ผู้ใช้ควบคุมได้

RequestSettingsChangeการติดตั้งใช้งานของบริการต้องตรวจสอบว่าการเปลี่ยนแปลงการตั้งค่าหนึ่งจะส่งผลต่อการตั้งค่าที่เลิกใช้งานแล้ว และการเปลี่ยนแปลงการตั้งค่าที่เลิกใช้งานแล้วจะส่งผลต่อการตั้งค่า

ตัวอย่างตรรกะความเข้ากันได้

  1. บริการเลิกใช้งานการตั้งค่าเก่า TEMPERATURE_C (เซลเซียส) และ เปิดตัว TEMPERATURE_K (เคลวิน)

  2. เมื่อตัวแทนส่งคำขออัปเดตการตั้งค่าใหม่

    • บริการจะได้รับคำขอสำหรับ TEMPERATURE_K (เช่น 295.15 K)

    • ตรรกะของบริการจะแปลงค่านี้เป็นเซลเซียส (22°C) และอัปเดตและคงค่าทั้ง 2 ไว้ภายใน เพื่อรักษาความสอดคล้องสำหรับไคลเอ็นต์รุ่นเดิม

  3. เมื่อตัวแทนส่งคำขอสำหรับการตั้งค่าที่เลิกใช้งานแล้วจากไคลเอ็นต์รุ่นเดิม

    • บริการได้รับคำขอสำหรับ TEMPERATURE_C (เช่น 24°C)
    • บริการจะแปลงค่านี้เป็นเคลวิน (297.15 K) และอัปเดตและบันทึกทั้ง 2 ค่าภายใน

กลยุทธ์การเขียนแบบคู่ช่วยให้มั่นใจได้ว่าไคลเอ็นต์ทั้งหมดจะอ่านข้อมูลที่สอดคล้องและถูกต้อง ไม่ว่าจะมีกำหนดการเปิดตัวอย่างไรก็ตาม เพื่อหลีกเลี่ยงการหยุดทำงานที่เกิดจากการไม่ตรงกันของการเปิดตัวภายนอก

ติดตั้งใช้งานไคลเอ็นต์

วิธีติดตั้งใช้งานไคลเอ็นต์ (เช่น HMI) ที่โต้ตอบกับเอเจนต์ User Preferences

  1. กำหนดแพ็กเกจบริการไคลเอ็นต์เพื่อโต้ตอบกับอินเทอร์เฟซค่ากำหนดของผู้ใช้ที่เฉพาะเจาะจง ในไฟล์ VSIDL ให้ทำดังนี้

    • ในฐานะเซิร์ฟเวอร์ ให้ใช้ com.sdv.google.user_preferences.view.ChangeNotifier เพื่อให้เอเจนต์ส่งการแจ้งเตือนแบบเรียลไทม์เกี่ยวกับการเปลี่ยนแปลงการตั้งค่า ไปยังไคลเอ็นต์ของคุณได้
    • ในฐานะไคลเอ็นต์ ให้ใช้ com.sdv.google.user_preferences.UserPreferencesManagementService เพื่อ ขอแก้ไขการตั้งค่าและติดตามการอัปเดต
    • ในฐานะไคลเอ็นต์ ให้ใช้ com.sdv.google.user_preferences.UserPreferencesAdminService เพื่อจัดการ โปรไฟล์ผู้ใช้ (เช่น สร้าง เลือก ลบ รีเซ็ตเป็นค่าเริ่มต้น)

    ตัวอย่างต่อไปนี้แสดงไฟล์ service_bundle.vsidl สำหรับไคลเอ็นต์

    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"
        }
    }
    

    เพิ่มนโยบายการให้สิทธิ์ตามนั้น หากต้องการอนุญาตการสื่อสารสำหรับ Agent ที่กำหนดค่าของผู้ใช้ ให้สร้างไคลเอ็นต์สำหรับเซิร์ฟเวอร์ที่ระบุ เช่น

    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. คุณเปลี่ยนการตั้งค่าคำขอได้ใน UserPreferencesManagementService ดังนี้

    1. เชื่อมต่อกับ UserPreferencesManagementService
    2. สร้างอินสแตนซ์ของ RequestSettingsChangeRequest โดยระบุ SettingsGroupId และการตั้งค่าที่ต้องการ
    3. ไม่บังคับ ตั้งค่า ChangePersistencePolicy เป็น PERSISTENT_CHANGE (ค่าเริ่มต้น) หรือ NON_PERSISTENT_CHANGE
    4. โทร RequestSettingsChange()

    ตัวอย่างต่อไปนี้เป็น 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. ติดตามการเปลี่ยนแปลงการตั้งค่าด้วย user_preferences_management_service.proto และ change_notifier.proto โดยทำดังนี้

    1. ใช้ OnSettingsChange RPC จากอินเทอร์เฟซ ChangeNotifier ภายในแพ็กเกจบริการ เอเจนต์ค่ากำหนดของผู้ใช้จะเรียกใช้เมธอดนี้ เมื่อมีการเปลี่ยนแปลง
    2. เชื่อมต่อกับ UserPreferencesManagementService
    3. สร้าง SubscribeToSettingsChangeAndGetSettingsRequest โดยระบุ SettingsGroupId ที่ต้องการตรวจสอบ
    4. หากต้องการเปลี่ยนกลับสถานะของการตั้งค่า แล้วส่งการอัปเดตในอนาคตผ่านการติดตั้งใช้งาน OnSettingsChange ให้เรียกใช้ SubscribeToSettingsChangeAndGetSettings()

    ตัวอย่างต่อไปนี้ของการใช้ChangeNotifierอินเทอร์เฟซเป็นภาษา 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())
        }
    }
    

    ตัวอย่างการสมัครใช้บริการต่อไปนี้อยู่ใน 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. ไม่บังคับ: ไคลเอ็นต์ที่จัดการโปรไฟล์ผู้ใช้ (เช่น แอปการตั้งค่าเฉพาะ) สามารถใช้ user_preferences_admin_service.proto เพื่อโต้ตอบ กับบริการของผู้ดูแลระบบได้โดยทำดังนี้

    1. เชื่อมต่อกับ UserPreferencesAdminService
    2. ใช้ RPC เช่น CreateUser, SelectUser, DeleteUser, FactoryReset และ ListUsers เพื่อจัดการโปรไฟล์ผู้ใช้

    ตัวอย่างการสร้างผู้ใช้ต่อไปนี้อยู่ใน Rust เชิงแนวคิด

    admin_service_client.CreateUser(&CreateUserRequest {
        user: Some(User {
            id: 1,
            flags: UserFlags::DRIVER.value(),
            ..Default::default()
        }).into(),
        ..Default::default()
    }).await?;
    
  5. ค้นหาการตั้งค่าและผู้ใช้ที่มีผ่านบริการผู้ดูแลระบบด้วย user_preferences_admin_service.proto

    1. รับรายชื่อผู้ใช้ที่ลงทะเบียนทั้งหมดโดยเรียกใช้ ListUsers() ใน UserPreferencesAdminService
    2. รับการตั้งค่าสำหรับผู้ใช้ที่เฉพาะเจาะจงโดยเรียกใช้ GetUserSettings(user_id) ใน UserPreferencesAdminService

    ตัวอย่างต่อไปนี้ของการแสดงผู้ใช้และการรับการตั้งค่าอยู่ใน 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);
    }
    

สรุปขั้นตอน

  1. ลูกค้าเริ่มและเชื่อมต่อกับบริการด้านการจัดการและการดูแลระบบของเอเจนต์
  2. ไคลเอ็นต์จะค้นพบและติดตามกลุ่มการตั้งค่า รวมถึงแสดง สถานะเริ่มต้น
  3. ไคลเอ็นต์ส่ง RequestSettingsChange ไปยังตัวแทน
  4. เอเจนต์จะส่งการแจ้งเตือน OnSettingsChange ไปยังไคลเอ็นต์พร้อม การตั้งค่าและสถานะที่อัปเดตแล้ว

ดูตัวอย่างที่ใช้งานได้ทั้งหมดได้ที่ HMIServiceใน @samples/user_preferences/v1/

ติดตั้งใช้งาน Agent

ชุดบริการที่เปิดใช้โดยตัวจัดระเบียบจะใช้เอเจนต์ค่ากำหนดของผู้ใช้ เราได้จัดเตรียมการใช้งานอ้างอิงไว้เพื่อความสะดวก

นอกจากนี้ ยังมีuser_preferences_sample.vsidlไฟล์ แพ็กเกจบริการตัวอย่างนี้สำหรับตัวแทนด้วย

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"
    }
}

การติดตั้งใช้งานสามารถใช้มิดเดิลแวร์ที่สร้างขึ้นและควรคอมไพล์เป็น rust_ffi_shared ที่อ้างอิงโดย ชุดบริการที่ใช้เอเจนต์ค่ากําหนดของผู้ใช้

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"
}

ไฟล์นโยบายการให้สิทธิ์.textprotoของไคลเอ็นต์ต้องมีสิทธิ์ที่จำเป็นดังนี้

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
}

ภาคผนวก: แนวคิดหลัก

ส่วนนี้จะอธิบายแนวคิดหลักบางอย่าง

ผู้ใช้

ผู้ใช้ยานพาหนะแต่ละราย (User คลาส) สามารถสร้างบัญชีเพื่อจัดเก็บค่ากำหนดของตนได้ ค่ากำหนดของผู้ใช้รองรับบัญชีสำหรับผู้ขับขี่ยานพาหนะเท่านั้น ผู้ขับขี่ที่เป็นแขกรับเชิญสามารถสร้างบัญชีชั่วคราวที่จะถูกลบโดยอัตโนมัติหลังจาก ใช้งาน 1 ครั้ง

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;
}

กลุ่มการตั้งค่า

กลุ่มการตั้งค่า (SettingsGroup class) จะจัดระเบียบและจัดการการตั้งค่าที่เกี่ยวข้อง คอมโพเนนต์ที่กำหนดค่าได้แต่ละรายการภายในยานพาหนะจะกำหนดการตั้งค่าเป็นกลุ่ม ซึ่งประกอบด้วยรายการการตั้งค่าที่แสดงเป็นคู่คีย์-ค่า เช่น รถยนต์ที่มีเบาะไฟฟ้าสามารถกำหนดกลุ่มการตั้งค่าสำหรับเบาะคนขับ และอีกกลุ่มสำหรับผู้โดยสารด้านหน้า โดยทั้ง 2 กลุ่มมีการตั้งค่าที่มีชื่อเหมือนกัน

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;
}

การตั้งค่า

การตั้งค่า ข้อความ (Setting class) แสดงการตั้งค่าเดียวภายใน SettingsGroup ข้อความนี้ประกอบด้วยคีย์ ซึ่งเป็นชื่อของ การตั้งค่า และค่า ซึ่งอาจเป็นค่าประเภทใดประเภทหนึ่ง

ตัวอย่างนี้แสดงวิธีระบุการตั้งค่าด้วยคีย์และค่า

// 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;
  }
}

คำจำกัดความของการตั้งค่า

คำจำกัดความของการตั้งค่า (SettingDefinition class) ทำหน้าที่เป็นเทมเพลตสำหรับ การตั้งค่าแต่ละรายการภายในกลุ่มการตั้งค่า โดยจะระบุลักษณะพื้นฐานของการตั้งค่า เช่น การตั้งค่าแชร์ในผู้ใช้ทั้งหมดหรือไม่ เฉพาะสำหรับผู้ใช้แต่ละราย หรือจัดการภายนอก (ส่งผ่าน)

ที่สำคัญ การตั้งค่าคำจำกัดความยังกำหนดข้อจำกัดใดๆ ในค่าของ การตั้งค่าด้วย เช่น ค่าต่ำสุดและสูงสุด ส่วนเพิ่มที่อนุญาต หรือชุดตัวเลือกที่จำกัด ข้อจำกัดเหล่านี้ช่วยให้ข้อมูลมีความสมบูรณ์และสอดคล้องกัน สำหรับการตั้งค่าแต่ละรายการ

// 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;
}

ตัวอย่างลำดับเหตุการณ์เมื่อผู้ใช้อัปเดตการตั้งค่า

ตัวอย่างนี้แสดงลําดับของเหตุการณ์ที่เกิดขึ้นเมื่อผู้ใช้ใช้ Android Automotive OS (AAOS) ในระบบสาระบันเทิงในรถยนต์ (IVI) เพื่ออัปเดตการตั้งค่า

เหตุการณ์เมื่อผู้ใช้เปลี่ยน
การตั้งค่า

รูปที่ 1 เหตุการณ์เมื่อผู้ใช้เปลี่ยนการตั้งค่า

ลำดับเหตุการณ์ตัวอย่างเมื่อยานพาหนะเริ่มเคลื่อนที่

ตัวอย่างนี้แสดงให้เห็นว่าค่ากำหนดของผู้ใช้ SDV จะใช้การตั้งค่าที่ผู้ใช้ต้องการ เมื่อรถเริ่มทำงานอย่างไร

เหตุการณ์เมื่อยานพาหนะ
เริ่มเคลื่อนที่

รูปที่ 2 เหตุการณ์เมื่อยานพาหนะเริ่มเคลื่อนที่