راهنمای معماری و پیاده‌سازی ترجیحات کاربر

این صفحه راهنمایی در مورد معماری سیستم تنظیمات کاربر SDV و دستورالعمل‌هایی برای پیاده‌سازی یک سرویس و کلاینت قابل کنترل توسط کاربر ارائه می‌دهد.

نمای کلی معماری

سیستم تنظیمات کاربر، ذخیره‌سازی و مدیریت تنظیمات کاربر را از اجرا و اعمال آن تنظیمات جدا می‌کند. اصطلاحات کلیدی معماری در جدول خلاصه شده‌اند:

ویژگی توضیحات نقش مسئولیت
سرویس قابل کنترل توسط کاربر یک بسته سرویس استاندارد SDV که یک دامنه خاص را مدیریت می‌کند (برای مثال، HVAC، صندلی‌های ماشین، سیستم صوتی) وضعیت مورد نظر از قابلیت‌ها و محدودیت‌های سخت‌افزار یا زیرسیستمی که کنترل می‌کند را ارائه می‌دهد.
  • ثبت: به عامل تنظیمات کاربر در مورد تنظیماتی که پشتیبانی می‌کند (فراداده، پیش‌فرض‌ها، محدودیت‌ها) اطلاع می‌دهد.
  • اجرا و خودمختاری: درخواست‌های تغییر تنظیمات را دریافت می‌کند، آنها را با توجه به وضعیت فعلی و قوانین ایمنی اعتبارسنجی می‌کند و آنها را روی سخت‌افزار اعمال می‌کند. خودمختاری کامل را حفظ می‌کند و مشخص می‌کند که آیا تغییر تنظیمات پذیرفته شده یا رد می‌شود.
عامل تنظیمات کاربر ارکستراتور مرکزی فضای ذخیره‌سازی متمرکز، مدیریت پروفایل کاربر و مرکز اعلان‌ها را فراهم می‌کند.
  • ذخیره‌سازی: تنظیمات برای هر کاربر (مثلاً راننده، مسافر) حفظ می‌شود.
  • مسیریابی: پروکسی‌ها درخواست‌های دریافتی از کلاینت‌ها (مثلاً رابط انسان و ماشین (HMI)) را به سرویس مناسبِ قابل کنترل توسط کاربر تغییر می‌دهند.
  • اعلان‌ها: با استفاده از رابط ChangeNotifier تغییرات را به طرف‌های ذینفع (نماها یا HMIها) اعلام می‌کند.
  • مدیریت کاربر: تغییر کاربر و اعمال وضعیت پایدار صحیح به تمام سرویس‌های ثبت‌شده را مدیریت می‌کند.
کلاینت تنظیمات کاربر یک برنامه یا سرویس که رابط کاربری ارائه می‌دهد، به عنوان مثال، یک برنامه 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. تنظیمات را هنگام راه‌اندازی در کلید proto 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. RPC RequestSettingsChange را پیاده‌سازی کنید.
    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. برای بازگرداندن زیرسیستم خود به حالت پاک، از RPC FactoryReset استفاده کنید:

    1. تمام تنظیمات را به مقادیر پیش‌فرض (مطابق آنچه در پیکربندی کد شما تعریف شده است) بازنشانی کنید.
    2. تابع UpdateSettings در سرویس رجیستری فراخوانی کنید تا به عامل اطلاع دهید که مقادیر به صورت خارجی تغییر کرده‌اند (توسط تنظیم مجدد، نه به درخواست کاربر).

سازگاری رو به عقب و تکامل طرحواره

طرحواره تنظیمات تعریف شده توسط یک سرویس قابل کنترل توسط کاربر، یک رابط عمومی در نظر گرفته می‌شود. این رابط توسط عامل تنظیمات کاربر و کلاینت‌های مختلف (به عنوان مثال، HMIها) که ممکن است برنامه‌های انتشار متفاوتی داشته باشند، استفاده می‌شود. بنابراین، حفظ سازگاری دقیق با نسخه‌های قبلی برای جلوگیری از بی‌ثباتی سیستم و خرابی کلاینت ضروری است.

تغییرات سازگار

