summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2022-06-14 16:39:44 -0700
committerXin Li <delphij@google.com>2022-06-14 16:39:44 -0700
commit0dd139b130fa8ebd11e4727dfd140588fc1c5b7b (patch)
treec8b2cfd24c1afd5c5ce407fea09276c2d09ec910
parentbfcee185bfba01d772cb21765a9e27634cfb85d2 (diff)
parenta24498718ccbfd10a4fc43a1ba9a2ecb2d8523b8 (diff)
downloadcar-0dd139b130fa8ebd11e4727dfd140588fc1c5b7b.tar.gz
Merge Android 12 QPR 3
Bug: 236045730 Merged-In: If61a479068bf9475b36885e3dcce778dfeb0b6e3 Change-Id: I8532fa760096167baa0ccb23938025c8d3e78989
-rw-r--r--emulator/aosp_car_emulator.mk8
-rw-r--r--emulator/audio/audio_policy_configuration.xml121
-rw-r--r--emulator/audio/car_emulator_audio.mk1
-rw-r--r--emulator/audio/driver/Android.bp21
-rw-r--r--emulator/audio/driver/audio_extn/audio_extn.h38
-rw-r--r--emulator/audio/driver/audio_extn/hfp.c143
-rw-r--r--emulator/audio/driver/audio_hw.c68
-rw-r--r--emulator/audio/driver/audio_hw.h1
-rw-r--r--emulator/audio/driver/audio_vbuffer.c3
-rw-r--r--emulator/audio/driver/ext_pcm.c54
-rw-r--r--emulator/audio/driver/ext_pcm.h1
-rw-r--r--emulator/audio/halservice/android.hardware.audio.service-caremu.rc1
-rw-r--r--emulator/audio/halservice/service.cpp10
-rw-r--r--emulator/usbpt/BoardConfig.mk16
-rw-r--r--emulator/usbpt/bluetooth/BoardConfig.mk18
-rw-r--r--emulator/usbpt/bluetooth/bluetooth.mk (renamed from emulator/bluetooth/btlinux-service.mk)16
-rw-r--r--emulator/usbpt/bluetooth/btusb/BoardConfig.mk24
-rw-r--r--emulator/usbpt/bluetooth/btusb/btusb.mk27
-rw-r--r--emulator/usbpt/bluetooth/btusb/hal/bdroid_buildcfg.h (renamed from emulator/bluetooth/hal/bdroid_buildcfg.h)0
-rw-r--r--emulator/usbpt/bluetooth/btusb/init.btusb.rc5
-rw-r--r--emulator/usbpt/bluetooth/btusb/rtl_bt/Android.bp24
-rwxr-xr-xemulator/usbpt/bluetooth/btusb/rtl_bt/rtl8821c_config.binbin0 -> 10 bytes
-rw-r--r--emulator/usbpt/bluetooth/btusb/rtl_bt/rtl8821c_fw.binbin0 -> 48816 bytes
-rw-r--r--emulator/usbpt/bluetooth/btusb/sepolicy/bluetooth.te2
-rw-r--r--emulator/usbpt/bluetooth/btusb/sepolicy/domain.te (renamed from emulator/bluetooth/sepolicy/domain.te)0
-rw-r--r--emulator/usbpt/bluetooth/btusb/sepolicy/file.te1
-rw-r--r--emulator/usbpt/bluetooth/btusb/sepolicy/file_contexts2
-rw-r--r--emulator/usbpt/bluetooth/btusb/sepolicy/property_contexts (renamed from emulator/bluetooth/sepolicy/property_contexts)0
-rw-r--r--emulator/usbpt/bluetooth/modules.blocklist2
-rw-r--r--emulator/usbpt/bluetooth/usb_modeswitch/Android.bp (renamed from emulator/usb_modeswitch/Android.bp)0
-rw-r--r--emulator/usbpt/bluetooth/usb_modeswitch/LICENSE (renamed from emulator/usb_modeswitch/LICENSE)0
-rw-r--r--emulator/usbpt/bluetooth/usb_modeswitch/usb_modeswitch.c (renamed from emulator/usb_modeswitch/usb_modeswitch.c)0
-rw-r--r--emulator/usbpt/bluetooth/usb_modeswitch/usb_modeswitch.h (renamed from emulator/usb_modeswitch/usb_modeswitch.h)0
-rw-r--r--emulator/usbpt/bluetooth/vendor.qemu.preferred.bt.service.rc (renamed from emulator/bluetooth/vendor.qemu.preferred.bt.service.rc)0
-rw-r--r--emulator/usbpt/car_usbpt.mk (renamed from emulator/btusb-passthrough/btusb.mk)7
-rw-r--r--emulator/usbpt/usbip-service/Android.bp63
-rw-r--r--emulator/usbpt/usbip-service/COPYING340
-rw-r--r--emulator/usbpt/usbip-service/README.md4
-rw-r--r--emulator/usbpt/usbip-service/TEST_MAPPING8
-rw-r--r--emulator/usbpt/usbip-service/UsbIpService.cpp55
-rw-r--r--emulator/usbpt/usbip-service/UsbIpTest.cpp101
-rw-r--r--emulator/usbpt/usbip-service/UsbIpUtils.cpp178
-rw-r--r--emulator/usbpt/usbip-service/UsbIpUtils.h25
-rw-r--r--emulator/usbpt/usbip-service/sepolicy/file_contexts4
-rw-r--r--emulator/usbpt/usbip-service/sepolicy/usbip_service.te16
-rw-r--r--emulator/usbpt/usbip-service/usbip-service.mk19
-rw-r--r--emulator/usbpt/usbip-service/usbip-service.rc2
-rw-r--r--emulator_car_x86_64/BoardConfig.mk3
-rw-r--r--gsi_car_base.mk1
49 files changed, 1318 insertions, 115 deletions
diff --git a/emulator/aosp_car_emulator.mk b/emulator/aosp_car_emulator.mk
index abf872d..711b590 100644
--- a/emulator/aosp_car_emulator.mk
+++ b/emulator/aosp_car_emulator.mk
@@ -25,8 +25,8 @@ $(call inherit-product, device/generic/car/common/car.mk)
# This overrides device/generic/car/common/car.mk
$(call inherit-product, device/generic/car/emulator/audio/car_emulator_audio.mk)
$(call inherit-product, device/generic/car/emulator/rotary/car_rotary.mk)
-# Enables USB and BT-USB passthrough
-$(call inherit-product, device/generic/car/emulator/btusb-passthrough/btusb.mk)
+# Enables USB related passthrough
+$(call inherit-product, device/generic/car/emulator/usbpt/car_usbpt.mk)
ifeq (true,$(BUILD_EMULATOR_CLUSTER_DISPLAY))
PRODUCT_COPY_FILES += \
@@ -35,7 +35,6 @@ PRODUCT_COPY_FILES += \
PRODUCT_PRODUCT_PROPERTIES += \
hwservicemanager.external.displays=1,400,600,120,0 \
persist.service.bootanim.displays=8140900251843329 \
- ro.carwatchdog.vhal_healthcheck.interval=10 \
ifeq (true,$(ENABLE_CLUSTER_OS_DOUBLE))
DEVICE_PACKAGE_OVERLAYS += device/generic/car/emulator/cluster/osdouble_overlay
@@ -43,3 +42,6 @@ else
DEVICE_PACKAGE_OVERLAYS += device/generic/car/emulator/cluster/overlay
endif # ENABLE_CLUSTER_OS_DOUBLE
endif # BUILD_EMULATOR_CLUSTER_DISPLAY
+
+PRODUCT_PRODUCT_PROPERTIES += \
+ ro.carwatchdog.vhal_healthcheck.interval=10 \
diff --git a/emulator/audio/audio_policy_configuration.xml b/emulator/audio/audio_policy_configuration.xml
index 4e61c76..d2a2b26 100644
--- a/emulator/audio/audio_policy_configuration.xml
+++ b/emulator/audio/audio_policy_configuration.xml
@@ -26,8 +26,8 @@
The module names are the same as in current .conf file:
“primary”, “A2DP”, “remote_submix”, “USB”
Each module will contain the following sections:
- “devicePorts”: a list of device descriptors for all input and output devices accessible via this
- module.
+ “devicePorts”: a list of device descriptors for all input and output devices accessible via
+ this module.
This contains both permanently attached devices and removable devices.
"gain": constraints applied to the millibel values:
- maxValueMB >= minValueMB
@@ -35,8 +35,8 @@
- (maxValueMB - minValueMB) % stepValueMB == 0
- (defaultValueMB - minValueMB) % stepValueMB == 0
“mixPorts”: listing all output and input streams exposed by the audio HAL
- “routes”: list of possible connections between input and output devices or between stream and
- devices.
+ “routes”: list of possible connections between input and output devices or between stream
+ and devices.
"route": is defined by an attribute:
-"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
-"sink": the sink involved in this route
@@ -60,7 +60,7 @@
<item>bus6_notification_out</item>
<item>bus7_system_sound_out</item>
<!-- names with _audio_zone_# are used for defined an emulator rear seat audio zone
- where each number # is the zone id number -->
+ where each number # is the zone id number -->
<item>bus100_audio_zone_1</item>
<item>bus200_audio_zone_2</item>
<item>Built-In Mic</item>
@@ -73,7 +73,7 @@
<defaultOutputDevice>bus0_media_out</defaultOutputDevice>
<mixPorts>
<mixPort name="mixport_bus0_media_out" role="source"
- flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ flags="AUDIO_OUTPUT_FLAG_PRIMARY">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
@@ -146,84 +146,93 @@
</mixPorts>
<devicePorts>
<devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- address="bus0_media_out">
+ address="bus0_media_out">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+ minValueMB="-3200" maxValueMB="600"
+ defaultValueMB="0" stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="bus1_navigation_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
address="bus1_navigation_out">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+ minValueMB="-3200" maxValueMB="600"
+ defaultValueMB="0" stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="bus2_voice_command_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- address="bus2_voice_command_out">
+ address="bus2_voice_command_out">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+ minValueMB="-3200" maxValueMB="600"
+ defaultValueMB="0" stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="bus3_call_ring_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- address="bus3_call_ring_out">
+ address="bus3_call_ring_out">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+ minValueMB="-3200" maxValueMB="600"
+ defaultValueMB="0" stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="bus4_call_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- address="bus4_call_out">
+ address="bus4_call_out">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+ minValueMB="-3200" maxValueMB="600"
+ defaultValueMB="0" stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="bus5_alarm_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- address="bus5_alarm_out">
+ address="bus5_alarm_out">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+ minValueMB="-3200" maxValueMB="600"
+ defaultValueMB="0" stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="bus6_notification_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- address="bus6_notification_out">
+ address="bus6_notification_out">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+ minValueMB="-3200" maxValueMB="600"
+ defaultValueMB="0" stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="bus7_system_sound_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- address="bus7_system_sound_out">
+ address="bus7_system_sound_out">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+ minValueMB="-3200" maxValueMB="600"
+ defaultValueMB="0" stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="bus100_audio_zone_1" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- address="bus100_audio_zone_1">
+ address="bus100_audio_zone_1">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+ minValueMB="-3200" maxValueMB="600"
+ defaultValueMB="0" stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="bus200_audio_zone_2" role="sink" type="AUDIO_DEVICE_OUT_BUS"
@@ -232,31 +241,35 @@
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+ minValueMB="-3200" maxValueMB="600"
+ defaultValueMB="0" stepValueMB="100"/>
</gains>
</devicePort>
- <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+ <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"
+ address="Built-In Mic" >
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
- channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
- <devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source">
+ <devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC"
+ role="source" address="Built-In Back Mic">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
- channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
- <devicePort tagName="Echo-Reference Mic" type="AUDIO_DEVICE_IN_ECHO_REFERENCE" role="source">
+ <devicePort tagName="Echo-Reference Mic" type="AUDIO_DEVICE_IN_ECHO_REFERENCE" role="source"
+ address="Echo-Reference Mic">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
- channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
<devicePort tagName="FM Tuner" type="AUDIO_DEVICE_IN_FM_TUNER" role="source"
- address="tuner0">
+ address="tuner0">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
<gains>
<gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+ minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="Tone Generator 0" type="AUDIO_DEVICE_IN_BUS" role="source"
@@ -265,7 +278,8 @@
samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
<gains>
<gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+ minValueMB="-3200" maxValueMB="600"
+ defaultValueMB="0" stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="Tone Generator 1" type="AUDIO_DEVICE_IN_BUS" role="source"
@@ -274,7 +288,8 @@
samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
<gains>
<gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+ minValueMB="-3200" maxValueMB="600"
+ defaultValueMB="0" stepValueMB="100"/>
</gains>
</devicePort>
</devicePorts>
@@ -282,15 +297,19 @@
<routes>
<route type="mix" sink="bus0_media_out" sources="mixport_bus0_media_out"/>
<route type="mix" sink="bus1_navigation_out" sources="mixport_bus1_navigation_out"/>
- <route type="mix" sink="bus2_voice_command_out" sources="mixport_bus2_voice_command_out"/>
+ <route type="mix" sink="bus2_voice_command_out"
+ sources="mixport_bus2_voice_command_out"/>
<route type="mix" sink="bus3_call_ring_out" sources="mixport_bus3_call_ring_out"/>
<route type="mix" sink="bus4_call_out" sources="mixport_bus4_call_out"/>
<route type="mix" sink="bus5_alarm_out" sources="mixport_bus5_alarm_out"/>
- <route type="mix" sink="bus6_notification_out" sources="mixport_bus6_notification_out"/>
- <route type="mix" sink="bus7_system_sound_out" sources="mixport_bus7_system_sound_out"/>
+ <route type="mix" sink="bus6_notification_out"
+ sources="mixport_bus6_notification_out"/>
+ <route type="mix" sink="bus7_system_sound_out"
+ sources="mixport_bus7_system_sound_out"/>
<route type="mix" sink="bus100_audio_zone_1" sources="mixport_bus100_audio_zone_1"/>
<route type="mix" sink="bus200_audio_zone_2" sources="mixport_bus200_audio_zone_2"/>
- <route type="mix" sink="primary input" sources="Built-In Mic,Built-In Back Mic,Echo-Reference Mic"/>
+ <route type="mix" sink="primary input"
+ sources="Built-In Mic,Built-In Back Mic,Echo-Reference Mic"/>
<route type="mix" sink="mixport_tuner0" sources="FM Tuner"/>
<route type="mix" sink="mixport_input_bus_tone_zone_0" sources="Tone Generator 0"/>
<route type="mix" sink="mixport_input_bus_tone_zone_1" sources="Tone Generator 1"/>
diff --git a/emulator/audio/car_emulator_audio.mk b/emulator/audio/car_emulator_audio.mk
index 9ebb3b6..80e59f7 100644
--- a/emulator/audio/car_emulator_audio.mk
+++ b/emulator/audio/car_emulator_audio.mk
@@ -35,5 +35,6 @@ PRODUCT_COPY_FILES += \
frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
device/generic/car/emulator/audio/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
device/generic/car/emulator/audio/car_audio_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/car_audio_configuration.xml \
+ frameworks/av/media/libeffects/data/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
DEVICE_PACKAGE_OVERLAYS += device/generic/car/emulator/audio/overlay
diff --git a/emulator/audio/driver/Android.bp b/emulator/audio/driver/Android.bp
index 945c628..8b9f53e 100644
--- a/emulator/audio/driver/Android.bp
+++ b/emulator/audio/driver/Android.bp
@@ -24,13 +24,31 @@ package {
default_applicable_licenses: ["device_generic_car_license"],
}
+soong_config_module_type {
+ name: "audio_extn_cc_defaults",
+ module_type: "cc_defaults",
+ config_namespace: "audio_extn_config",
+ bool_variables: ["isHFPEnabled"],
+ properties: ["srcs", "cflags"],
+}
+
+audio_extn_cc_defaults {
+ name: "audio_extn_hfp",
+ soong_config_variables: {
+ isHFPEnabled: {
+ cflags: ["-DHFP_ENABLED"],
+ srcs: ["audio_extn/hfp.c"],
+ },
+ },
+}
+
cc_library_shared {
vendor: true,
vintf_fragments: ["android.hardware.audio@6.0-impl.xml"],
name: "audio.primary.caremu",
relative_install_path: "hw",
-
+ defaults: ["audio_extn_hfp"],
srcs: [
"audio_hw.c",
"audio_vbuffer.c",
@@ -38,6 +56,7 @@ cc_library_shared {
],
include_dirs: ["external/tinyalsa/include"],
+ local_include_dirs: ["audio_extn"],
export_include_dirs: [
"include"
],
diff --git a/emulator/audio/driver/audio_extn/audio_extn.h b/emulator/audio/driver/audio_extn/audio_extn.h
new file mode 100644
index 0000000..13050c6
--- /dev/null
+++ b/emulator/audio/driver/audio_extn/audio_extn.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AUDIO_EXTN_H
+#define AUDIO_EXTN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "audio_hw.h"
+#include <cutils/str_parms.h>
+
+#ifndef HFP_ENABLED
+#define audio_extn_hfp_set_parameters(adev, parms) (0)
+#else
+int audio_extn_hfp_set_parameters(struct generic_audio_device *adev,
+ struct str_parms *parms);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUDIO_EXTN_H */
diff --git a/emulator/audio/driver/audio_extn/hfp.c b/emulator/audio/driver/audio_extn/hfp.c
new file mode 100644
index 0000000..fbe4000
--- /dev/null
+++ b/emulator/audio/driver/audio_extn/hfp.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifdef HFP_ENABLED
+
+#define LOG_TAG "audio_hw_hfp"
+#define LOG_NDDEBUG 0
+
+#include "audio_extn.h"
+#include <cutils/log.h>
+#include <cutils/str_parms.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#define AUDIO_PARAMETER_HFP_ENABLE "hfp_enable"
+#define AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE "hfp_set_sampling_rate"
+#define AUDIO_PARAMETER_HFP_VOLUME "hfp_volume"
+#define AUDIO_PARAMETER_HFP_VALUE_MAX 128
+
+static int hfp_set_enable(struct generic_audio_device *adev, bool enable) {
+ struct mixer_ctl *ctl;
+ ALOGD("%s: enter enable : %d", __func__, enable);
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_PARAMETER_HFP_ENABLE);
+ if (!ctl) {
+ ALOGE("%s: Could not get mixer ctl for - %s", __func__,
+ AUDIO_PARAMETER_HFP_ENABLE);
+ return -EINVAL;
+ }
+
+ if (mixer_ctl_set_value(ctl, 0, enable) < 0) {
+ ALOGE("%s: Couldn't set mixer ctrl for %s", __func__,
+ AUDIO_PARAMETER_HFP_ENABLE);
+ return -EINVAL;
+ }
+
+ adev->hfp_running = enable;
+ ALOGD("%s: exit: status success", __func__);
+ return 0;
+}
+
+static int hfp_set_sampling_rate(struct generic_audio_device *adev, int rate) {
+ struct mixer_ctl *ctl;
+ ALOGD("%s: enter rate = %d", __func__, rate);
+
+ ctl =
+ mixer_get_ctl_by_name(adev->mixer, AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE);
+ if (!ctl) {
+ ALOGE("%s: Could not get mixer ctl for - %s", __func__,
+ AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE);
+ return -EINVAL;
+ }
+
+ if (mixer_ctl_set_value(ctl, 0, rate) < 0) {
+ ALOGE("%s: Couldn't set mixer ctrl for %s", __func__,
+ AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE);
+ return -EINVAL;
+ }
+
+ ALOGD("%s: exit: status success", __func__);
+ return 0;
+}
+
+static int hfp_set_volume(struct generic_audio_device *adev, int vol) {
+ struct mixer_ctl *ctl;
+ ALOGD("%s: enter vol = %d", __func__, vol);
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_PARAMETER_HFP_VOLUME);
+ if (!ctl) {
+ ALOGE("%s: Could not get mixer ctl for - %s", __func__,
+ AUDIO_PARAMETER_HFP_VOLUME);
+ return -EINVAL;
+ }
+
+ if (mixer_ctl_set_value(ctl, 0, vol) < 0) {
+ ALOGE("%s: Couldn't set mixer ctrl for %s", __func__,
+ AUDIO_PARAMETER_HFP_VOLUME);
+ return -EINVAL;
+ }
+
+ ALOGD("%s: exit: status success", __func__);
+ return 0;
+}
+
+int audio_extn_hfp_set_parameters(struct generic_audio_device *adev,
+ struct str_parms *parms) {
+ int ret = 0, rate, vol;
+ char value[AUDIO_PARAMETER_HFP_VALUE_MAX] = {0};
+
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_HFP_ENABLE, value,
+ sizeof(value));
+ if (ret >= 0) {
+ if (!strncmp(value, "true", sizeof(value))) {
+ if (!adev->hfp_running)
+ ret = hfp_set_enable(adev, true);
+ else
+ ALOGW("%s: HFP is already active.", __func__);
+ } else {
+ if (adev->hfp_running)
+ ret = hfp_set_enable(adev, false);
+ else
+ ALOGW("%s: ignore STOP, HFP not active", __func__);
+ }
+
+ if (ret < 0)
+ goto exit;
+ }
+
+ memset(value, 0, sizeof(value));
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE, value,
+ sizeof(value));
+ if (ret >= 0) {
+ rate = strtol(value, NULL, 10);
+ ret = hfp_set_sampling_rate(adev, rate);
+ if (ret < 0)
+ goto exit;
+ }
+
+ memset(value, 0, sizeof(value));
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_HFP_VOLUME, value,
+ sizeof(value));
+ if (ret >= 0) {
+ vol = strtol(value, NULL, 10);
+ ret = hfp_set_volume(adev, vol);
+ }
+
+exit:
+ ALOGD("%s exit: status", __func__);
+ return ret;
+}
+#endif /*HFP_ENABLED*/
diff --git a/emulator/audio/driver/audio_hw.c b/emulator/audio/driver/audio_hw.c
index 36796c4..65cbb11 100644
--- a/emulator/audio/driver/audio_hw.c
+++ b/emulator/audio/driver/audio_hw.c
@@ -22,6 +22,7 @@
#define LOG_TAG "audio_hw_generic_caremu"
// #define LOG_NDEBUG 0
+#include "audio_extn.h"
#include "audio_hw.h"
#include "include/audio_hw_control.h"
@@ -87,6 +88,7 @@ static const char * const AUDIO_ZONE_KEYWORD = "_audio_zone_";
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
#define SIZE_OF_PARSE_BUFFER 32
+#define SIZE_OF_THREAD_NAME_BUFFER 16
static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state);
@@ -162,6 +164,11 @@ void set_device_address_is_muted(const char *device_address, bool is_muted){
pthread_mutex_unlock(&out->lock);
}
+static void set_shortened_thread_name(pthread_t thread, const char *name) {
+ char shortenedName[SIZE_OF_THREAD_NAME_BUFFER];
+ strncpy(shortenedName, name, SIZE_OF_THREAD_NAME_BUFFER);
+ pthread_setname_np(thread, shortenedName);
+}
static struct pcm_config pcm_config_out = {
.channels = 2,
@@ -505,6 +512,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, si
const size_t frame_size = audio_stream_out_frame_size(stream);
const size_t frames = bytes / frame_size;
+ set_shortened_thread_name(pthread_self(), __func__);
+
pthread_mutex_lock(&out->lock);
if (out->worker_standby) {
@@ -1002,6 +1011,8 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer, size_t byte
bool mic_mute = false;
size_t read_bytes = 0;
+ set_shortened_thread_name(pthread_self(), __func__);
+
adev_get_mic_mute(&adev->device, &mic_mute);
pthread_mutex_lock(&in->lock);
@@ -1183,34 +1194,35 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
out->worker_standby = true;
out->worker_exit = false;
pthread_create(&out->worker_thread, NULL, out_write_worker, out);
- }
-
- out->enabled_channels = BOTH_CHANNELS;
- // For targets where output streams are closed regularly, currently ducked/muted addresses
- // should be tracked so that the address of new streams can be checked to determine the
- // default state
- out->is_ducked = 0;
- out->is_muted = 0;
- if (address) {
- out->bus_address = calloc(strlen(address) + 1, sizeof(char));
- strncpy(out->bus_address, address, strlen(address));
- hashmapPut(adev->out_bus_stream_map, out->bus_address, out);
- /* TODO: read struct audio_gain from audio_policy_configuration */
- out->gain_stage = (struct audio_gain) {
- .min_value = -3200,
- .max_value = 600,
- .step_value = 100,
- };
- out->amplitude_ratio = 1.0;
- if (property_get_bool(PROP_KEY_SIMULATE_MULTI_ZONE_AUDIO, false)) {
- out->enabled_channels = strstr(out->bus_address, AUDIO_ZONE_KEYWORD)
- ? RIGHT_CHANNEL: LEFT_CHANNEL;
- ALOGD("%s Routing %s to %s channel", __func__,
- out->bus_address, out->enabled_channels == RIGHT_CHANNEL ? "Right" : "Left");
+ set_shortened_thread_name(out->worker_thread, address);
+
+ out->enabled_channels = BOTH_CHANNELS;
+ // For targets where output streams are closed regularly, currently ducked/muted addresses
+ // should be tracked so that the address of new streams can be checked to determine the
+ // default state
+ out->is_ducked = 0;
+ out->is_muted = 0;
+ if (address) {
+ out->bus_address = calloc(strlen(address) + 1, sizeof(char));
+ strncpy(out->bus_address, address, strlen(address));
+ hashmapPut(adev->out_bus_stream_map, out->bus_address, out);
+ /* TODO: read struct audio_gain from audio_policy_configuration */
+ out->gain_stage = (struct audio_gain) {
+ .min_value = -3200,
+ .max_value = 600,
+ .step_value = 100,
+ };
+ out->amplitude_ratio = 1.0;
+ if (property_get_bool(PROP_KEY_SIMULATE_MULTI_ZONE_AUDIO, false)) {
+ out->enabled_channels = strstr(out->bus_address, AUDIO_ZONE_KEYWORD)
+ ? RIGHT_CHANNEL: LEFT_CHANNEL;
+ ALOGD("%s Routing %s to %s channel", __func__,
+ out->bus_address, out->enabled_channels == RIGHT_CHANNEL ? "Right" : "Left");
+ }
}
+ *stream_out = &out->stream;
+ ALOGD("%s bus: %s", __func__, out->bus_address);
}
- *stream_out = &out->stream;
- ALOGD("%s bus: %s", __func__, out->bus_address);
error:
return ret;
@@ -1250,6 +1262,7 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
results = 0;
ALOGD("%s Changed play zone id to %d", __func__, adev->last_zone_selected_to_play);
}
+ results = audio_extn_hfp_set_parameters(adev, parms);
str_parms_destroy(parms);
pthread_mutex_unlock(&adev->lock);
return results;
@@ -1428,6 +1441,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
in->worker_standby = true;
in->worker_exit = false;
pthread_create(&in->worker_thread, NULL, in_read_worker, in);
+ set_shortened_thread_name(in->worker_thread, address ? address : "mic");
}
if (address) {
@@ -1665,6 +1679,8 @@ static int adev_open(const hw_module_t *module,
adev->last_zone_selected_to_play = DEFAULT_ZONE_TO_LEFT_SPEAKER;
+ adev->hfp_running = false;
+
device_handle = adev;
audio_device_ref_count++;
diff --git a/emulator/audio/driver/audio_hw.h b/emulator/audio/driver/audio_hw.h
index 1f9aa51..c243222 100644
--- a/emulator/audio/driver/audio_hw.h
+++ b/emulator/audio/driver/audio_hw.h
@@ -37,6 +37,7 @@ struct generic_audio_device {
int next_tone_frequency_to_assign; // Protected by this->lock
// Play on Speaker zone selection
int last_zone_selected_to_play; // Protected by this->lock
+ bool hfp_running;
};
static struct generic_audio_device *device_handle;
diff --git a/emulator/audio/driver/audio_vbuffer.c b/emulator/audio/driver/audio_vbuffer.c
index 79be545..8377f5c 100644
--- a/emulator/audio/driver/audio_vbuffer.c
+++ b/emulator/audio/driver/audio_vbuffer.c
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-#define LOG_TAG "audio_hw_generic"
+#define LOG_TAG "audio_hw_generic_caremu"
+// #define LOG_NDEBUG 0
#include <errno.h>
#include <stdlib.h>
diff --git a/emulator/audio/driver/ext_pcm.c b/emulator/audio/driver/ext_pcm.c
index df3e1f1..2b0e825 100644
--- a/emulator/audio/driver/ext_pcm.c
+++ b/emulator/audio/driver/ext_pcm.c
@@ -14,9 +14,11 @@
* limitations under the License.
*/
-#define LOG_TAG "audio_hw_generic"
+#define LOG_TAG "audio_hw_generic_caremu"
+// #define LOG_NDEBUG 0
#include <errno.h>
+#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -31,6 +33,8 @@ static struct ext_pcm *shared_ext_pcm = NULL;
// Sleep 10ms between each mixing, this interval value is arbitrary chosen
#define MIXER_INTERVAL_MS 10
+#define MS_TO_US 1000
+
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
@@ -70,7 +74,8 @@ static bool mixer_thread_mix(__unused void *key, void *value, void *context) {
}
static void *mixer_thread_loop(void *context) {
- ALOGD("%s: __enter__", __func__);
+ pthread_setname_np(pthread_self(), "car_mixer_loop");
+ ALOGD("%s: starting mixer loop", __func__);
struct ext_pcm *ext_pcm = (struct ext_pcm *)context;
do {
pthread_mutex_lock(&ext_pcm->mixer_lock);
@@ -79,14 +84,25 @@ static void *mixer_thread_loop(void *context) {
hashmapForEach(ext_pcm->mixer_pipeline_map, mixer_thread_mix,
&ext_pcm->mixer_pipeline);
if (ext_pcm->mixer_pipeline.position > 0) {
- pcm_write(ext_pcm->pcm, (void *)ext_pcm->mixer_pipeline.buffer,
+ int ret = pcm_write(ext_pcm->pcm, (void *)ext_pcm->mixer_pipeline.buffer,
ext_pcm->mixer_pipeline.position * sizeof(int16_t));
+ if (ret != 0) {
+ ALOGE("%s error[%d] writing data to pcm");
+ }
}
memset(&ext_pcm->mixer_pipeline, 0, sizeof(struct ext_mixer_pipeline));
pthread_cond_broadcast(&ext_pcm->mixer_wake);
pthread_mutex_unlock(&ext_pcm->mixer_lock);
- usleep(MIXER_INTERVAL_MS * 1000);
+ pthread_mutex_lock(&ext_pcm_init_lock);
+ bool keep_running = ext_pcm->run_mixer;
+ pthread_mutex_unlock(&ext_pcm_init_lock);
+ if (!keep_running) {
+ break;
+ }
+ usleep(MIXER_INTERVAL_MS * MS_TO_US);
} while (1);
+ ALOGD("%s: exiting mixer loop", __func__);
+ return NULL;
}
static int mixer_pipeline_write(struct ext_pcm *ext_pcm, const char *bus_address,
@@ -130,12 +146,10 @@ struct ext_pcm *ext_pcm_open(unsigned int card, unsigned int device,
pthread_create(&shared_ext_pcm->mixer_thread, (const pthread_attr_t *)NULL,
mixer_thread_loop, shared_ext_pcm);
shared_ext_pcm->mixer_pipeline_map = hashmapCreate(8, str_hash_fn, str_eq);
+ shared_ext_pcm->run_mixer = true;
}
- pthread_mutex_unlock(&ext_pcm_init_lock);
-
- pthread_mutex_lock(&shared_ext_pcm->lock);
shared_ext_pcm->ref_count += 1;
- pthread_mutex_unlock(&shared_ext_pcm->lock);
+ pthread_mutex_unlock(&ext_pcm_init_lock);
return shared_ext_pcm;
}
@@ -147,27 +161,37 @@ static bool mixer_free_pipeline(__unused void *key, void *value, void *context)
}
int ext_pcm_close(struct ext_pcm *ext_pcm) {
+ ALOGD("%s closing pcm", __func__);
if (ext_pcm == NULL || ext_pcm->pcm == NULL) {
return -EINVAL;
}
- pthread_mutex_lock(&ext_pcm->lock);
- ext_pcm->ref_count -= 1;
- pthread_mutex_unlock(&ext_pcm->lock);
-
pthread_mutex_lock(&ext_pcm_init_lock);
- if (ext_pcm->ref_count <= 0) {
+ int count = ext_pcm->ref_count -= 1;
+ if (count <= 0) {
+ ext_pcm->run_mixer = false;
+ // On pcm open new shared_ext_pcm will be created
+ shared_ext_pcm = NULL;
+ pthread_mutex_unlock(&ext_pcm_init_lock);
+ void* ret_val = NULL;
+ int ret = pthread_join(ext_pcm->mixer_thread, &ret_val);
+ if (ret != 0) {
+ ALOGE("%s error[%d] when joining thread",
+ __func__, ret);
+ // Try killing if timeout failed
+ pthread_kill(ext_pcm->mixer_thread, SIGINT);
+ }
+ pthread_mutex_lock(&ext_pcm_init_lock);
pthread_mutex_destroy(&ext_pcm->lock);
pcm_close(ext_pcm->pcm);
pthread_mutex_destroy(&ext_pcm->mixer_lock);
hashmapForEach(ext_pcm->mixer_pipeline_map, mixer_free_pipeline,
(void *)NULL);
hashmapFree(ext_pcm->mixer_pipeline_map);
- pthread_kill(ext_pcm->mixer_thread, SIGINT);
free(ext_pcm);
- shared_ext_pcm = NULL;
}
pthread_mutex_unlock(&ext_pcm_init_lock);
+ ALOGD("%s finished closing pcm", __func__);
return 0;
}
diff --git a/emulator/audio/driver/ext_pcm.h b/emulator/audio/driver/ext_pcm.h
index c038b86..562b874 100644
--- a/emulator/audio/driver/ext_pcm.h
+++ b/emulator/audio/driver/ext_pcm.h
@@ -34,6 +34,7 @@ struct ext_pcm {
struct pcm *pcm;
pthread_mutex_t lock;
pthread_cond_t mixer_wake;
+ bool run_mixer;
unsigned int ref_count;
pthread_mutex_t mixer_lock;
struct ext_mixer_pipeline mixer_pipeline;
diff --git a/emulator/audio/halservice/android.hardware.audio.service-caremu.rc b/emulator/audio/halservice/android.hardware.audio.service-caremu.rc
index 768425f..76ee350 100644
--- a/emulator/audio/halservice/android.hardware.audio.service-caremu.rc
+++ b/emulator/audio/halservice/android.hardware.audio.service-caremu.rc
@@ -7,4 +7,3 @@ service vendor.audio-hal /vendor/bin/hw/android.hardware.audio.service-caremu
capabilities BLOCK_SUSPEND
ioprio rt 4
task_profiles ProcessCapacityHigh HighPerformance
- onrestart restart audioserver
diff --git a/emulator/audio/halservice/service.cpp b/emulator/audio/halservice/service.cpp
index aafff4d..581e9af 100644
--- a/emulator/audio/halservice/service.cpp
+++ b/emulator/audio/halservice/service.cpp
@@ -47,6 +47,7 @@ using android::hardware::registerPassthroughServiceImplementation;
int main(int /* argc */, char* /* argv */ []) {
// Setup HIDL Audio HAL
+ LOG(INFO) << "AudioControl start audio HAL.";
configureRpcThreadpool(16, false /*callerWillJoin*/);
android::status_t status;
status = registerPassthroughServiceImplementation<IDevicesFactory>();
@@ -55,14 +56,17 @@ int main(int /* argc */, char* /* argv */ []) {
LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering audio effects service: %d", status);
// Setup AudioControl HAL
- ABinderProcess_setThreadPoolMaxThreadCount(0);
+ ABinderProcess_setThreadPoolMaxThreadCount(16);
std::shared_ptr<AudioControl> audioControl = ::ndk::SharedRefBase::make<AudioControl>();
const std::string instance = std::string() + AudioControl::descriptor + "/default";
- binder_status_t aidlStatus =
- AServiceManager_addService(audioControl->asBinder().get(), instance.c_str());
+ binder_status_t aidlStatus = AServiceManager_addService(audioControl->asBinder().get(),
+ instance.c_str());
CHECK(aidlStatus == STATUS_OK);
+ LOG(INFO) << "AudioControl status: status " << aidlStatus;
+
ABinderProcess_joinThreadPool();
+ LOG(ERROR) << "ABinderProcess_joinThreadPool should never get here ";
return EXIT_FAILURE; // should not reach
}
diff --git a/emulator/usbpt/BoardConfig.mk b/emulator/usbpt/BoardConfig.mk
new file mode 100644
index 0000000..ea43a0b
--- /dev/null
+++ b/emulator/usbpt/BoardConfig.mk
@@ -0,0 +1,16 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+include device/generic/car/emulator/usbpt/bluetooth/BoardConfig.mk
diff --git a/emulator/usbpt/bluetooth/BoardConfig.mk b/emulator/usbpt/bluetooth/BoardConfig.mk
new file mode 100644
index 0000000..3c37ad4
--- /dev/null
+++ b/emulator/usbpt/bluetooth/BoardConfig.mk
@@ -0,0 +1,18 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+BOARD_HAVE_BLUETOOTH := true
+
+include device/generic/car/emulator/usbpt/bluetooth/btusb/BoardConfig.mk
diff --git a/emulator/bluetooth/btlinux-service.mk b/emulator/usbpt/bluetooth/bluetooth.mk
index ab427d2..935097f 100644
--- a/emulator/bluetooth/btlinux-service.mk
+++ b/emulator/usbpt/bluetooth/bluetooth.mk
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2021 The Android Open Source Project
+# Copyright (C) 2019 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,14 +19,14 @@
PRODUCT_PACKAGES += \
android.hardware.bluetooth@1.1-service.btlinux \
-# Allow sepolicies to be excluded in GSI targets.
-ifeq ($(DO_NOT_INCLUDE_BT_SEPOLICY),)
-BOARD_SEPOLICY_DIRS += \
- device/generic/car/emulator/bluetooth/sepolicy
-endif
-
PRODUCT_COPY_FILES += \
- device/generic/car/emulator/bluetooth/vendor.qemu.preferred.bt.service.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/vendor.qemu.preferred.bt.service.rc \
+ device/generic/car/emulator/usbpt/bluetooth/vendor.qemu.preferred.bt.service.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/vendor.qemu.preferred.bt.service.rc \
+ device/generic/car/emulator/usbpt/bluetooth/modules.blocklist:$(TARGET_COPY_OUT_VENDOR_RAMDISK)/lib/modules/modules.blocklist \
PRODUCT_SYSTEM_PROPERTIES += \
persist.bluetooth.enablenewavrcp=false \
+
+# USB Passthru
+PRODUCT_PACKAGES += usb_modeswitch
+
+$(call inherit-product, device/generic/car/emulator/usbpt/bluetooth/btusb/btusb.mk)
diff --git a/emulator/usbpt/bluetooth/btusb/BoardConfig.mk b/emulator/usbpt/bluetooth/btusb/BoardConfig.mk
new file mode 100644
index 0000000..7011ee7
--- /dev/null
+++ b/emulator/usbpt/bluetooth/btusb/BoardConfig.mk
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR := device/generic/car/emulator/usbpt/bluetooth/btusb/hal
+
+TARGET_KERNEL_USE ?= 5.10
+
+ifeq ($(TARGET_ARCH),x86_64)
+BOARD_VENDOR_KERNEL_MODULES += kernel/prebuilts/common-modules/virtual-device/$(TARGET_KERNEL_USE)/x86-64/btusb.ko
+else ifeq ($(TARGET_ARCH),arm64)
+BOARD_VENDOR_KERNEL_MODULES += kernel/prebuilts/common-modules/virtual-device/$(TARGET_KERNEL_USE)/arm64/btusb.ko
+endif
diff --git a/emulator/usbpt/bluetooth/btusb/btusb.mk b/emulator/usbpt/bluetooth/btusb/btusb.mk
new file mode 100644
index 0000000..6e21465
--- /dev/null
+++ b/emulator/usbpt/bluetooth/btusb/btusb.mk
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Allow sepolicies to be excluded in GSI targets.
+ifeq ($(DO_NOT_INCLUDE_BT_SEPOLICY),)
+BOARD_SEPOLICY_DIRS += \
+ device/generic/car/emulator/usbpt/bluetooth/btusb/sepolicy
+endif
+
+# USB Passthru
+PRODUCT_PACKAGES += rtl8821c_fw.bin.car \
+ rtl8821c_config.bin.car
+
+PRODUCT_COPY_FILES += \
+ device/generic/car/emulator/usbpt/bluetooth/btusb/init.btusb.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.btusb.rc \
diff --git a/emulator/bluetooth/hal/bdroid_buildcfg.h b/emulator/usbpt/bluetooth/btusb/hal/bdroid_buildcfg.h
index 132b683..132b683 100644
--- a/emulator/bluetooth/hal/bdroid_buildcfg.h
+++ b/emulator/usbpt/bluetooth/btusb/hal/bdroid_buildcfg.h
diff --git a/emulator/usbpt/bluetooth/btusb/init.btusb.rc b/emulator/usbpt/bluetooth/btusb/init.btusb.rc
new file mode 100644
index 0000000..4603f83
--- /dev/null
+++ b/emulator/usbpt/bluetooth/btusb/init.btusb.rc
@@ -0,0 +1,5 @@
+on early-init
+ write /sys/module/firmware_class/parameters/path /vendor/firmware/
+
+on boot
+ exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d /vendor/lib/modules btusb.ko
diff --git a/emulator/usbpt/bluetooth/btusb/rtl_bt/Android.bp b/emulator/usbpt/bluetooth/btusb/rtl_bt/Android.bp
new file mode 100644
index 0000000..ade064e
--- /dev/null
+++ b/emulator/usbpt/bluetooth/btusb/rtl_bt/Android.bp
@@ -0,0 +1,24 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "device_generic_car_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["device_generic_car_license"],
+}
+
+prebuilt_firmware {
+ name: "rtl8821c_fw.bin.car",
+ src: "rtl8821c_fw.bin",
+ sub_dir: "rtl_bt",
+ filename_from_src: true,
+ proprietary: true,
+}
+
+prebuilt_firmware {
+ name: "rtl8821c_config.bin.car",
+ src: "rtl8821c_config.bin",
+ sub_dir: "rtl_bt",
+ filename_from_src: true,
+ proprietary: true,
+}
diff --git a/emulator/usbpt/bluetooth/btusb/rtl_bt/rtl8821c_config.bin b/emulator/usbpt/bluetooth/btusb/rtl_bt/rtl8821c_config.bin
new file mode 100755
index 0000000..76f62b8
--- /dev/null
+++ b/emulator/usbpt/bluetooth/btusb/rtl_bt/rtl8821c_config.bin
Binary files differ
diff --git a/emulator/usbpt/bluetooth/btusb/rtl_bt/rtl8821c_fw.bin b/emulator/usbpt/bluetooth/btusb/rtl_bt/rtl8821c_fw.bin
new file mode 100644
index 0000000..ad31c94
--- /dev/null
+++ b/emulator/usbpt/bluetooth/btusb/rtl_bt/rtl8821c_fw.bin
Binary files differ
diff --git a/emulator/usbpt/bluetooth/btusb/sepolicy/bluetooth.te b/emulator/usbpt/bluetooth/btusb/sepolicy/bluetooth.te
new file mode 100644
index 0000000..dacbe8f
--- /dev/null
+++ b/emulator/usbpt/bluetooth/btusb/sepolicy/bluetooth.te
@@ -0,0 +1,2 @@
+allow kernel vendor_fw_file:file {open read};
+allow kernel vendor_fw_file:dir search;
diff --git a/emulator/bluetooth/sepolicy/domain.te b/emulator/usbpt/bluetooth/btusb/sepolicy/domain.te
index 448f1c3..448f1c3 100644
--- a/emulator/bluetooth/sepolicy/domain.te
+++ b/emulator/usbpt/bluetooth/btusb/sepolicy/domain.te
diff --git a/emulator/usbpt/bluetooth/btusb/sepolicy/file.te b/emulator/usbpt/bluetooth/btusb/sepolicy/file.te
new file mode 100644
index 0000000..bfde7a6
--- /dev/null
+++ b/emulator/usbpt/bluetooth/btusb/sepolicy/file.te
@@ -0,0 +1 @@
+type vendor_fw_file, vendor_file_type, file_type;
diff --git a/emulator/usbpt/bluetooth/btusb/sepolicy/file_contexts b/emulator/usbpt/bluetooth/btusb/sepolicy/file_contexts
new file mode 100644
index 0000000..a4c28ba
--- /dev/null
+++ b/emulator/usbpt/bluetooth/btusb/sepolicy/file_contexts
@@ -0,0 +1,2 @@
+# Vendor Firmwares
+/(vendor|system/vendor)/firmware(/.*)? u:object_r:vendor_fw_file:s0
diff --git a/emulator/bluetooth/sepolicy/property_contexts b/emulator/usbpt/bluetooth/btusb/sepolicy/property_contexts
index 224ca7f..224ca7f 100644
--- a/emulator/bluetooth/sepolicy/property_contexts
+++ b/emulator/usbpt/bluetooth/btusb/sepolicy/property_contexts
diff --git a/emulator/usbpt/bluetooth/modules.blocklist b/emulator/usbpt/bluetooth/modules.blocklist
new file mode 100644
index 0000000..5816cd8
--- /dev/null
+++ b/emulator/usbpt/bluetooth/modules.blocklist
@@ -0,0 +1,2 @@
+# List of sub-device specific modules to not load automatically
+blocklist btusb.ko
diff --git a/emulator/usb_modeswitch/Android.bp b/emulator/usbpt/bluetooth/usb_modeswitch/Android.bp
index 8858908..8858908 100644
--- a/emulator/usb_modeswitch/Android.bp
+++ b/emulator/usbpt/bluetooth/usb_modeswitch/Android.bp
diff --git a/emulator/usb_modeswitch/LICENSE b/emulator/usbpt/bluetooth/usb_modeswitch/LICENSE
index 1f963da..1f963da 100644
--- a/emulator/usb_modeswitch/LICENSE
+++ b/emulator/usbpt/bluetooth/usb_modeswitch/LICENSE
diff --git a/emulator/usb_modeswitch/usb_modeswitch.c b/emulator/usbpt/bluetooth/usb_modeswitch/usb_modeswitch.c
index 3b7c48b..3b7c48b 100644
--- a/emulator/usb_modeswitch/usb_modeswitch.c
+++ b/emulator/usbpt/bluetooth/usb_modeswitch/usb_modeswitch.c
diff --git a/emulator/usb_modeswitch/usb_modeswitch.h b/emulator/usbpt/bluetooth/usb_modeswitch/usb_modeswitch.h
index f407f95..f407f95 100644
--- a/emulator/usb_modeswitch/usb_modeswitch.h
+++ b/emulator/usbpt/bluetooth/usb_modeswitch/usb_modeswitch.h
diff --git a/emulator/bluetooth/vendor.qemu.preferred.bt.service.rc b/emulator/usbpt/bluetooth/vendor.qemu.preferred.bt.service.rc
index acd158b..acd158b 100644
--- a/emulator/bluetooth/vendor.qemu.preferred.bt.service.rc
+++ b/emulator/usbpt/bluetooth/vendor.qemu.preferred.bt.service.rc
diff --git a/emulator/btusb-passthrough/btusb.mk b/emulator/usbpt/car_usbpt.mk
index 8fc898d..d6dc800 100644
--- a/emulator/btusb-passthrough/btusb.mk
+++ b/emulator/usbpt/car_usbpt.mk
@@ -13,10 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# Enable Bluetooth passthrough support
-$(call inherit-product, device/generic/car/emulator/bluetooth/btlinux-service.mk)
-
-PRODUCT_PACKAGES += usb_modeswitch \
+$(call inherit-product, device/generic/car/emulator/usbpt/bluetooth/bluetooth.mk)
+$(call inherit-product, device/generic/car/emulator/usbpt/usbip-service/usbip-service.mk)
+# Required for USB passthrough
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.usb.host.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.usb.host.xml
diff --git a/emulator/usbpt/usbip-service/Android.bp b/emulator/usbpt/usbip-service/Android.bp
new file mode 100644
index 0000000..9ad8446
--- /dev/null
+++ b/emulator/usbpt/usbip-service/Android.bp
@@ -0,0 +1,63 @@
+package {
+ default_applicable_licenses: ["external_usbip-service_license"],
+}
+
+license {
+ name: "external_usbip-service_license",
+ visibility: [":__subpackages__"],
+ license_kinds: ["SPDX-license-identifier-GPL-2.0"],
+ license_text: ["COPYING"],
+}
+
+cc_defaults {
+ name: "usbip_defaults",
+ host_supported: true,
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ shared_libs: [
+ "liblog",
+ "libutils",
+ "libcutils",
+ "libbase",
+ "libc++",
+ ],
+ product_specific: true,
+ stl: "none",
+}
+
+cc_binary {
+ name: "usbip_service",
+ init_rc: ["usbip-service.rc"],
+ defaults: ["usbip_defaults"],
+ srcs: [
+ "UsbIpService.cpp"
+ ],
+ static_libs: [
+ "usbip_utils",
+ ],
+}
+
+cc_library {
+ name: "usbip_utils",
+ defaults: ["usbip_defaults"],
+ srcs: [
+ "UsbIpUtils.cpp"
+ ],
+ export_include_dirs: ["./"],
+}
+
+cc_test {
+ name: "usbip_test",
+ defaults: ["usbip_defaults"],
+ srcs: ["UsbIpTest.cpp"],
+ test_suites: ["general-tests"],
+
+ test_options: {
+ unit_test: false,
+ },
+ shared_libs: [
+ "usbip_utils",
+ ],
+}
diff --git a/emulator/usbpt/usbip-service/COPYING b/emulator/usbpt/usbip-service/COPYING
new file mode 100644
index 0000000..c5611e4
--- /dev/null
+++ b/emulator/usbpt/usbip-service/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/emulator/usbpt/usbip-service/README.md b/emulator/usbpt/usbip-service/README.md
new file mode 100644
index 0000000..693e86d
--- /dev/null
+++ b/emulator/usbpt/usbip-service/README.md
@@ -0,0 +1,4 @@
+Implements a very basic version of usbip.
+
+GPLv2 license is maintained in this directory since it implements interfaces
+provided by the usbip library.
diff --git a/emulator/usbpt/usbip-service/TEST_MAPPING b/emulator/usbpt/usbip-service/TEST_MAPPING
new file mode 100644
index 0000000..c977d11
--- /dev/null
+++ b/emulator/usbpt/usbip-service/TEST_MAPPING
@@ -0,0 +1,8 @@
+{
+ "presubmit": [
+ {
+ "name": "usbpip_test",
+ "host": true
+ }
+ ]
+}
diff --git a/emulator/usbpt/usbip-service/UsbIpService.cpp b/emulator/usbpt/usbip-service/UsbIpService.cpp
new file mode 100644
index 0000000..26d2f3d
--- /dev/null
+++ b/emulator/usbpt/usbip-service/UsbIpService.cpp
@@ -0,0 +1,55 @@
+#include <arpa/inet.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <log/log.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "UsbIpUtils.h"
+
+int main(int argc, char *argv[]) {
+ if (argc != 4) {
+ ALOGE("usage: 'usbip_service <ip_addr> <port> <dev_id>'\n");
+ return -1;
+ }
+ ALOGD("IP: %s\nPort: %s\nDevId: %s\n", argv[1], argv[2], argv[3]);
+
+ usbip_conn_info info;
+ if (!get_usbip_connection(argv[1], argv[2], argv[3], &info)) {
+ ALOGE("Couldn't retrieve socket connection\n");
+ return -1;
+ }
+
+ // Get free port.
+ FILE *file = fopen("/sys/devices/platform/vhci_hcd.0/status", "r");
+ if (file == NULL) {
+ ALOGE("Couldn't open sysfs status file: %s\n", strerror(errno));
+ close(info.sock_fd);
+ return -1;
+ }
+ int port_num = get_free_vhci_port(file, info.speed);
+
+ // Pass socket to the kernel driver.
+ int fd =
+ openat(AT_FDCWD, "/sys/devices/platform/vhci_hcd.0/attach", O_WRONLY);
+ if (fd == -1) {
+ ALOGE("Couldn't open sysfs attach file: %s\n", strerror(errno));
+ close(info.sock_fd);
+ return -1;
+ }
+ if (dprintf(fd, "%d %d %d %d", port_num, info.sock_fd, info.dev_id,
+ info.speed) < 0) {
+ ALOGE("Failed to attach socket to VHCI.\n");
+ close(info.sock_fd);
+ close(fd);
+ return -1;
+ }
+
+ close(info.sock_fd);
+ close(fd);
+ return 0;
+}
diff --git a/emulator/usbpt/usbip-service/UsbIpTest.cpp b/emulator/usbpt/usbip-service/UsbIpTest.cpp
new file mode 100644
index 0000000..97ef09c
--- /dev/null
+++ b/emulator/usbpt/usbip-service/UsbIpTest.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <gtest/gtest.h>
+
+#include <cstdio>
+#include <string>
+
+#include "UsbIpUtils.h"
+
+/* No virtual USB devices are attached. */
+static const std::string EMPTY_STATUS =
+ "hub port sta spd dev sockfd local_busid\n"
+ "hs 0000 004 000 00000000 000000 0-0\n"
+ "hs 0001 004 000 00000000 000000 0-0\n"
+ "hs 0002 004 000 00000000 000000 0-0\n"
+ "hs 0003 004 000 00000000 000000 0-0\n"
+ "ss 0004 004 000 00000000 000000 0-0\n"
+ "ss 0005 004 000 00000000 000000 0-0\n"
+ "ss 0006 004 000 00000000 000000 0-0\n"
+ "ss 0007 004 000 00000000 000000 0-0";
+
+/* A single high speed an super speed device are attached. */
+static const std::string PORTS_ALLOCATED =
+ "hub port sta spd dev sockfd local_busid\n"
+ "hs 0000 006 003 00010003 000003 4-1\n"
+ "hs 0001 004 000 00000000 000000 0-0\n"
+ "hs 0002 004 000 00000000 000000 0-0\n"
+ "hs 0003 004 000 00000000 000000 0-0\n"
+ "ss 0004 006 004 00010004 000004 5-1\n"
+ "ss 0005 004 000 00000000 000000 0-0\n"
+ "ss 0006 004 000 00000000 000000 0-0\n"
+ "ss 0007 004 000 00000000 000000 0-0";
+
+/* All USB device ports are allocated. */
+static const std::string NONE_AVAILABLE =
+ "hub port sta spd dev sockfd local_busid\n"
+ "hs 0000 006 003 00010001 000003 4-1\n"
+ "hs 0001 006 003 00010002 000004 4-2\n"
+ "hs 0002 006 003 00010003 000005 4-3\n"
+ "hs 0003 006 003 00010004 000006 4-4\n"
+ "ss 0004 006 004 00010005 000007 5-1\n"
+ "ss 0005 006 004 00010006 000008 5-2\n"
+ "ss 0006 006 004 00010007 000009 5-3\n"
+ "ss 0007 006 004 00010008 000010 5-4";
+
+/*
+ * Returns a file pointer associated with a std::string.
+ * NOTE: User should call fclose on the pointer when done.
+ */
+static FILE *get_fp_from_string(const std::string &test_input) {
+ return fmemopen((void *)test_input.c_str(), test_input.size(), "r");
+}
+
+TEST(UsbIpTest, ReturnsFirstHighSpeedPort) {
+ FILE *file = get_fp_from_string(EMPTY_STATUS);
+ ASSERT_EQ(get_free_vhci_port(file, USBIP_SPEED_HIGH), 0);
+ fclose(file);
+}
+
+TEST(UsbIpTest, ReturnsFirstSuperSpeedPort) {
+ FILE *file = get_fp_from_string(EMPTY_STATUS);
+ ASSERT_EQ(get_free_vhci_port(file, USBIP_SPEED_SUPER), 4);
+ fclose(file);
+}
+
+TEST(UsbIpTest, ReturnsFirstFreeHighSpeedPort) {
+ FILE *file = get_fp_from_string(PORTS_ALLOCATED);
+ ASSERT_EQ(get_free_vhci_port(file, USBIP_SPEED_HIGH), 1);
+ fclose(file);
+}
+
+TEST(UsbIpTest, ReturnsFirstFreeSuperSpeedPort) {
+ FILE *file = get_fp_from_string(PORTS_ALLOCATED);
+ ASSERT_EQ(get_free_vhci_port(file, USBIP_SPEED_SUPER), 5);
+ fclose(file);
+}
+
+TEST(UsbIpTest, AllHighSpeedPortsAllocatted) {
+ FILE *file = get_fp_from_string(NONE_AVAILABLE);
+ ASSERT_EQ(get_free_vhci_port(file, USBIP_SPEED_HIGH), -1);
+ fclose(file);
+}
+
+TEST(UsbIpTest, AllSuperSpeedPortsAllocated) {
+ FILE *file = get_fp_from_string(NONE_AVAILABLE);
+ ASSERT_EQ(get_free_vhci_port(file, USBIP_SPEED_SUPER), -1);
+ fclose(file);
+}
diff --git a/emulator/usbpt/usbip-service/UsbIpUtils.cpp b/emulator/usbpt/usbip-service/UsbIpUtils.cpp
new file mode 100644
index 0000000..ce449f7
--- /dev/null
+++ b/emulator/usbpt/usbip-service/UsbIpUtils.cpp
@@ -0,0 +1,178 @@
+#include "UsbIpUtils.h"
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <log/log.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+constexpr uint16_t kIpVersion = 0x0111;
+
+constexpr uint16_t kOpRequest = 0x8003;
+constexpr uint16_t kOpResponse = 0x0003;
+
+// Fields associated with all USBIP packets.
+typedef struct op_req_common {
+ uint16_t ip_version;
+ uint16_t command_code;
+ uint32_t status;
+} op_req_common;
+
+typedef struct op_req_import {
+ op_req_common common;
+ uint32_t busid[8];
+} op_req_import;
+
+typedef struct op_rep_import {
+ op_req_common common;
+} op_rep_import;
+
+// Metadata fields only valid for successful status flag.
+typedef struct op_rep_import_metadata {
+ uint32_t path[64];
+ uint32_t bus_id[8];
+ uint32_t bus_num;
+ uint32_t dev_num;
+ uint32_t speed;
+ uint16_t id_vendor;
+ uint16_t id_product;
+ uint16_t bcd_device;
+ uint8_t device_class;
+ uint8_t device_subclass;
+ uint8_t device_protocol;
+ uint8_t configuration_value;
+ uint8_t num_configurations;
+ uint8_t num_interfaces;
+} op_rep_import_success;
+
+bool get_usbip_connection(const char *server, const char *port,
+ const char *dev_id, usbip_conn_info *info) {
+ struct sockaddr_in address;
+
+ // Setup socket to the server.
+ if ((info->sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == 0) {
+ ALOGE("Opening socket failed: %s\n", strerror(errno));
+ return false;
+ }
+
+ int flags = 1;
+ if (setsockopt(info->sock_fd, SOL_SOCKET, SO_KEEPALIVE, &flags,
+ sizeof(flags)) == -1) {
+ ALOGE("Failed to enable keep alive: %s\n", strerror(errno));
+ close(info->sock_fd);
+ return false;
+ }
+ if (setsockopt(info->sock_fd, SOL_TCP, TCP_NODELAY, &flags,
+ sizeof(flags)) == -1) {
+ ALOGE("Failed to enable no delay: %s\n", strerror(errno));
+ close(info->sock_fd);
+ return false;
+ }
+
+ address.sin_family = AF_INET;
+ if (inet_aton(server, &address.sin_addr) == 0) {
+ ALOGE("Failure to convert ip address %s\n", server);
+ close(info->sock_fd);
+ return false;
+ }
+
+ errno = 0;
+ char *error;
+ address.sin_port = strtol(port, &error, 10);
+ if (address.sin_port == 0) {
+ ALOGE("Port is invalid %s\n", port);
+ close(info->sock_fd);
+ return false;
+ }
+ address.sin_port = htons(address.sin_port);
+ if (connect(info->sock_fd, (struct sockaddr *)&address, sizeof(address)) ==
+ -1) {
+ ALOGE("Connection failed: %s\n", strerror(errno));
+ close(info->sock_fd);
+ return false;
+ }
+
+ // Fill in op request
+ op_req_import op_req;
+ op_req.common.ip_version = htons(kIpVersion);
+ op_req.common.command_code = htons(kOpRequest);
+ op_req.common.status = 0x0000;
+ strncpy((char *)op_req.busid, dev_id, sizeof(op_req.busid));
+
+ if (send(info->sock_fd, &op_req, sizeof(op_req), 0) == -1) {
+ ALOGE("Error sending op_req: %s\n", strerror(errno));
+ close(info->sock_fd);
+ return false;
+ }
+
+ // Read in op response.
+ op_rep_import op_rep;
+ if (recv(info->sock_fd, &op_rep, sizeof(op_rep), MSG_WAITALL) == -1) {
+ ALOGE("Error receiving op_rep: %s\n", strerror(errno));
+ close(info->sock_fd);
+ return false;
+ }
+
+ if (op_rep.common.status != 0) {
+ ALOGE("op_rep status is invalid.\n");
+ close(info->sock_fd);
+ return false;
+ }
+
+ uint16_t command = ntohs(op_rep.common.command_code);
+ if (command != kOpResponse) {
+ ALOGE("Invalid command expected: %d received: %d", command, kOpResponse);
+ close(info->sock_fd);
+ return false;
+ }
+
+ op_rep_import_success data;
+ if (recv(info->sock_fd, &data, sizeof(data), MSG_WAITALL) == -1) {
+ ALOGE("Error receiving op_rep_data: %s\n", strerror(errno));
+ close(info->sock_fd);
+ return false;
+ }
+
+ int temp_bus_num = ntohl(data.bus_num);
+ int temp_dev_num = ntohl(data.dev_num);
+ info->speed = ntohl(data.speed);
+ info->dev_id = (temp_bus_num << 16) | temp_dev_num;
+ return true;
+}
+
+int get_free_vhci_port(FILE *file, int speed) {
+ // Throw away the header line.
+ char *buf = NULL;
+ size_t length = 0;
+ if (getline(&buf, &length, file) == -1) {
+ ALOGE("Couldn't get the header line: %s\n", strerror(errno));
+ free(buf);
+ return -1;
+ }
+ free(buf);
+
+ char busid[32];
+ char hub[3];
+ int port = 0;
+ int status = 0;
+ int spd = 0;
+ int dev = 0;
+ int sockfd = 0;
+ const char *expected_hub = (speed == USBIP_SPEED_SUPER) ? "ss" : "hs";
+
+ // Scan status lines for a free USB port.
+ while (fscanf(file, "%2s %d %d %d %x %u %31s\n", hub, &port, &status, &spd,
+ &dev, &sockfd, busid) != EOF) {
+ if (strcmp(expected_hub, hub) == 0 && status == USBIP_VDEV_NULL) {
+ return port;
+ }
+ }
+
+ return -1;
+}
diff --git a/emulator/usbpt/usbip-service/UsbIpUtils.h b/emulator/usbpt/usbip-service/UsbIpUtils.h
new file mode 100644
index 0000000..c410ba0
--- /dev/null
+++ b/emulator/usbpt/usbip-service/UsbIpUtils.h
@@ -0,0 +1,25 @@
+#include <stdio.h>
+
+// Speed constants
+inline constexpr int USBIP_SPEED_HIGH = 3;
+inline constexpr int USBIP_SPEED_SUPER = 4;
+
+// Status Constants
+inline constexpr int USBIP_VDEV_NULL = 4;
+
+// Connection information
+typedef struct usbip_conn_info {
+ int sock_fd;
+ int speed;
+ int dev_id;
+} usbip_conn_info;
+
+/*
+ * Connects to server and retrieves required info for connection.
+ * NOTE: User must close the sock_fd when they are done with it.
+ */
+bool get_usbip_connection(const char *server, const char *port,
+ const char *dev_id, usbip_conn_info *info);
+
+/* Returns free port number from vhci, -1 on failure. */
+int get_free_vhci_port(FILE *file, int speed);
diff --git a/emulator/usbpt/usbip-service/sepolicy/file_contexts b/emulator/usbpt/usbip-service/sepolicy/file_contexts
new file mode 100644
index 0000000..47fe583
--- /dev/null
+++ b/emulator/usbpt/usbip-service/sepolicy/file_contexts
@@ -0,0 +1,4 @@
+/product/bin/usbip_service u:object_r:usbip_service_exec:s0
+/sys/devices/platform/vhci_hcd.0/status u:object_r:sysfs_usbip:s0
+/sys/devices/platform/vhci_hcd.0/attach u:object_r:sysfs_usbip:s0
+
diff --git a/emulator/usbpt/usbip-service/sepolicy/usbip_service.te b/emulator/usbpt/usbip-service/sepolicy/usbip_service.te
new file mode 100644
index 0000000..b885493
--- /dev/null
+++ b/emulator/usbpt/usbip-service/sepolicy/usbip_service.te
@@ -0,0 +1,16 @@
+type usbip_service, domain;
+type sysfs_usbip, sysfs_type, fs_type;
+type usbip_service_exec, exec_type, system_file_type, file_type;
+
+net_domain(usbip_service);
+
+allow usbip_service netd:tcp_socket { read write };
+
+allow kernel su:tcp_socket { read write };
+allow kernel shell:tcp_socket { read write };
+
+allow init sysfs_usbip:file setattr;
+
+allow shell sysfs_usbip:dir { r_dir_perms };
+allow shell sysfs_usbip:file { rw_file_perms };
+allow shell usbip_service_exec:file { execute execute_no_trans getattr map open read };
diff --git a/emulator/usbpt/usbip-service/usbip-service.mk b/emulator/usbpt/usbip-service/usbip-service.mk
new file mode 100644
index 0000000..46b2ef7
--- /dev/null
+++ b/emulator/usbpt/usbip-service/usbip-service.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2021 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+PRODUCT_PACKAGES += usbip_service
+BOARD_SEPOLICY_DIRS += device/generic/car/emulator/usbpt/usbip-service/sepolicy
+
diff --git a/emulator/usbpt/usbip-service/usbip-service.rc b/emulator/usbpt/usbip-service/usbip-service.rc
new file mode 100644
index 0000000..7172bb7
--- /dev/null
+++ b/emulator/usbpt/usbip-service/usbip-service.rc
@@ -0,0 +1,2 @@
+on boot
+ chmod 222 /sys/bus/platform/devices/vhci_hcd.0/attach
diff --git a/emulator_car_x86_64/BoardConfig.mk b/emulator_car_x86_64/BoardConfig.mk
index 999f93b..1d99680 100644
--- a/emulator_car_x86_64/BoardConfig.mk
+++ b/emulator_car_x86_64/BoardConfig.mk
@@ -15,11 +15,10 @@
# Use generic_x86_64 BoardConfig as base
include build/make/target/board/emulator_x86_64/BoardConfig.mk
+include device/generic/car/emulator/usbpt/BoardConfig.mk
# Override BOARD_SUPER_PARTITION_SIZE to inclease the mounted system partition.
BOARD_SUPER_PARTITION_SIZE := 5856296960
BOARD_EMULATOR_DYNAMIC_PARTITIONS_SIZE = 3489660928
-BOARD_HAVE_BLUETOOTH := true
-BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR := device/generic/car/emulator/bluetooth/hal
diff --git a/gsi_car_base.mk b/gsi_car_base.mk
index 9769d53..b1fa936 100644
--- a/gsi_car_base.mk
+++ b/gsi_car_base.mk
@@ -44,6 +44,7 @@ PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
system/bin/carpowerpolicyd \
system/bin/carwatchdogd \
system/bin/com.android.car.procfsinspector \
+ system/bin/curl \
system/bin/vehicle_binding_util \
system/etc/apns-conf.xml \
system/etc/init/android.automotive.evs.manager@1.1.rc \