يحتوي العديد من بُنى المركبات الحالية على وحدات تحكُّم إلكترونية متعدّدة. (ECU) خارج نظام الترفيه والمعلومات الذي يتحكم في سهولة العمل، مثل المقعد الإعدادات والتعديلات المعكوسة. استنادًا إلى الأجهزة والطاقة الحالية الهياكل الهندسية المختلفة، يتم تشغيل العديد من وحدات ECU قبل أن يتم تشغيل نظام الترفيه والمعلومات المستند إلى Android تم تشغيل الجهاز. يمكن ربط وحدات ECU هذه بنظام المعلومات والترفيه المستند إلى Android. النظام من خلال طبقة تجريد أجهزة المركبة (VHAL):
بدءًا من نظام التشغيل Android 11، قدّم نظام التشغيل Android Automotive (AAOS) مجموعة جديدة من الخصائص على VHAL للإنشاء والتبديل والإزالة والربط والملحقات الخارجية لتحديد هوية المستخدمين. على سبيل المثال، تتيح هذه المواقع الجديدة برنامج تشغيل لربط ملحق خارجي، مثل مفتاح لاسلكي، بمستخدم Android وبعد ذلك، عندما يقترب السائق من المركبة، تستيقظ وحدة ECU وترصد وجود المفتاح اللاسلكي. تشير وحدة ECU هذه إلى HAL مستخدم Android الذي يجب أن عليه نظام الترفيه والمعلومات. بدء تشغيل الجهاز، ما يقلل من الوقت الذي ينتظره السائق عند تشغيل جهاز Android المستخدم المطلوب تحميله.
تفعيل HAL للمستخدم
يجب تفعيل خصائص 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 shell
getprop android.car.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 ووحدة ECU خارجية. تستخدم هذه السمات بروتوكول الطلب والاستجابة، في الذي يطلبه نظام Android من خلال تعيين قيمة خاصية يستجيب HAL من خلال إصدار حدث تغيير الموقع.
ملاحظة: في حال توفُّر HAL للمستخدم، جميع ما يلي: الخاصة به.
خاصية HAL | الوصف |
---|---|
INITIAL_USER_INFO (قراءة/كتابة) |
ويستدعي نظام Android هذه الخاصية لتحديد نظام Android.
المستخدم الذي يبدأ تشغيل النظام منه عند تشغيل الجهاز أو استئناف تشغيله
التعليق على ذاكرة الوصول العشوائي (STR). وعند استدعائها، يجب أن تستجيب HAL بأحد
هذه الخيارات:
ملاحظة: في حال عدم استجابة "HAL"، سيكون السلوك التلقائي هو وتنفيذه بعد فترة المهلة (خمس ثوانٍ افتراضيًا)، مما يؤخر التشغيل. في حالة رد HAL، وإخفاق نظام Android في تنفيذ الإجراء (على سبيل المثال، إذا تم الوصول إلى الحد الأقصى لعدد المستخدمين)، يتم استخدام السلوك الافتراضي. مثال: الإعداد التلقائي هو يبدأ نظام Android آخر المستخدم النشط عند التشغيل. في حال العثور على مفتاح لاسلكي لمستخدم آخر، ستبدأ وحدة التحكّم عن بُعد (ECU) خاصية HAL وعند بدء التشغيل، يتغير نظام Android لبدء لدى ذلك المستخدم المحدد. |
SWITCH_USER (قراءة/كتابة) |
ويتم طلب هذه السمة عند تبديل مستخدم Android النشط الذي يعمل في المقدّمة.
يمكن استدعاء الخاصية إما من خلال نظام Android أو بواسطة HAL إلى
تطلب تبديل المستخدم. تشمل مهام سير العمل الثلاثة ما يلي:
يعتمد سير العمل الحديث نهج التزام قائم على مرحلتين لضمان تتم مزامنة نظام Android مع وحدة ECU الخارجية. عندما يبدأ Android عملية التبديل:
من المفترَض أن تنتظر HAL حتى ما بعد مثال: يحاول السائق أثناء تحركه تبديل مستخدمي Android في واجهة مستخدم الترفيه والمعلومات. ومع ذلك، نظرًا لأن مقعد السيارة بمستخدم Android، يتحرك المقعد أثناء تبديل المستخدم. وبالتالي، فإن وحدة التحكّم عن بُعد في المقاعد لا تؤكد عملية التبديل، تستجيب قناة HAL بخطأ، ولا يتم تبديل مستخدم Android.
سير العمل القديم هو اتّصال أحادية الاتجاه يتم إرساله بعد تبديل المستخدِم.
(وبالتالي لا يمكن لـ HAL حظر التبديل). ولا يتم استدعاؤه إلا عند التشغيل (بعد
مفتاح تبديل المستخدم المبدئي) أو للتطبيقات التي تستدعي
مثال: إذا كان التطبيق يستخدم
ينشأ سير عمل المركبة من HAL، وليس من نظام Android:
مثال: استخدم يوسف المفتاح اللاسلكي الخاص بأليس لفتح السيارة.
وردت "هيئة الاتصالات الفيدرالية" (HAL) على طلب |
CREATE_USER (قراءة/كتابة) |
يطلب نظام Android هذه السمة عندما يكون مستخدم Android جديد
تم إنشاؤه (باستخدام واجهة برمجة تطبيقات CarUserManager.createUser() ).
تتجاوب قناة HAL مع مثال: ينقر سائق على رمز واجهة مستخدم نظام الترفيه والمعلومات إنشاء مستخدم Android جديد. يؤدي هذا إلى إرسال طلب إلى HAL وبقية للأنظمة الفرعية للمركبة. يتم إعلام وحدات ECU بالمستخدِم الذي تم إنشاؤه حديثًا. مشاكل أخرى والأنظمة الفرعية ووحدات ECU، ثم ربط رقم تعريف المستخدم الداخلي لديها بنظام Android رقم تعريف المستخدم |
REMOVE_USER (الكتابة فقط) |
يستدعي نظام Android هذه الخاصية بعد أن يكون مستخدم Android
تمت إزالتها (باستخدام الطريقة CarUserManager.removeUser() ).
هذه مكالمة أحادية الاتجاه، ولا يُتوقَّع أي ردّ من HAL. مثال: ينقر السائق لإزالة صورة حالية مستخدم Android في واجهة مستخدم نظام الترفيه والمعلومات يتم إعلام HAL وإرشادات يتم إعلام الأنظمة الفرعية للمركبة ووحدات التحكم بالوحدة الإلكترونية بإزالة المستخدم إزالة رقم تعريف المستخدم الداخلي لديهم. |
المواقع الإضافية
في ما يلي سمات إضافية غير مرتبطة بحالات مراحل نشاط المستخدم. ويمكن تنفيذ كل منها بدون دعم طبقة تجريد الأجهزة (HAL) للمستخدم.
خاصية HAL | الوصف |
---|---|
USER_IDENTIFICATION_ASSOCIATION (قراءة/كتابة) |
استخدِم هذا الموقع لربط أي مستخدم Android بتعريف شخصي.
آلية، مثل مفتاح لاسلكي أو هاتف. استخدِم هذه السمة نفسها من أجل
get أو set عملية ربط.
مثال: ينقر سائق على رمز "واجهة المستخدم لنظام الترفيه والمعلومات" لربطه.
المفتاح اللاسلكي المستخدَم لفتح المركبة ( |
المكتبات المساعدة
جميع العناصر المستخدَمة في رسائل الطلب والردّ (مثل
UserInfo
، InitialUserInfoRequest
،
InitialUSerInfoResponse
، وما إلى ذلك) لديها تمثيل على مستوى عالٍ
باستخدام C++ struct
، لكن يجب تسوية الإزالة
كائنات VehiclePropValue
القياسية (انظر الأمثلة أدناه). لتسهيل الاستخدام
من التطوير،
لغة C++
يتم توفير "مكتبة مساعد Google" في AOSP لتحويل HAL للمستخدم تلقائيًا.
structs
إلى VehiclePropValue
(والعكس).
أمثلة
معلومات_المستخدم INITIAL
مثال على الطلب (عند التشغيل لأول مرة)
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 }
SWITCH_USER
ويختلف الاسم الفعلي للفئات والخصائص قليلاً، ولكن وسير العمل العام هو ذاته، كما هو موضح أدناه:
الشكل 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 }
إزالة_المستخدم
مثال على الطلب
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 }