یک سرویس قابل کنترل توسط کاربر باید فقط تغییرات سازگار را در طرح تنظیمات خود اعمال کند. این تغییرات تضمین می‌کنند که کلاینت‌های قدیمی‌تر بدون به‌روزرسانی به درستی کار کنند:

  • یک تنظیم جدید و اختیاری با مقدار پیش‌فرض معقول اضافه کنید:

    • این تنظیم اختیاری است، بنابراین کلاینت‌ها باید وجود آن را بررسی کنند تا از نسخه‌های مختلف سرویس پشتیبانی کنند.
    • اگر کلاینت‌ها برای تشخیص این تنظیم به‌روزرسانی نشده باشند، آن را نادیده می‌گیرند.
    • اگر هیچ ترجیح کاربری برای تنظیم جدید وجود نداشته باشد، عامل از مقدار پیش‌فرض ارائه شده استفاده می‌کند.

تغییرات ناسازگار

تغییرات زیر نقض قوانین محسوب می‌شوند و ممنوع هستند زیرا بلافاصله به مشتریان قدیمی آسیب می‌رسانند:

  • حذف یک تنظیم موجود.

  • معنی، واحد یا نوع داده یک تنظیم موجود را تغییر دهید (برای مثال، تغییر از یک عدد صحیح که نشان دهنده دما بر حسب سانتیگراد است به یک عدد اعشاری که نشان دهنده فشار بر حسب پاسکال است).

  • مقدار پیش‌فرض یک تنظیم موجود را تغییر دهید. دلیل اصلی ممنوعیت تغییر مقدار پیش‌فرض، پیچیدگی احتمالی در انتقال مداوم داده‌ها است. عامل تنظیمات را بر اساس طرح ثبت سرویس ذخیره می‌کند. تغییر مقدار پیش‌فرض نیاز به منطق پیچیده‌ای برای انتقال تمام پروفایل‌های کاربری موجود به پیش‌فرض جدید دارد یا خطر استفاده از یک مقدار از نظر فنی نادرست برای کاربرانی که هرگز به صراحت ترجیح را تنظیم نکرده‌اند، وجود دارد.

مدیریت تغییرات ضروری برای شکستن قفل

اگر نیاز به تغییر اساسی باشد، سرویس نباید تنظیمات موجود را تغییر دهد. رویکرد مدیریت این انتقال ضمن حفظ سازگاری، عمدتاً در منطق سرویس قابل کنترل توسط کاربر قرار دارد:

  1. یک تنظیم جدید با تعریف، کلید یا واحد جدید مورد نظر ایجاد کنید.
  2. با ثبت تنظیمات موجود برای سازگاری، آن را منسوخ کنید. هنگام ایجاد کلاینت‌های جدید، از این تنظیمات جدید استفاده کنید.
  3. به مشتریان جدید توصیه کنید که منطق سازگاری را در منطق تجاری سرویس قابل کنترل توسط کاربر پیاده‌سازی کنند.

پیاده‌سازی RequestSettingsChange سرویس باید تضمین کند که تغییر در یک تنظیم در همتای منسوخ‌شده‌ی آن منعکس می‌شود و تغییر در همتای آن نیز در آن تنظیم منعکس می‌شود.

مثال منطق سازگاری:

  1. یک سرویس، تنظیمات قدیمی TEMPERATURE_C (سلسیوس) را منسوخ کرده و TEMPERATURE_K (کلوین) را معرفی می‌کند.

  2. وقتی اپراتور درخواستی برای به‌روزرسانی تنظیمات جدید ارسال می‌کند:

    • این سرویس درخواستی برای TEMPERATURE_K (برای مثال، ۲۹۵.۱۵ K) دریافت می‌کند.

    • منطق سرویس این را به سانتیگراد (22 درجه سانتیگراد) تبدیل می‌کند و به صورت داخلی هر دو مقدار را به‌روزرسانی و حفظ می‌کند تا سازگاری را برای کلاینت‌های قدیمی حفظ کند.

  3. وقتی نماینده درخواستی برای تنظیمات منسوخ شده از یک کلاینت قدیمی ارسال می‌کند:

    • این سرویس درخواستی برای TEMPERATURE_C (برای مثال، ۲۴ درجه سانتیگراد) دریافت می‌کند.
    • این سرویس این را به کلوین (۲۹۷.۱۵ کلوین) تبدیل می‌کند و هر دو مقدار را به‌طور داخلی به‌روزرسانی و حفظ می‌کند.

این استراتژی نوشتن دوگانه تضمین می‌کند که همه کلاینت‌ها، صرف نظر از برنامه انتشارشان، داده‌های ثابت و دقیقی را می‌خوانند و از خرابی ناشی از عدم تطابق انتشار خارجی جلوگیری می‌کنند.

پیاده‌سازی یک کلاینت

