Android Automotive

As I’ve mentioned before, those would be terrible aspect ratios for any purpose, especially automotive. You wouldn’t be able to fit the on-screen keyboard in there because its far too short relative to its width.

1 Like

Hello,

I would like to validate the Vehicle HAL.
I have develop a little simulator that push some datas into sockets (speed, fuel level, positions latitude/longitude).
I know that I have to create my own HAL on this file hardware/libhardware/modules/vehicle/vehicle.c
I don’t understand very well the implementation of this file and where can I put a little C socket client that will get the datas and set them to notify applications that there are some new values.

Then, from the High Level (from an app) I would like to retrieve the new values from The CarSensorManager and display it (this part should work already)

A little help would be appreciate to better understand the architecture.
Thanks a lot.

That’s actually the old HAL.
The new implementation is in hardware/interfaces/automotive/vehicle.

1 Like

Why Google does not update their documentation :roll_eyes: ? I’ll check for it. Thanks

I just checked this implementation and it seems to be good.
I noticed that there is the class SocketComm which will open a Socket Server.
SocketComm opens a socket via adb’s TCP port forwarding to enable a Host PC to connect to the vehicleHAL The port is 33452

I would like to test that. But it seems that the service android.hardware.automotive.vehicle@2.0-service (located in /vendor/bin/hw) is not started so I cannot connect to it. When I execute : service check android.hardware.automotive.vehicle@2.0-service, it’s not recognized as a service … (not found)

How to start this complete implementation ? I see also that there is a FakeValueGenerator. Maybe I won’t need to use my custom one.

Thanks for help.

This is a bit of process.
It’s been a while since we were using the default vehicle impl, so these instructions might be a bit out of date.

Adding the Automotive HAL to a device


Inherit from the “car” build

Inherit from the car product in the device makefile (device/linaro/hikey/hikey960.mk):

$(call inherit-product, packages/services/Car/car_product/build/car.mk)

The vehicle HAL (android.hardware.automotive.vehicle@2.0) and other required services/apps are included through car.mk

Set SELinux to Permissive

In order to get the HAL to appear in the binderized section of the lshal command, we must:

  • disable SELinux (set to permissive mode) in the board config makefile (device/linaro/hikey/hikey960/BoardConfig.mk):
    BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive
    
    • Don’t forget to rebuild the device and re-install
    • You really should fix the permissions later, but for now this makes it easier to get up and running.

Manually start the service:

Do this in a terminal window you don’t mind losing.
Backgrounding like this while inside an adb connection will cause you to lose it.
Note that this will not work if you pass the command to adb shell.
It must be an interactive shell to work properly.

adb shell
/vendor/bin/hw/android.hardware.automotive.vehicle@2.0-service &

Fix the Device Manifest (optional)

To prevent this warning in the logcat logs add the vehicle HAL to the manifest.xml (device/linaro/hikey/manifest.xml)

https://source.android.com/devices/architecture/vintf/objects#device-manifest-file

ERROR:

The following error occurred when manifest.xml defined ‘hikey.hardware.automotive.vehicle’
‘/system/bin/hwservicemanager: getTransport: Cannot find entry android.hardware.automotive.vehicle@2.0::IVehicle/default in either framework or device manifest’

<hal format="hidl">
    <name>android.hardware.automotive.vehicle</name>
    <transport>hwbinder</transport>
    <version>2.0</version>
    <interface>
        <name>IVehicle</name>
        <instance>default</instance>
    </interface>
</hal>

Don’t forget to rebuild the device and re-install.

Automatically Start the Service on Boot

Finally, in order for init to automatically start the hardware service on boot, we need to add an SELinux domain and file context.
(Even though we’ve set SELinux to permissive, it is still enabled. Android does not allow disabling SELinux, only making it more permissive. So, there is still a minimal amount of configuration to be done.)

Create a *.te file for the hardware service that defines the domain.

device/linaro/hikey/sepolicy/hal_vehicle_hikey.te

# vehicle subsystem
type hal_vehicle_hikey, domain;

# may be started by init
type hal_vehicle_hikey_exec, exec_type, file_type;
init_daemon_domain(hal_vehicle_hikey)

Then add the domain to the executable to the domain.

device/linaro/hikey/sepolicy/file_contexts

/system/vendor/bin/hw/android\.hardware\.automotive\.vehicle@2\.0-service    u:object_r:hal_vehicle_hikey_exec:s0

Demonstrating the fake-value-generator HAL

  • Add the Vehicle HAL tests (located in packages/services/Car/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/) to PRODUCT_PACKAGES in the device makefile (device/linaro/hikey/hikey960.mk):
    PRODUCT_PACKAGES += VehicleHALTest
    
    • Don’t forget to rebuild the device and re-install, and manually start the vehicle HAL service
  • Run the tests
    adb shell am instrument -w com.android.car.vehiclehal.test/android.support.test.runner.AndroidJUnitRunner
    
  • To see the values from the UI:
    • Set up the board:
      • Connect a monitor to the hikey board
      • Power the board
    • Open the KitchenSinkApp
    • Open the sensors menu item
    • Run the tests (see above)
      • The values on the sensors view should show the generated HAL values for Speed, RPM, and Odometer that the tests trigger
2 Likes

I’d love to hear about your experiments with sending values via the socket.
Being able to do that would be really valuable when running in an emulator.

1 Like

Thank you so much for your Adding HAL to device helper.
It seems to work, now the service is running correctly.

