Skip to content
Vehicle properties
Users & security

SWITCH_USER

What it is

Defines a request to switch the foreground Android user.

This property is used primarily by the Android System to inform the HAL that the current foreground Android user is switching, but it could also be used by the HAL to request the Android system to switch users - the

When the request is made by Android, it sets a VehiclePropValue and the HAL must responde with a property change event; when the HAL is making the request, it must also do it through a property change event (the main difference is that the request id will be positive in the former case, and negative in the latter; the SwitchUserMessageType will also be different).

The format of both request is defined by SwitchUserRequest and the format of the response (when needed) is defined by SwitchUserResponse. How the HAL (or Android System) should proceed depends on the message type (which is defined by the SwitchUserMessageType parameter), as defined below.

1.LEGACY_ANDROID_SWITCH -----------------------

Called by the Android System to indicate the Android user is about to change, when the change request was made in a way that is not integrated with the HAL (for example, through adb shell am switch-user).

The HAL can switch its internal user once it receives this request, but it doesn't need to reply back to the Android System. If its internal user cannot be changed for some reason, then it must wait for the SWITCH_USER(type=ANDROID_POST_SWITCH) call to recover (for example, it could issue a SWITCH_USER(type=VEHICLE_REQUEST) to switch back to the previous user), but ideally it should never fail (as switching back could result in a confusing experience for the end user).

For example, if the system have users (0, 10, 11) and it's switching from 0 to 11 (where none of them have any special flag), the request would be:

int32[0]: 42 // request id int32[1]: 1 // SwitchUserMessageType::LEGACY_ANDROID_SWITCH int32[2]: 11 // target user id int32[3]: 0 // target user flags (none) int32[4]: 10 // current user int32[5]: 0 // current user flags (none) int32[6]: 3 // number of users int32[7]: 0 // user #0 (Android user id 0) int32[8]: 0 // flags of user #0 (none) int32[9]: 10 // user #1 (Android user id 10) int32[10]: 0 // flags of user #1 (none) int32[11]: 11 // user #2 (Android user id 11) int32[12]: 0 // flags of user #2 (none)

2.ANDROID_SWITCH ---------------- Called by the Android System to indicate the Android user is about to change, but Android will wait for the HAL's response (up to some time) before proceeding.

The HAL must switch its internal user once it receives this request, then respond back to Android with a SWITCH_USER(type=VEHICLE_RESPONSE) indicating whether its internal user was switched or not (through the SwitchUserStatus enum).

For example, if Android has users (0, 10, 11) and it's switching from 10 to 11 (where none of them have any special flag), the request would be:

int32[0]: 42 // request id int32[1]: 2 // SwitchUserMessageType::ANDROID_SWITCH int32[2]: 11 // target user id int32[3]: 0 // target user flags (none) int32[4]: 10 // current user int32[5]: 0 // current user flags (none) int32[6]: 3 // number of users int32[7]: 0 // 1st user (user 0) int32[8]: 1 // 1st user flags (SYSTEM) int32[9]: 10 // 2nd user (user 10) int32[10]: 0 // 2nd user flags (none) int32[11]: 11 // 3rd user (user 11) int32[12]: 0 // 3rd user flags (none)

If the request succeeded, the HAL must update the property with:

int32[0]: 42 // request id int32[1]: 3 // messageType = SwitchUserMessageType::VEHICLE_RESPONSE int32[2]: 1 // status = SwitchUserStatus::SUCCESS

But if it failed, the response would be something like:

int32[0]: 42 // request id int32[1]: 3 // messageType = SwitchUserMessageType::VEHICLE_RESPONSE int32[2]: 2 // status = SwitchUserStatus::FAILURE string: "108-D'OH!" // OEM-specific error message

3.VEHICLE_RESPONSE ------------------ Called by the HAL to indicate whether a request of type ANDROID_SWITCH should proceed or abort - see the ANDROID_SWITCH section above for more info.

4.VEHICLE_REQUEST ------------------ Called by the HAL to request that the current foreground Android user is switched.

This is useful in situations where Android started as one user, but the vehicle identified the driver as another user. For example, user A unlocked the car using the key fob of user B; the INITIAL_USER_INFO request returned user B, but then a face recognition subsubsystem identified the user as A.

The HAL makes this request by a property change event (passing a negative request id), and the Android system will response by issue an ANDROID_POST_SWITCH call which the same request id.

For example, if the current foreground Android user is 10 and the HAL asked it to switch to 11, the request would be:

int32[0]: -108 // request id int32[1]: 4 // messageType = SwitchUserMessageType::VEHICLE_REQUEST int32[2]: 11 // Android user id

If the request succeeded and Android has 3 users (0, 10, 11), the response would be:

int32[0]: -108 // request id int32[1]: 5 // messageType = SwitchUserMessageType::ANDROID_POST_SWITCH int32[2]: 11 // target user id int32[3]: 0 // target user id flags (none) int32[4]: 11 // current user int32[5]: 0 // current user flags (none) int32[6]: 3 // number of users int32[7]: 0 // 1st user (user 0) int32[8]: 0 // 1st user flags (none) int32[9]: 10 // 2nd user (user 10) int32[10]: 4 // 2nd user flags (none) int32[11]: 11 // 3rd user (user 11) int32[12]: 3 // 3rd user flags (none)

Notice that both the current and target user ids are the same - if the request failed, then they would be different (i.e, target user would be 11, but current user would still be 10).

5.ANDROID_POST_SWITCH --------------------- Called by the Android System after a request to switch a user was made.

This property is called after switch requests of any type (i.e., LEGACY_ANDROID_SWITCH, ANDROID_SWITCH, or VEHICLE_REQUEST) and can be used to determine if the request succeeded or failed:

1. When it succeeded, it's called when the Android user is in the unlocked state and the value of the current and target users ids in the response are the same. This would be equivalent to receiving an Intent.ACTION_USER_UNLOCKED in an Android app. 2. When it failed it's called right away and the value of the current and target users ids in the response are different (as the current user didn't change to the target). 3. If a new switch request is made before the HAL responded to the previous one or before the user was unlocked, then the ANDROID_POST_SWITCH request is not made. For example, the driver could accidentally switch to the wrong user which has lock credentials, then switch to the right one before entering the credentials.

The HAL can update its internal state once it receives this request, but it doesn't need to reply back to the Android System.

Request: the first N values as defined by INITIAL_USER_INFO (where the request-specific value at index 1 is SwitchUserMessageType::ANDROID_POST_SWITCH), then 2 more values for the target user id (i.e., the Android user id that was requested to be switched to) and its flags (as defined by UserFlags).

Response: none.

Example: see VEHICLE_REQUEST section above.

How the ID is built

A property ID is a 32-bit value packing four fields. Reading 0x11e00f08 apart:

FieldMaskValueMeans
Group0xf00000000x10000000SYSTEM
Area0x0f0000000x01000000GLOBAL
Type0x00ff00000x00e00000MIXED
Ordinal0x0000ffff0x00000f080xf08

Reading it from an app

CarPropertyManager mgr = (CarPropertyManager)
        car.getCarManager(Car.PROPERTY_SERVICE);

CarPropertyValue<Object> value =
        mgr.getProperty(VehiclePropertyIds.SWITCH_USER, 0);

This property can be read and written, though an OEM may implement it as read-only. It fires a callback whenever the value changes.