برای پیاده‌سازی یک کلاینت (مثلاً یک HMI) که با عامل تنظیمات کاربر تعامل دارد:

  1. بسته سرویس کلاینت خود را برای تعامل با رابط‌های کاربری خاص User Preferences تعریف کنید. در فایل 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"
        }
    }
    

    سیاست‌های مجوزدهی را بر این اساس اضافه کنید. برای اجازه دادن به ارتباط برای عامل تنظیمات کاربر، یک کلاینت برای سرورهای مشخص شده ایجاد کنید. به عنوان مثال:

    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. RPC OnSettingsChange را از رابط ChangeNotifier در بسته سرویس خود پیاده‌سازی کنید. عامل تنظیمات کاربر (User Preferences agent) این متد را هنگام وقوع تغییر فراخوانی می‌کند.
    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 به agent ارسال می‌کند.
  4. عامل، یک اعلان OnSettingsChange را به کلاینت ارسال می‌کند که حاوی تنظیمات و وضعیت به‌روزرسانی‌شده است.

برای مشاهده‌ی یک مثال کاربردی کامل، به HMIService در @samples/user_preferences/v1/ مراجعه کنید.

پیاده‌سازی عامل

یک بسته سرویس راه‌اندازی‌شده توسط هماهنگ‌کننده، عامل تنظیمات کاربر را پیاده‌سازی می‌کند. برای راحتی، یک پیاده‌سازی مرجع ارائه شده است.

علاوه بر این، این فایل نمونه بسته سرویس 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 ) می‌تواند حسابی ایجاد کند که در آن تنظیمات برگزیده خود را ذخیره کند. تنظیمات برگزیده کاربر فقط از حساب‌های کاربری مخصوص رانندگان وسیله نقلیه پشتیبانی می‌کند. رانندگان مهمان می‌توانند حساب‌های کاربری موقت ایجاد کنند که پس از یک بار استفاده به طور خودکار حذف می‌شوند.

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 ) تنظیمات مرتبط را سازماندهی و مدیریت می‌کنند. هر جزء قابل تنظیم در وسیله نقلیه، تنظیمات خود را به صورت گروه‌هایی تعریف می‌کند که شامل لیستی از تنظیمات است که به صورت جفت‌های کلید-مقدار نمایش داده می‌شوند. به عنوان مثال، وسایل نقلیه با صندلی‌های برقی می‌توانند یک گروه تنظیمات برای صندلی راننده و گروه دیگری برای سرنشین جلو تعریف کنند که هر دو گروه حاوی تنظیمات با نام یکسان هستند.

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 )، نشان‌دهنده‌ی یک تنظیم واحد در 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 ) به عنوان قالب‌هایی برای تنظیمات فردی در یک گروه تنظیمات عمل می‌کنند. آن‌ها ویژگی‌های اساسی تنظیمات را مشخص می‌کنند، مانند اینکه آیا تنظیمات بین همه کاربران به اشتراک گذاشته شده است، مختص هر کاربر است یا به صورت خارجی مدیریت می‌شود (passthrough).

نکته مهم این است که تعاریف تنظیمات، هرگونه محدودیتی را بر روی مقدار تنظیمات، مانند حداقل و حداکثر مقادیر، افزایش‌های مجاز یا مجموعه‌ای محدود از گزینه‌ها، تعریف می‌کنند. این محدودیت‌ها منجر به یکپارچگی و سازگاری داده‌ها برای هر تنظیم می‌شوند.

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

نمونه‌ای از توالی رویدادها هنگامی که کاربر یک تنظیم را به‌روزرسانی می‌کند

این مثال توالی رویدادهایی را نشان می‌دهد که هنگام استفاده کاربر از سیستم اطلاعات سرگرمی درون خودرویی (IVI) سیستم عامل اندروید اتوموتیو (AAOS) برای به‌روزرسانی یک تنظیم، رخ می‌دهند:

رویدادهایی که کاربر تنظیمات را تغییر می‌دهد

شکل ۱. رویدادهایی که کاربر تنظیمات را تغییر می‌دهد.

نمونه‌ای از توالی رویدادها هنگام روشن شدن خودرو

این مثال نشان می‌دهد که چگونه تنظیمات برگزیده کاربر SDV هنگام روشن شدن خودرو، تنظیمات برگزیده کاربر را اعمال می‌کند:

رویدادهایی که هنگام روشن شدن خودرو رخ می‌دهند

شکل ۲. رویدادهایی که هنگام روشن شدن وسیله نقلیه رخ می‌دهند.