Problem is on the running tests, the FakeValueGenerator. Got this error :
android.util.AndroidException: INSTRUMENTATION_FAILED:

In fact, it is not on the list of the possible instrumentation.
The output of this command : adb shell pm list instrumentation is instrumentation:org.chromium.webview_shell/.WebViewLayoutTestRunner (target=org.chromium.webview_shell) only.

Maybe this line PRODUCT_PACKAGES += VehicleHALTest did not do anything ?

Maybe. Have you tried running adb install on the apk to manually install the tests?

No I did not. I found the APK and installed it.

The tests are not updating the values on the KitchenSinkApp.

com.android.car.vehiclehal.test.E2ePerformanceTest:…
com.android.car.vehiclehal.test.Obd2FreezeFrameTest:.
com.android.car.vehiclehal.test.Obd2LiveFrameTest:.

Time: 2.407

OK (7 tests)

In fact they finish after 2 seconds.

Are these tests calling the code FakeValueGenerator.cpp that I see in hardware/interfaces/automotive/vehicle ?

EDIT:
Indeed, I noticed that the EmbeddKitchenSinkApp has some problems to connect to the Car.
here is my logcat :
https://gist.github.com/AhmedX6/17213a06b30ef6971107a7ffa9d0b120

Hmm… that’s interesting.
Looks like the Vehicle service crashed.
We were also seeing intermittent dead object exceptions yesterday on master.
I’m wondering if something changed recently.
Not sure, but I’ll let you know if we find the cause.

Thank you. I noticed that there was an exception in line 220 of SensorHalService.java (ArrayIndexOutOfBounds)…

Can you try running adb logcat CAR.SENSOR:* *:S to see what’s going on in there?
Might want to do it on a fresh boot to get early logs too.
adb reboot && adb logcat CAR.SENSOR:* :*S

You might also want to try adding additional logging to that file to get extra visibility into what’s happening.

It’s a misery… CPU is overheating. And I have so much exceptions like that.

CAR.SENSOR.KS: Unrecognized event type: 22
04-11 15:18:51.233  3177  3177 W System.err: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0

I think I will develop my own application that will connect to the car and the Sensor.
You think it’s possible on user application ? Or application must be system ?

What is the best solution ?
I don’t know really if the testRunner is working well. I see some values changing but the app bugs too much.

The best solution is to dig in and figure out what event type 22 is, where it’s coming from, and why the index is out of bounds.

I consistently find it disappointing that the Hikey960 is only supported on the master branch when there’s no guarantee the master branch works at any given moment in time…

Event type 22 should be public static final int SENSOR_TYPE_IGNITION_STATE = 22;

#EDIT
I did develop my own application that connect to Car Service and I think I found where is the problem on KitchenApp, because I don’t have any problem on my own application
Problems come from :
for (Integer sensor : supportedSensors) { ...} at line 128 of SensorTestFragment.java. When adding multiple listeners it makes crash the CarSensorManager, the result is a DeadObjectException.

So in my application I just added one listener on the SPEED and I have no problems.

1 Like

@doitright

Is it possible to get the position using : Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); with Android Automotive ?

I have plugged a USB GPS but indeed, no ttyUSB0 is mounted. I tested on a Raspberry my USB GPS and I see the ttyUSBO.

Maybe a configuration on Kernel is missing ?

Thanks for help.

So first off, a GPS is not a filesystem, so they are not mounted.
If your GPS isn’t working, the first thing you need to check is the kernel output. Plug it in, and see what the kernel says.

Regarding the device file for the GPS, that would depend on what kind of hardware is in your “USB GPS”. I’ve been working with U-BLOX GPS’s, since they are both inexpensive, and very good. They enumerate as /dev/ttyACMx (and so you will notice that all of my configurations have it set to reflect that path). If yours enumerates as ttyUSB0, then you would have to adjust the configurations (this means GPS HAL, SELINUX policy, and UEVENT configuration) to match yours.

While I can’t possibly enable every possible hardware configuration in the kernel, I can tell you that the kernel (upstream AOSP one, and thus copied into my fork) does have most generic USB-serial drivers enabled. You can’t just guess that something is missing in the kernel until you actually check what the kernel says when you plug the hardware in.

1 Like

Thank for all these explanations.
Here you have the output when I plug my USB GPS.
:confused: $ [ 1249.892694] usb 1-1.2.4: new full-speed USB device number 7 using xhci-hcd
[ 1250.059676] usb 1-1.2.4: New USB device found, idVendor=10c4, idProduct=ea60
[ 1250.067150] usb 1-1.2.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 1250.074861] usb 1-1.2.4: Product: CP2102 USB to UART Bridge Controller
[ 1250.081544] usb 1-1.2.4: Manufacturer: Silicon Labs
[ 1250.086627] usb 1-1.2.4: SerialNumber: 0001

Indeed I see in file_contexts line /dev/ttyACM(.*) u:object_r:console_device:s0.
What should I change exactly, I don’t really understand how all that works.

When I say “mounted” I mean that there is no ttyUSB created when I plug the GPS USB.
In file_contexts I see also /dev/ttyUSB(.*) u:object_r:console_device:s0. This one does not work then ?

Everything that says ttyUSB0 is for the AMFM RADIO.

Your hardware is supported by the cp210x driver: https://github.com/torvalds/linux/blob/master/drivers/usb/serial/cp210x.c#L144

To enable that, you will have to set CONFIG_USB_SERIAL_CP210X=y in your kernel config.

Probably isn’t enabled, because its a very unusual part.

1 Like