مواقع HAL للمستخدم

يحتوي العديد من بُنى المركبات الحالية على وحدات تحكُّم إلكترونية متعدّدة. (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 بأحد هذه الخيارات:
  • السلوك التلقائي الذي يضبطه Android (التبديل إلى آخر عملية استخدام المستخدم أو إنشاء مستخدم جديد إذا كانت هذه هي عملية التشغيل الأولى).
  • التبديل إلى مستخدم حالي.
  • إنشاء مستخدم جديد (باستخدام الخصائص الاختيارية للاسم والعلامات والنظام اللغة وما إلى ذلك) والتبديل إلى هذا المستخدم الجديد.

ملاحظة: في حال عدم استجابة "HAL"، سيكون السلوك التلقائي هو وتنفيذه بعد فترة المهلة (خمس ثوانٍ افتراضيًا)، مما يؤخر التشغيل. في حالة رد HAL، وإخفاق نظام Android في تنفيذ الإجراء (على سبيل المثال، إذا تم الوصول إلى الحد الأقصى لعدد المستخدمين)، يتم استخدام السلوك الافتراضي.

مثال: الإعداد التلقائي هو يبدأ نظام Android آخر المستخدم النشط عند التشغيل. في حال العثور على مفتاح لاسلكي لمستخدم آخر، ستبدأ وحدة التحكّم عن بُعد (ECU) خاصية HAL وعند بدء التشغيل، يتغير نظام Android لبدء لدى ذلك المستخدم المحدد.

SWITCH_USER
(قراءة/كتابة)
ويتم طلب هذه السمة عند تبديل مستخدم Android النشط الذي يعمل في المقدّمة. يمكن استدعاء الخاصية إما من خلال نظام Android أو بواسطة HAL إلى تطلب تبديل المستخدم. تشمل مهام سير العمل الثلاثة ما يلي:
  • حديث بدأ التبديل من CarUserManager.
  • الإصدار القديم: بدأ التبديل من ActivityManager.
  • المركبة: يتم استدعاؤه من خلال HAL لطلب تبديل المستخدم.

يعتمد سير العمل الحديث نهج التزام قائم على مرحلتين لضمان تتم مزامنة نظام Android مع وحدة ECU الخارجية. عندما يبدأ Android عملية التبديل:

  1. تحقَّق من HAL لتحديد ما إذا كان يمكن تبديل المستخدم.

    تتجاوب قناة HAL مع SUCCESS أو FAILURE، بحيث يعرف نظام Android ما إذا كان يريد المتابعة أم لا.

  2. أكمِل عملية تبديل مستخدم Android.

    يرسل Android الرد ANDROID_POST_SWITCH إلى HAL للإشارة إلى نجاح أو فشل التبديل.

من المفترَض أن تنتظر HAL حتى ما بعد ANDROID_POST_SWITCH. الاستجابة لتعديل حالتها من أجل مزامنة وحدات ECU أو تحديث طبقة تجريد الأجهزة (HAL) الأخرى المواقع.

مثال: يحاول السائق أثناء تحركه تبديل مستخدمي Android في واجهة مستخدم الترفيه والمعلومات. ومع ذلك، نظرًا لأن مقعد السيارة بمستخدم Android، يتحرك المقعد أثناء تبديل المستخدم. وبالتالي، فإن وحدة التحكّم عن بُعد في المقاعد لا تؤكد عملية التبديل، تستجيب قناة HAL بخطأ، ولا يتم تبديل مستخدم Android.

سير العمل القديم هو اتّصال أحادية الاتجاه يتم إرساله بعد تبديل المستخدِم. (وبالتالي لا يمكن لـ HAL حظر التبديل). ولا يتم استدعاؤه إلا عند التشغيل (بعد مفتاح تبديل المستخدم المبدئي) أو للتطبيقات التي تستدعي ActivityManager.switchUser() بدلاً من CarUserManager.switchUser() المرجع هناك تطبيقان (Settings) وSystemUI يستخدمان حاليًا لكن إذا وفر المصنّع الأصلي للجهاز تطبيقات الإعدادات الخاصة به للتبديل بين المستخدمين، على المصنّعين الأصليين للأجهزة تغيير طريقة الاستخدام.

مثال: إذا كان التطبيق يستخدم ActivityManager.switchUser() إلى تبديل المستخدمين، ثم يتم إرسال اتصال أحادي الاتجاه إلى HAL لإبلاغ المستخدم بأن المستخدم حدوث عملية تبديل.

ينشأ سير عمل المركبة من HAL، وليس من نظام Android:

  1. تطلب HAL تبديل المستخدم.
  2. يُكمِل النظام عملية تبديل مستخدم Android.
  3. يرسل Android استجابة ANDROID_POST_SWITCH إلى HAL للإشارة إلى أنّ نجاح أو فشل التبديل.

مثال: استخدم يوسف المفتاح اللاسلكي الخاص بأليس لفتح السيارة. وردت "هيئة الاتصالات الفيدرالية" (HAL) على طلب INITIAL_USER_INFO مع تضمين رقم تعريف المستخدم لأليس. وبعد ذلك، حددت وحدة ECU بمستشعرات حيوية أن السائق هو يوسف، أرسل HAL للمستخدم طلب SWITCH_USER لتبديل المستخدمين.

CREATE_USER
(قراءة/كتابة)
يطلب نظام Android هذه السمة عندما يكون مستخدم Android جديد تم إنشاؤه (باستخدام واجهة برمجة تطبيقات CarUserManager.createUser()).

تتجاوب قناة HAL مع SUCCESS أو FAILURE. إذا كانت يستجيب بروتوكول HAL للإخفاق، ويزيل نظام Android المستخدم.

مثال: ينقر سائق على رمز واجهة مستخدم نظام الترفيه والمعلومات إنشاء مستخدم Android جديد. يؤدي هذا إلى إرسال طلب إلى HAL وبقية للأنظمة الفرعية للمركبة. يتم إعلام وحدات ECU بالمستخدِم الذي تم إنشاؤه حديثًا. مشاكل أخرى والأنظمة الفرعية ووحدات ECU، ثم ربط رقم تعريف المستخدم الداخلي لديها بنظام 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، وما إلى ذلك) لديها تمثيل على مستوى عالٍ باستخدام 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
}