این صفحه راهنمایی در مورد معماری سیستم تنظیمات کاربر SDV و دستورالعملهایی برای پیادهسازی یک سرویس و کلاینت قابل کنترل توسط کاربر ارائه میدهد.
نمای کلی معماری
سیستم تنظیمات کاربر، ذخیرهسازی و مدیریت تنظیمات کاربر را از اجرا و اعمال آن تنظیمات جدا میکند. اصطلاحات کلیدی معماری در جدول خلاصه شدهاند:
| ویژگی | توضیحات | نقش | مسئولیت |
|---|---|---|---|
| سرویس قابل کنترل توسط کاربر | یک بسته سرویس استاندارد SDV که یک دامنه خاص را مدیریت میکند (برای مثال، HVAC، صندلیهای ماشین، سیستم صوتی) | وضعیت مورد نظر از قابلیتها و محدودیتهای سختافزار یا زیرسیستمی که کنترل میکند را ارائه میدهد. |
|
| عامل تنظیمات کاربر | ارکستراتور مرکزی | فضای ذخیرهسازی متمرکز، مدیریت پروفایل کاربر و مرکز اعلانها را فراهم میکند. |
|
| کلاینت تنظیمات کاربر | یک برنامه یا سرویس که رابط کاربری ارائه میدهد، به عنوان مثال، یک برنامه IVI با HMI یا منطق دیگری که نیاز به تعامل با تنظیمات کاربر دارد. | با کاربران تعامل دارد، تنظیمات را نمایش میدهد و درخواستهای تغییر را آغاز میکند. |
|
پیادهسازی یک سرویس قابل کنترل توسط کاربر
برای اطلاع دادن به عامل تنظیمات کاربر که کدام کلیدها وجود دارند، انواع داده آنها، مقادیر پیشفرض و محدودیتها (به عنوان مثال، حداقل و حداکثر مقادیر)، بسته سرویس شما باید با رابط UserPreferencesRegistryService تعامل داشته باشد. وقتی سرویس شما شروع میشود، باید تنظیماتی را که نمایش میدهد ثبت کند. عامل، RequestSettingsChange را روی سرویس شما فراخوانی میکند وقتی کاربری سعی میکند تنظیماتی را تغییر دهد (یا هنگام تغییر کاربران).
مراحل این بخش را دنبال کنید تا به تنظیمات کاربر (و یک کاربر با HMI) اجازه دهید سرویس شما را کنترل کند.
رابطهای سرویس را در فایل 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" } }- به عنوان سرور،
تنظیمات را هنگام راهاندازی در کلید proto
user_preferences_registry_service.protoثبت کنید:- به
UserPreferencesRegistryServiceمتصل شوید. - یک نمونه از
RegisterSettingsRequestایجاد کنید. - یک نمونه از
SettingsGroup(مجموعهای منطقی از تنظیمات) تعریف کنید. برای هر تنظیم، موارد زیر را تعریف کنید:
* **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).تابع
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?;- به
مدیریت درخواستهای تغییر تنظیمات در
user_controllable_service.proto:- RPC
RequestSettingsChangeرا پیادهسازی کنید. - اعتبارسنجی کنید که آیا مقادیر درخواستی در چارچوب فعلی معتبر هستند یا خیر (برای مثال، اگر سختافزار آماده باشد).
- منطق خاصی را برای اعمال تغییر اعمال کنید (برای مثال، صندلی را جابجا کنید، سرعت پنکه را تغییر دهید).
- مقادیر اعمال شده در
RequestSettingsChangeResponseرا برمیگرداند: - اگر تغییر را پذیرفتید، مقدار جدید را برگردانید.
- اگر مقدار را رد یا محدود کردهاید، مقداری را که تعیین کردهاید (یا نگه داشتهاید) برگردانید.
مثال زیر در 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, }) }- RPC
برای بازگرداندن زیرسیستم خود به حالت پاک، از RPC
FactoryResetاستفاده کنید:- تمام تنظیمات را به مقادیر پیشفرض (مطابق آنچه در پیکربندی کد شما تعریف شده است) بازنشانی کنید.
- تابع
UpdateSettingsدر سرویس رجیستری فراخوانی کنید تا به عامل اطلاع دهید که مقادیر به صورت خارجی تغییر کردهاند (توسط تنظیم مجدد، نه به درخواست کاربر).
سازگاری رو به عقب و تکامل طرحواره
طرحواره تنظیمات تعریف شده توسط یک سرویس قابل کنترل توسط کاربر، یک رابط عمومی در نظر گرفته میشود. این رابط توسط عامل تنظیمات کاربر و کلاینتهای مختلف (به عنوان مثال، HMIها) که ممکن است برنامههای انتشار متفاوتی داشته باشند، استفاده میشود. بنابراین، حفظ سازگاری دقیق با نسخههای قبلی برای جلوگیری از بیثباتی سیستم و خرابی کلاینت ضروری است.
تغییرات سازگار
یک سرویس قابل کنترل توسط کاربر باید فقط تغییرات سازگار را در طرح تنظیمات خود اعمال کند. این تغییرات تضمین میکنند که کلاینتهای قدیمیتر بدون بهروزرسانی به درستی کار کنند:
یک تنظیم جدید و اختیاری با مقدار پیشفرض معقول اضافه کنید:
- این تنظیم اختیاری است، بنابراین کلاینتها باید وجود آن را بررسی کنند تا از نسخههای مختلف سرویس پشتیبانی کنند.
- اگر کلاینتها برای تشخیص این تنظیم بهروزرسانی نشده باشند، آن را نادیده میگیرند.
- اگر هیچ ترجیح کاربری برای تنظیم جدید وجود نداشته باشد، عامل از مقدار پیشفرض ارائه شده استفاده میکند.
تغییرات ناسازگار
تغییرات زیر نقض قوانین محسوب میشوند و ممنوع هستند زیرا بلافاصله به مشتریان قدیمی آسیب میرسانند:
حذف یک تنظیم موجود.
معنی، واحد یا نوع داده یک تنظیم موجود را تغییر دهید (برای مثال، تغییر از یک عدد صحیح که نشان دهنده دما بر حسب سانتیگراد است به یک عدد اعشاری که نشان دهنده فشار بر حسب پاسکال است).
مقدار پیشفرض یک تنظیم موجود را تغییر دهید. دلیل اصلی ممنوعیت تغییر مقدار پیشفرض، پیچیدگی احتمالی در انتقال مداوم دادهها است. عامل تنظیمات را بر اساس طرح ثبت سرویس ذخیره میکند. تغییر مقدار پیشفرض نیاز به منطق پیچیدهای برای انتقال تمام پروفایلهای کاربری موجود به پیشفرض جدید دارد یا خطر استفاده از یک مقدار از نظر فنی نادرست برای کاربرانی که هرگز به صراحت ترجیح را تنظیم نکردهاند، وجود دارد.
مدیریت تغییرات ضروری برای شکستن قفل
اگر نیاز به تغییر اساسی باشد، سرویس نباید تنظیمات موجود را تغییر دهد. رویکرد مدیریت این انتقال ضمن حفظ سازگاری، عمدتاً در منطق سرویس قابل کنترل توسط کاربر قرار دارد:
- یک تنظیم جدید با تعریف، کلید یا واحد جدید مورد نظر ایجاد کنید.
- با ثبت تنظیمات موجود برای سازگاری، آن را منسوخ کنید. هنگام ایجاد کلاینتهای جدید، از این تنظیمات جدید استفاده کنید.
- به مشتریان جدید توصیه کنید که منطق سازگاری را در منطق تجاری سرویس قابل کنترل توسط کاربر پیادهسازی کنند.
پیادهسازی RequestSettingsChange سرویس باید تضمین کند که تغییر در یک تنظیم در همتای منسوخشدهی آن منعکس میشود و تغییر در همتای آن نیز در آن تنظیم منعکس میشود.
مثال منطق سازگاری:
یک سرویس، تنظیمات قدیمی
TEMPERATURE_C(سلسیوس) را منسوخ کرده وTEMPERATURE_K(کلوین) را معرفی میکند.وقتی اپراتور درخواستی برای بهروزرسانی تنظیمات جدید ارسال میکند:
این سرویس درخواستی برای
TEMPERATURE_K(برای مثال، ۲۹۵.۱۵ K) دریافت میکند.منطق سرویس این را به سانتیگراد (22 درجه سانتیگراد) تبدیل میکند و به صورت داخلی هر دو مقدار را بهروزرسانی و حفظ میکند تا سازگاری را برای کلاینتهای قدیمی حفظ کند.
وقتی نماینده درخواستی برای تنظیمات منسوخ شده از یک کلاینت قدیمی ارسال میکند:
- این سرویس درخواستی برای
TEMPERATURE_C(برای مثال، ۲۴ درجه سانتیگراد) دریافت میکند. - این سرویس این را به کلوین (۲۹۷.۱۵ کلوین) تبدیل میکند و هر دو مقدار را بهطور داخلی بهروزرسانی و حفظ میکند.
- این سرویس درخواستی برای
این استراتژی نوشتن دوگانه تضمین میکند که همه کلاینتها، صرف نظر از برنامه انتشارشان، دادههای ثابت و دقیقی را میخوانند و از خرابی ناشی از عدم تطابق انتشار خارجی جلوگیری میکنند.
پیادهسازی یک کلاینت
برای پیادهسازی یک کلاینت (مثلاً یک HMI) که با عامل تنظیمات کاربر تعامل دارد:
بسته سرویس کلاینت خود را برای تعامل با رابطهای کاربری خاص 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 }- به عنوان سرور،
شما میتوانید تنظیمات درخواست را در
UserPreferencesManagementServiceتغییر دهید:- به
UserPreferencesManagementServiceمتصل شوید. - یک نمونه از
RequestSettingsChangeRequestایجاد کنید وSettingsGroupIdو تنظیمات مورد نظر را مشخص کنید. - اختیاری.
ChangePersistencePolicyرا رویPERSISTENT_CHANGE(پیشفرض) یاNON_PERSISTENT_CHANGEتنظیم کنید. - فراخوانی
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?;- به
با استفاده از
user_preferences_management_service.protoوchange_notifier.protoدر تغییرات تنظیمات مشترک شوید:- RPC
OnSettingsChangeرا از رابطChangeNotifierدر بسته سرویس خود پیادهسازی کنید. عامل تنظیمات کاربر (User Preferences agent) این متد را هنگام وقوع تغییر فراخوانی میکند. - به
UserPreferencesManagementServiceمتصل شوید. - یک
SubscribeToSettingsChangeAndGetSettingsRequestایجاد کنید کهSettingsGroupIdمورد نظر برای نظارت را مشخص کند. - برای بازگرداندن وضعیت تنظیمات و سپس ارسال بهروزرسانیهای آینده از طریق پیادهسازی
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?;- RPC
اختیاری: کلاینتهایی که پروفایلهای کاربری را مدیریت میکنند (برای مثال، یک برنامه تنظیمات اختصاصی) میتوانند
user_preferences_admin_service.protoبرای تعامل با سرویس ادمین استفاده کنند:- به
UserPreferencesAdminServiceمتصل شوید. - از 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?;- به
تنظیمات و کاربران موجود را از طریق سرویس ادمین با
user_preferences_admin_service.protoکشف کنید:- با فراخوانی
ListUsers()درUserPreferencesAdminService، فهرستی از تمام کاربران ثبتنامشده را دریافت کنید. - با فراخوانی
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); }- با فراخوانی
خلاصه جریان
- کلاینت سرویسهای مدیریتی و اداری نماینده را راهاندازی و به آنها متصل میشود.
- کلاینت گروههای تنظیمات را پیدا کرده و در آنها مشترک میشود و حالت اولیه را نمایش میدهد.
- کلاینت یک
RequestSettingsChangeبه agent ارسال میکند. - عامل، یک اعلان
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 هنگام روشن شدن خودرو، تنظیمات برگزیده کاربر را اعمال میکند:

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