تحتوي العديد من هياكل المركبات الحالية على وحدات تحكم إلكترونية متعددة (ECUs) خارج نظام المعلومات والترفيه الذي يتحكم في بيئة العمل ، مثل إعدادات المقعد وتعديلات المرآة. استنادًا إلى هياكل الأجهزة والطاقة الحالية ، يتم تشغيل العديد من وحدات التحكم الإلكترونية قبل تشغيل نظام المعلومات والترفيه المستند إلى Android. يمكن أن تتفاعل وحدات التحكم الإلكترونية هذه مع نظام معلومات ترفيهي قائم على نظام Android من خلال طبقة تجريد أجهزة السيارة (VHAL) .
بدءًا من Android 11 ، قدم نظام التشغيل Android Automotive OS (AAOS) مجموعة جديدة من الخصائص على VHAL لإنشاء الملحقات الخارجية وتبديلها وإزالتها وربطها لتحديد المستخدمين. على سبيل المثال ، تتيح هذه الخصائص الجديدة للسائق إقران ملحق خارجي ، مثل مفتاح فوب ، بمستخدم Android الخاص به. ثم ، عندما يقترب السائق من السيارة ، تستيقظ وحدة التحكم الإلكترونية وتكتشف مفتاح التشغيل. تشير وحدة التحكم الإلكترونية هذه إلى HAL إلى مستخدم Android الذي يجب أن يبدأ نظام المعلومات والترفيه تشغيله ، مما يقلل من الوقت الذي ينتظره السائق حتى يتم تحميل مستخدم Android الخاص به.
قم بتمكين HAL للمستخدم
يجب تمكين خصائص User HAL بشكل صريح من خلال التأكد من ضبط خاصية النظام android.car.user_hal_enabled
على " true
". (يمكن القيام بذلك أيضًا في ملف car.mk
، بحيث لا يلزم تعيينه يدويًا.) تحقق من تمكين user_hal_enabled=true
عن طريق تفريغ UserHalService
:
$ adb shell dumpsys car_service --hal UserHalService|grep enabled user_hal_enabled=true
يمكنك أيضًا التحقق من user_hal_enabled
باستخدام adb logcat CarServiceHelper *:s
. إذا تم تعطيل الخاصية ، يتم عرض رسالة مثل ما يلي عند بدء system_server
:
I CarServiceHelper: Not using User HAL
لتمكين user_hal_enabled
يدويًا ، قم بتعيين خاصية النظام android.car.user_hal_enabled
وأعد تشغيل system_server
:
$ adb shell setprop android.car.user_hal_enabled true $ adb shell stop && adb shell start
يظهر إخراج logcat
على النحو التالي:
I CarServiceHelper: User HAL enabled with timeout of 5000ms D CarServiceHelper: Got result from HAL: OK I CarServiceHelper: User HAL returned DEFAULT behavior
خصائص HAL للمستخدم
خصائص دورة حياة المستخدم
توفر الخصائص التالية معلومات HAL لحالات دورة حياة المستخدم ، والتي تتيح مزامنة دورة حياة المستخدم بين نظام Android ووحدة التحكم الإلكترونية الخارجية. تستخدم هذه الخصائص بروتوكول طلب واستجابة ، حيث يقوم نظام Android بتقديم طلب عن طريق تعيين قيمة خاصية ويستجيب HAL عن طريق إصدار حدث تغيير الخاصية.
ملاحظة: عند دعم User HAL ، يجب تنفيذ جميع الخصائص التالية.
خاصية HAL | وصف |
---|---|
INITIAL_USER_INFO (قراءة و كتابة) | يتم استدعاء هذه الخاصية بواسطة نظام Android لتحديد مستخدم Android الذي سيبدأ النظام عند تشغيل الجهاز أو استئنافه من Suspend-to-RAM (STR). عند الاتصال ، يجب أن يستجيب HAL بأحد هذه الخيارات:
ملاحظة: إذا لم يستجب HAL ، فإن السلوك الافتراضي هو التنفيذ بعد فترة المهلة (خمس (5) ثوانٍ افتراضيًا) ، مما يؤخر التمهيد. إذا ردت طبقة تجريد الأجهزة ، ولكن فشل نظام Android في تنفيذ الإجراء (على سبيل المثال ، إذا تم الوصول إلى الحد الأقصى لعدد المستخدمين) ، فسيتم استخدام السلوك الافتراضي. على سبيل المثال ، بشكل افتراضي ، يبدأ نظام Android في آخر مستخدم نشط عند التمهيد. إذا تم اكتشاف مفتاح فوب لمستخدم مختلف ، فإن وحدة التحكم الإلكترونية تتجاوز خاصية HAL ، وأثناء بدء التشغيل ، يتحول نظام Android ليبدأ في ذلك المستخدم المحدد. |
SWITCH_USER (قراءة و كتابة) | يتم استدعاء هذه الخاصية عند تبديل مستخدم Android الأمامي النشط. يمكن استدعاء الخاصية إما عن طريق نظام Android أو HAL لطلب تبديل المستخدم. تدفقات العمل الثلاثة هي:
يستخدم سير العمل الحديث نهج الالتزام على مرحلتين لضمان مزامنة نظام Android ووحدة التحكم الإلكترونية الخارجية. عندما يبدأ Android التبديل:
يجب أن ينتظر HAL حتى بعد استجابة على سبيل المثال ، أثناء الحركة ، يحاول السائق تبديل مستخدمي Android في واجهة مستخدم المعلومات والترفيه. ومع ذلك ، نظرًا لأن إعدادات مقعد السيارة مرتبطة بمستخدم Android ، فسوف يتحرك المقعد أثناء تبديل المستخدم. وبالتالي ، فإن وحدة التحكم الإلكترونية التي تتحكم في المقاعد لا تؤكد التبديل ، ويستجيب HAL بفشل ، ولا يتم تبديل مستخدم Android. سير العمل القديم عبارة عن مكالمة أحادية الاتجاه يتم إرسالها بعد تبديل المستخدم (لذلك لا يمكن لـ HAL حظر المحول). يتم استدعاؤه فقط عند التمهيد (بعد تبديل المستخدم الأولي) أو للتطبيقات التي تستدعي على سبيل المثال ، إذا كان التطبيق يستخدم ينشأ سير عمل السيارة من HAL ، وليس من نظام Android:
على سبيل المثال ، استخدم Bob سلسلة مفاتيح Alice لفتح السيارة ورد HAL على طلب |
CREATE_USER (قراءة و كتابة) | يتم استدعاء هذه الخاصية بواسطة نظام Android عند إنشاء مستخدم Android جديد (باستخدام واجهة برمجة تطبيقات CarUserManager.createUser() ). يستجيب HAL على سبيل المثال ، ينقر برنامج التشغيل على أيقونة واجهة مستخدم معلومات وترفيه لإنشاء مستخدم Android جديد. يؤدي هذا إلى إرسال طلب إلى HAL وبقية الأنظمة الفرعية للمركبة. يتم إعلام وحدات التحكم الإلكترونية بالمستخدم الذي تم إنشاؤه حديثًا. ثم تقوم الأنظمة الفرعية ووحدات التحكم الإلكترونية الأخرى بربط معرف المستخدم الداخلي الخاص بها بمعرف مستخدم Android. |
REMOVE_USER (اكتب فقط) | يستدعي نظام Android هذه الخاصية بعد إزالة مستخدم Android (باستخدام واجهة برمجة تطبيقات CarUserManager.removeUser() ).هذه مكالمة أحادية الاتجاه - لا يتوقع رد من HAL. على سبيل المثال ، ينقر برنامج التشغيل لإزالة مستخدم Android موجود في واجهة مستخدم نظام المعلومات والترفيه. يتم إبلاغ HAL ويتم إبلاغ الأنظمة الفرعية للمركبة ووحدات التحكم الإلكترونية الأخرى بإزالة المستخدم حتى يتمكنوا من إزالة معرف المستخدم الداخلي الخاص بهم. |
خصائص إضافية
فيما يلي خصائص إضافية غير مرتبطة بحالات دورة حياة المستخدم. يمكن تنفيذ كل منها بدون دعم HAL للمستخدم.
خاصية HAL | وصف |
---|---|
USER_IDENTIFICATION_ASSOCIATION (قراءة و كتابة) | استخدم هذه الخاصية لربط أي مستخدم Android بآلية تعريف ، مثل مفتاح فوب أو هاتف. استخدم هذه الخاصية نفسها get اقترانات أو set .على سبيل المثال ، ينقر السائق على أيقونة واجهة مستخدم معلومات وترفيه لربط مفتاح التشغيل المستخدم لفتح السيارة (KEY_123) بمستخدم Android النشط الحالي (USER_11). |
مكتبات المساعد
جميع الكائنات المستخدمة في رسائل الطلب والاستجابة (مثل UserInfo
و InitialUserInfoRequest
و InitialUSerInfoResponse
وما إلى ذلك) لها تمثيل عالي المستوى باستخدام struct
C ++ ، ولكن يجب تسوية VehiclePropValue
القياسية (انظر الأمثلة أدناه). لسهولة التطوير ، يتم توفير مكتبة مساعد C ++ في AOSP لتحويل VehiclePropValue
structs
والعكس صحيح).
أمثلة
INITIAL_USER_INFO
طلب مثال (في التمهيد الأول)
VehiclePropValue { // flattened from InitialUserInfoRequest prop: 299896583 // INITIAL_USER_INFO prop.values.int32Values: [0] = 1 // Request ID [1] = 1 // InitialUserInfoRequestType.FIRST_BOOT [2] = 0 // user id of current user [3] = 1 // flags of current user (SYSTEM) [4] = 1 // number of existing users [5] = 0 // existingUser[0].id [6] = 1 // existingUser[0].flags }
مثال على الاستجابة (إنشاء مستخدم مسؤول)
VehiclePropValue { // flattened from InitialUserInfoResponse prop: 299896583 // INITIAL_USER_INFO prop.values.int32Values: [0] = 1 // Request ID (must match request) [1] = 2 // InitialUserInfoResponseAction.CREATE [2] = -10000 // user id (not used on CREATE) [3] = 8 // user flags (ADMIN) prop.values.stringValue: "en-US||Car Owner" // User locale and User name }
تغير المستخدم
يختلف الاسم الفعلي للفئات والخصائص قليلاً ولكن سير العمل الكلي هو نفسه ، كما هو موضح أدناه:
الشكل 1. سير عمل خصائص HAL للمستخدم
مثال طلب سير العمل الحديث
VehiclePropValue { // flattened from SwitchUserRequest prop: 299896585 // SWITCH_USER prop.values.int32Values: [0] = 42 // Request ID [1] = 2 // SwitchUserMessageType::ANDROID_SWITCH ("modern") [2,3] = 11,0 // target user id (11) and flags (none in this case) [4,5] = 10,8 // current user id (10) and flags (ADMIN) [6] = 3 // number of existing users (0, 10, 11) [7,8] = 0,1 // existingUser[0] (id=0, flags=SYSTEM) [9,10] = 10,8 // existingUser[1] (id=10, flags=ADMIN) [11,12] = 11,0 // existingUser[2] (id=11, flags=NONE) }
مثال على استجابة سير العمل الحديثة
VehiclePropValue { // flattened from SwitchUserResponse prop: 299896584 // SWITCH_USER prop.values.int32Values: [0] = 42 // Request ID (must match request) [1] = 3 // SwitchUserMessageType::VEHICLE_RESPONSE [2] = 1 // SwitchUserStatus::SUCCESS }
مثال على استجابة ما بعد التبديل لسير العمل الحديث
تحدث هذه الاستجابة عادةً عندما ينجح مفتاح Android:
VehiclePropValue { // flattened from SwitchUserRequest prop: 299896584 // SWITCH_USER prop.values.int32Values: [0] = 42 // Request ID (must match "pre"-SWITCH_USER request ) [1] = 5 // SwitchUserMessageType::ANDROID_POST_SWITCH [2,3] = 11,0 // target user id (11) and flags (none in this case) [4,5] = 11,0 // current user id (11) and flags (none in this case) [6] = 3 // number of existing users (0, 10, 11) [7,8] = 0,1 // existingUser[0] (id=0, flags=SYSTEM) [9,10] = 10,8 // existingUser[1] (id=10, flags=ADMIN) [11,12] = 11,0 // existingUser[2] (id=11, flags=NONE) }
استجابة ما بعد التبديل الحديثة لسير العمل
تحدث هذه الاستجابة عادةً عندما يفشل مفتاح Android:
VehiclePropValue { // flattened from SwitchUserRequest prop: 299896584 // SWITCH_USER prop.values.int32Values: [0] = 42 // Request ID (must match "pre"-SWITCH_USER request ) [1] = 5 // SwitchUserMessageType::ANDROID_POST_SWITCH [2,3] = 11,0 // target user id (11) and flags (none in this case) [4,5] = 10,8 // current user id (10) and flags (ADMIN) [6] = 3 // number of existing users (0, 10, 11) [7,8] = 0,1 // existingUser[0] (id=0, flags=SYSTEM) [9,10] = 10,8 // existingUser[1] (id=10, flags=ADMIN) [11,12] = 11,0 // existingUser[2] (id=11, flags=NONE) }
مثال على طلب سير العمل القديم
VehiclePropValue { // flattened from SwitchUserRequest prop: 299896584 // SWITCH_USER prop.values.int32Values: [0] = 2 // Request ID [1] = 1 // SwitchUserMessageType::LEGACY_ANDROID_SWITCH [2,3] = 10,8 // target user id (10) and flags (ADMIN) [4,5] = 0,1 // current user id (0) and flags (SYSTEM) [6] = 3 // number of existing users (0, 10, 11) [7,8] = 0,1 // existingUser[0] (id=0, flags=SYSTEM) [9,10] = 10,8 // existingUser[1] (id=10, flags=ADMIN) [11,12] = 11,0 // existingUser[2] (id=11, flags=NONE) }
مثال على طلب سير عمل السيارة
VehiclePropValue { // flattened from SwitchUserRequest prop: 299896584 // SWITCH_USER prop.values.int32Values: [0] = -108 // Request ID (must be negative) [1] = 4 // SwitchUserMessageType::VEHICLE_REQUEST [2] = 11 // target user id }
استجابة ما بعد التبديل القديمة لسير العمل
تحدث هذه الاستجابة عادةً عندما ينجح مفتاح Android:
VehiclePropValue { // flattened from SwitchUserRequest prop: 299896584 // SWITCH_USER prop.values.int32Values: [0] = -108 // Request ID (must match from vehicle request ) [1] = 5 // SwitchUserMessageType::ANDROID_POST_SWITCH [2,3] = 11,0 // target user id (11) and flags (none in this case) [4,5] = 11,0 // current user id (11) and flags (none in this case) [6] = 3 // number of existing users (0, 10, 11) [7,8] = 0,1 // existingUser[0] (id=0, flags=SYSTEM) [9,10] = 10,8 // existingUser[1] (id=10, flags=ADMIN) [11,12] = 11,0 // existingUser[2] (id=11, flags=NONE) }
CREATE_USER
طلب مثال
VehiclePropValue { // flattened from CreateUserRequest prop: 299896585 // CREATE_USER prop.values.int32Values: [0] = 42 // Request ID [1,2] = 11,6 // Android id of the created user and flags (id=11, flags=GUEST, EPHEMERAL) [3,4] = 10,0 // current user id (10) and flags (none in this case) [5] = 3 // number of existing users (0, 10, 11) [6,7] = 0,1 // existingUser[0] (id=0, flags=SYSTEM) [8,9] = 10,8 // existingUser[1] (id=10, flags=ADMIN) [10,11] = 11,6 // newUser[2] (id=11, flags=GUEST,EPHEMERAL) }
مثال على الاستجابة
VehiclePropValue { // flattened from CreateUserResponse prop: 299896585 // CREATE_USER prop.values.int32Values: [0] = 42 // Request ID (must match request) [1] = 3 // CreateUserStatus::SUCCESS }
REMOVE_USER
طلب مثال
VehiclePropValue { // flattened from RemoveUserRequest prop: 299896586 // REMOVE_USER prop.values.int32Values: [0] = 42 // Request ID [1,2] = 11,0 // Android id of the removed user and flags (none in this case) [3,4] = 10,0 // current user id (10) and flags (none in this case) [5] = 2 // number of existing users (0, 10) [6,7] = 0,1 // existingUser[0] (id=0, flags=SYSTEM) [8,9] = 10,8 // existingUser[1] (id=10, flags=ADMIN) }
USER_IDENTIFICATION_ASSOCIATION
تعيين مثال (مفتاح فوب مرتبط بالمستخدم 10)
VehiclePropValue { // flattened from UserIdentificationSetRequest prop: 299896587 // USER_IDENTIFICATION_ASSOCIATION prop.values.int32Values: [0] = 43 // Request ID [1,2] = 10,0 // Android id (10) and flags (none in this case) [3] = 1 // number of associations being set [4] = 1 // 1st type: UserIdentificationAssociationType::KEY_FOB [5] = 1 // 1st value: UserIdentificationAssociationSetValue::ASSOCIATE_CURRENT_USER }