summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2021-08-14 06:31:09 +0000
committerXin Li <delphij@google.com>2021-08-14 06:31:09 +0000
commit52dac511bbbaced40b3b125b285152ed0969e5e3 (patch)
tree7df0119bdb77169dd46a2c636a70ad20d4be1972
parent74705aedbffb8a8ee1c0adb124da86b1d499630b (diff)
parentb91e40133039b060c0acee9cdd04376de22c4716 (diff)
downloadcar-52dac511bbbaced40b3b125b285152ed0969e5e3.tar.gz
Merge sc-dev-plus-aosp-without-vendor@7634622
Merged-In: I4d1a97735cd6466db1819a082257dfa70ff58505 Change-Id: I8f9cee29ff3746e2108842d021ee9f2a5114124e
-rw-r--r--AndroidProducts.mk6
-rw-r--r--common/car.mk14
-rw-r--r--common/car_core_hardware.xml7
-rw-r--r--common/fstab.ranchu.car9
-rw-r--r--common/overlay/frameworks/base/core/res/res/values/config.xml3
-rw-r--r--common/overlay/frameworks/base/core/res/res/values/vendor_policy_exempt_apps.xml (renamed from emulator/rotary/overlay/packages/apps/Car/RotaryController/res/values/strings.xml)17
-rw-r--r--common/preinstalled-packages-product-car-emulator.xml99
-rw-r--r--common/sepolicy/file_contexts2
-rw-r--r--common/sepolicy/hal_audio_caremu.te13
-rw-r--r--common/sepolicy/hal_vehicle_default.te3
-rw-r--r--common/sepolicy/system_server.te2
-rw-r--r--emulator/aosp_car_emulator.mk22
-rw-r--r--emulator/audio/audio_policy_configuration.xml27
-rw-r--r--emulator/audio/car_audio_configuration.xml20
-rw-r--r--emulator/audio/car_emulator_audio.mk2
-rw-r--r--emulator/audio/driver/Android.bp4
-rw-r--r--emulator/audio/driver/audio_hw.c242
-rw-r--r--emulator/audio/driver/audio_hw.h5
-rw-r--r--emulator/audio/driver/ext_pcm.c25
-rw-r--r--emulator/audio/driver/ext_pcm.h1
-rw-r--r--emulator/audio/driver/include/audio_hw_control.h49
-rw-r--r--emulator/audio/halservice/Android.bp89
-rw-r--r--emulator/audio/halservice/AudioControl.cpp290
-rw-r--r--emulator/audio/halservice/AudioControl.h65
-rw-r--r--emulator/audio/halservice/PowerPolicyClient.cpp70
-rw-r--r--emulator/audio/halservice/PowerPolicyClient.h53
-rw-r--r--emulator/audio/halservice/android.hardware.audio.service-caremu.rc10
-rw-r--r--emulator/audio/halservice/audiocontrol-caremu.xml6
-rw-r--r--emulator/audio/halservice/service.cpp73
-rw-r--r--emulator/audio/overlay/packages/services/Car/service/res/values/config.xml5
-rw-r--r--emulator/cluster/display_settings.xml8
-rw-r--r--emulator/cluster/osdouble_overlay/packages/services/Car/service/res/values/config.xml70
-rw-r--r--emulator/cluster/overlay/packages/services/Car/service/res/values/config.xml44
-rw-r--r--emulator/rotary/car_rotary.mk3
-rw-r--r--gsi_car_arm64.mk22
-rw-r--r--gsi_car_base.mk160
-rw-r--r--gsi_car_x86_64.mk22
-rw-r--r--setup/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml23
-rw-r--r--setup/overlay/packages/services/Car/service/res/values/config.xml30
39 files changed, 1393 insertions, 222 deletions
diff --git a/AndroidProducts.mk b/AndroidProducts.mk
index ff095c2..13eeea7 100644
--- a/AndroidProducts.mk
+++ b/AndroidProducts.mk
@@ -20,6 +20,9 @@ PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/aosp_car_x86.mk \
$(LOCAL_DIR)/aosp_car_x86_64.mk \
$(LOCAL_DIR)/car_x86_64.mk \
+ $(LOCAL_DIR)/gsi_car_arm64.mk \
+ $(LOCAL_DIR)/gsi_car_x86_64.mk \
+
COMMON_LUNCH_CHOICES := \
aosp_car_arm-userdebug \
@@ -27,5 +30,8 @@ COMMON_LUNCH_CHOICES := \
aosp_car_x86-userdebug \
aosp_car_x86_64-userdebug \
car_x86_64-userdebug \
+ gsi_car_arm64-userdebug \
+ gsi_car_x86_64-userdebug \
+
EMULATOR_VENDOR_NO_SOUND_TRIGGER := false
diff --git a/common/car.mk b/common/car.mk
index 1a98679..05bec5a 100644
--- a/common/car.mk
+++ b/common/car.mk
@@ -18,8 +18,7 @@
# TODO: Add broadcastradio@.2.0 back once it's stable b/145694104
PRODUCT_PACKAGES += \
android.hardware.automotive.vehicle@2.0-service \
- android.hardware.automotive.audiocontrol@2.0-service \
- android.frameworks.automotive.display@1.0-service \
+ android.hardware.audio.service-caremu
# Emulator configuration
PRODUCT_COPY_FILES += \
@@ -46,10 +45,6 @@ PRODUCT_COPY_FILES += \
device/generic/car/common/android.hardware.disable.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.fingerprint.xml \
device/generic/car/common/android.hardware.disable.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.wifi.direct.xml \
-# Overwrite goldfish fstab.ranchu to turn off adoptable_storage
-PRODUCT_COPY_FILES += \
- device/generic/car/common/fstab.ranchu.car:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.ranchu
-
# Enable landscape
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.screen.landscape.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.screen.landscape.xml
@@ -83,12 +78,6 @@ PRODUCT_COPY_FILES += \
PRODUCT_COPY_FILES += \
device/generic/car/common/preinstalled-packages-product-car-emulator.xml:$(TARGET_COPY_OUT_PRODUCT)/etc/sysconfig/preinstalled-packages-product-car-emulator.xml
-# Multi-user properties
-PRODUCT_SYSTEM_DEFAULT_PROPERTIES := \
- android.car.number_pre_created_users=1 \
- android.car.number_pre_created_guests=1 \
- android.car.user_hal_enabled=true
-
# Additional selinux policy
BOARD_SEPOLICY_DIRS += device/generic/car/common/sepolicy
@@ -99,5 +88,4 @@ ifneq (,$(filter aosp_car_x86_64 aosp_car_arm64,$(TARGET_PRODUCT)))
$(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_release.mk)
endif
-$(call inherit-product, packages/services/Car/evs/sepolicy/evs.mk)
$(call inherit-product, packages/services/Car/car_product/build/car.mk)
diff --git a/common/car_core_hardware.xml b/common/car_core_hardware.xml
index e027149..41b84c6 100644
--- a/common/car_core_hardware.xml
+++ b/common/car_core_hardware.xml
@@ -44,11 +44,16 @@
<feature name="android.software.connectionservice" />
<feature name="android.software.voice_recognizers" notLowRam="true" />
<feature name="android.software.home_screen" />
+ <feature name="android.software.companion_device_setup" />
<feature name="android.software.cant_save_state" />
- <feature name="android.software.input_methods" />
<feature name="android.software.midi" />
<feature name="android.software.secure_lock_screen" />
+ <!-- Feature to support device admins -->
+ <!-- TODO(b/178412797): not fully supported yet, CTS tests are still
+ failing. -->
+ <feature name="android.software.device_admin" />
+
<!-- devices with GPS must include android.hardware.location.gps.xml -->
<!-- devices with an autofocus camera and/or flash must include either
android.hardware.camera.autofocus.xml or
diff --git a/common/fstab.ranchu.car b/common/fstab.ranchu.car
deleted file mode 100644
index 1ff0331..0000000
--- a/common/fstab.ranchu.car
+++ /dev/null
@@ -1,9 +0,0 @@
-# Android fstab file.
-# This is a copy of device/generic/goldfish/fstab.ranchu, but removing encryptable=userdata to turn off adoptable_storage
-#<dev> <mnt_point> <type> <mnt_flags options> <fs_mgr_flags>
-system /system ext4 ro,barrier=1 wait,logical,avb=vbmeta,first_stage_mount
-vendor /vendor ext4 ro,barrier=1 wait,logical,first_stage_mount
-/dev/block/vdc /data ext4 noatime,nosuid,nodev,nomblk_io_submit,errors=panic wait,check,quota,fileencryption=aes-256-xts:aes-256-cts,reservedsize=128M
-/dev/block/pci/pci0000:00/0000:00:06.0/by-name/metadata /metadata ext4 noatime,nosuid,nodev wait,formattable,first_stage_mount
-/devices/*/block/vdf auto auto defaults voldmanaged=sdcard:auto
-dev/block/zram0 none swap defaults zramsize=75%
diff --git a/common/overlay/frameworks/base/core/res/res/values/config.xml b/common/overlay/frameworks/base/core/res/res/values/config.xml
index 6933a49..b6a7eb9 100644
--- a/common/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/common/overlay/frameworks/base/core/res/res/values/config.xml
@@ -25,4 +25,7 @@
<!-- AAOS doesn't support fingerprint and face -->
<string-array name="config_biometric_sensors" translatable="false" >
</string-array>
+ <string-array translatable="false" name="config_ethernet_interfaces">
+ <item>eth0;11,12,14;;</item>
+ </string-array>
</resources>
diff --git a/emulator/rotary/overlay/packages/apps/Car/RotaryController/res/values/strings.xml b/common/overlay/frameworks/base/core/res/res/values/vendor_policy_exempt_apps.xml
index 751c980..93f80ac 100644
--- a/emulator/rotary/overlay/packages/apps/Car/RotaryController/res/values/strings.xml
+++ b/common/overlay/frameworks/base/core/res/res/values/vendor_policy_exempt_apps.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2020 The Android Open Source Project
+ ~ Copyright (C) 2021 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.
@@ -15,6 +15,17 @@
~ limitations under the License.
-->
<resources>
- <!-- Component name of rotary IME. Empty if none. Overlaid to use demo rotary IME. -->
- <string name="rotary_input_method" translatable="false">com.android.car.rotaryime/.RotaryIme</string>
+ <!--
+ A collection of apps that are critical for the device and hence will never be disabled by
+ device policies or APIs.
+ -->
+ <string-array translatable="false" name="vendor_policy_exempt_apps">
+ <!-- This is just an example; on real products this list would
+ contain apps like:
+ - Rear-view camera
+ - Driver assistance
+ - Vehicle warnings
+ -->
+ <item>com.google.android.car.netdbug</item>
+ </string-array>
</resources>
diff --git a/common/preinstalled-packages-product-car-emulator.xml b/common/preinstalled-packages-product-car-emulator.xml
index 30a06bc..a22118f 100644
--- a/common/preinstalled-packages-product-car-emulator.xml
+++ b/common/preinstalled-packages-product-car-emulator.xml
@@ -86,6 +86,11 @@
<install-in user-type="SYSTEM" />
</install-in-user-type>
+ <!-- Required for RearViewCamera -->
+ <install-in-user-type package="com.google.android.car.rvc">
+ <install-in user-type="FULL" />
+ <install-in user-type="SYSTEM" />
+ </install-in-user-type>
<!--
Apps that do need to run on SYSTEM and evaluated by package owner.
Here the apps will have FULL only.
@@ -141,91 +146,6 @@
<install-in-user-type package="com.android.car.themeplayground">
<install-in user-type="FULL" />
</install-in-user-type>
- <!-- TODO(b/144915994) Remove these com.android.theme.* pacakges-->
- <install-in-user-type package="com.android.theme.color.black">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.color.cinnamon">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.color.green">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.color.ocean">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.color.orchid">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.color.purple">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.color.space">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.font.notoserifsource">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon.pebble">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon.roundedrect">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon.squircle">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon.taperedrect">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon.teardrop">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon.vessel">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.circular.android">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.circular.launcher">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.circular.settings">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.circular.systemui">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.circular.themepicker">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.filled.android">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.filled.launcher">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.filled.settings">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.filled.systemui">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.filled.themepicker">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.rounded.android">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.rounded.launcher">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.rounded.settings">
- <install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.rounded.systemui">
- <install-in user-type="FULL" />
- </install-in-user-type>
<install-in-user-type package="com.android.car.linkviewer">
<install-in user-type="FULL" />
</install-in-user-type>
@@ -259,15 +179,9 @@
<install-in-user-type package="com.android.sdksetup">
<install-in user-type="FULL" />
</install-in-user-type>
- <install-in-user-type package="com.android.internal.display.cutout.emulation.emu01">
- <install-in user-type="FULL" />
- </install-in-user-type>
<install-in-user-type package="com.android.cellbroadcastservice">
<install-in user-type="FULL" />
</install-in-user-type>
- <install-in-user-type package="com.android.theme.icon_pack.rounded.themepicker">
- <install-in user-type="FULL" />
- </install-in-user-type>
<install-in-user-type package="com.android.service.ims">
<install-in user-type="FULL" />
</install-in-user-type>
@@ -302,9 +216,6 @@
<install-in user-type="FULL" />
<install-in user-type="SYSTEM" />
</install-in-user-type>
- <install-in-user-type package="com.android.car.secondaryhome">
- <install-in user-type="FULL" />
- </install-in-user-type>
<install-in-user-type package="com.android.car.multidisplay">
<install-in user-type="FULL" />
</install-in-user-type>
diff --git a/common/sepolicy/file_contexts b/common/sepolicy/file_contexts
new file mode 100644
index 0000000..5737b92
--- /dev/null
+++ b/common/sepolicy/file_contexts
@@ -0,0 +1,2 @@
+# Audio HAL
+/vendor/bin/hw/android\.hardware\.audio\.service-caremu u:object_r:hal_audio_caremu_exec:s0
diff --git a/common/sepolicy/hal_audio_caremu.te b/common/sepolicy/hal_audio_caremu.te
new file mode 100644
index 0000000..5c0af23
--- /dev/null
+++ b/common/sepolicy/hal_audio_caremu.te
@@ -0,0 +1,13 @@
+type hal_audio_caremu, domain;
+
+hal_server_domain(hal_audio_caremu, hal_audio)
+hal_server_domain(hal_audio_caremu, hal_audiocontrol)
+
+type hal_audio_caremu_exec, exec_type, vendor_file_type, file_type;
+init_daemon_domain(hal_audio_caremu)
+
+carwatchdog_client_domain(hal_audio_caremu)
+binder_use(hal_audio_caremu)
+
+# Enable audiocontrol to listen to power policy daemon.
+carpowerpolicy_callback_domain(hal_audio_caremu)
diff --git a/common/sepolicy/hal_vehicle_default.te b/common/sepolicy/hal_vehicle_default.te
deleted file mode 100644
index c0a9698..0000000
--- a/common/sepolicy/hal_vehicle_default.te
+++ /dev/null
@@ -1,3 +0,0 @@
-# Configuration for register VHAL to car watchdog
-carwatchdog_client_domain(hal_vehicle_default)
-binder_use(hal_vehicle_default)
diff --git a/common/sepolicy/system_server.te b/common/sepolicy/system_server.te
index a9ce1b1..fd67577 100644
--- a/common/sepolicy/system_server.te
+++ b/common/sepolicy/system_server.te
@@ -1,2 +1,2 @@
# Allow system_server to kill vehicle HAL
-allow system_server hal_vehicle_server:process sigkill;
+allow system_server hal_vehicle_default:process { sigkill signal };
diff --git a/emulator/aosp_car_emulator.mk b/emulator/aosp_car_emulator.mk
index 1fe1b32..c0b0b59 100644
--- a/emulator/aosp_car_emulator.mk
+++ b/emulator/aosp_car_emulator.mk
@@ -13,16 +13,34 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# Enable Setup Wizard. This overrides the setting in emulator_vendor.mk
+PRODUCT_SYSTEM_EXT_PROPERTIES += \
+ ro.setupwizard.mode?=OPTIONAL
+
+ifeq (,$(ENABLE_REAR_VIEW_CAMERA_SAMPLE))
+ENABLE_REAR_VIEW_CAMERA_SAMPLE:=true
+endif
+
$(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)
+PRODUCT_COPY_FILES += \
+ frameworks/native/data/etc/android.hardware.usb.host.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.usb.host.xml
+
ifeq (true,$(BUILD_EMULATOR_CLUSTER_DISPLAY))
+PRODUCT_COPY_FILES += \
+ device/generic/car/emulator/cluster/display_settings.xml:system/etc/display_settings.xml
PRODUCT_PRODUCT_PROPERTIES += \
- hwservicemanager.external.displays=1,1080,600,120,0 \
+ hwservicemanager.external.displays=1,400,600,120,0 \
persist.service.bootanim.displays=8140900251843329
-endif
+ifeq (true,$(ENABLE_CLUSTER_OS_DOUBLE))
+DEVICE_PACKAGE_OVERLAYS += device/generic/car/emulator/cluster/osdouble_overlay
+else
+DEVICE_PACKAGE_OVERLAYS += device/generic/car/emulator/cluster/overlay
+endif # ENABLE_CLUSTER_OS_DOUBLE
+endif # BUILD_EMULATOR_CLUSTER_DISPLAY
# Define the host tools and libs that are parts of the SDK.
$(call inherit-product, sdk/build/product_sdk.mk)
diff --git a/emulator/audio/audio_policy_configuration.xml b/emulator/audio/audio_policy_configuration.xml
index ed0f4a6..4e61c76 100644
--- a/emulator/audio/audio_policy_configuration.xml
+++ b/emulator/audio/audio_policy_configuration.xml
@@ -78,56 +78,47 @@
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
- <mixPort name="mixport_bus1_navigation_out" role="source"
- flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ <mixPort name="mixport_bus1_navigation_out" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
- <mixPort name="mixport_bus2_voice_command_out" role="source"
- flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ <mixPort name="mixport_bus2_voice_command_out" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
- <mixPort name="mixport_bus3_call_ring_out" role="source"
- flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ <mixPort name="mixport_bus3_call_ring_out" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
- <mixPort name="mixport_bus4_call_out" role="source"
- flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ <mixPort name="mixport_bus4_call_out" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
- <mixPort name="mixport_bus5_alarm_out" role="source"
- flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ <mixPort name="mixport_bus5_alarm_out" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
- <mixPort name="mixport_bus6_notification_out" role="source"
- flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ <mixPort name="mixport_bus6_notification_out" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
- <mixPort name="mixport_bus7_system_sound_out" role="source"
- flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ <mixPort name="mixport_bus7_system_sound_out" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
- <mixPort name="mixport_bus100_audio_zone_1" role="source"
- flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ <mixPort name="mixport_bus100_audio_zone_1" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
- <mixPort name="mixport_bus200_audio_zone_2" role="source"
- flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ <mixPort name="mixport_bus200_audio_zone_2" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
diff --git a/emulator/audio/car_audio_configuration.xml b/emulator/audio/car_audio_configuration.xml
index d79ff33..5c0a880 100644
--- a/emulator/audio/car_audio_configuration.xml
+++ b/emulator/audio/car_audio_configuration.xml
@@ -28,20 +28,11 @@
<group>
<device address="bus0_media_out">
<context context="music"/>
- </device>
- <device address="bus3_call_ring_out">
- <context context="call_ring"/>
+ <context context="announcement"/>
</device>
<device address="bus6_notification_out">
<context context="notification"/>
</device>
- <device address="bus7_system_sound_out">
- <context context="system_sound"/>
- <context context="emergency"/>
- <context context="safety"/>
- <context context="vehicle_status"/>
- <context context="announcement"/>
- </device>
</group>
<group>
<device address="bus1_navigation_out">
@@ -55,11 +46,20 @@
<device address="bus4_call_out">
<context context="call"/>
</device>
+ <device address="bus3_call_ring_out">
+ <context context="call_ring"/>
+ </device>
</group>
<group>
<device address="bus5_alarm_out">
<context context="alarm"/>
</device>
+ <device address="bus7_system_sound_out">
+ <context context="system_sound"/>
+ <context context="emergency"/>
+ <context context="safety"/>
+ <context context="vehicle_status"/>
+ </device>
</group>
</volumeGroups>
</zone>
diff --git a/emulator/audio/car_emulator_audio.mk b/emulator/audio/car_emulator_audio.mk
index da5c60a..d2e3d09 100644
--- a/emulator/audio/car_emulator_audio.mk
+++ b/emulator/audio/car_emulator_audio.mk
@@ -15,7 +15,7 @@
PRODUCT_PACKAGES += \
audio.r_submix.default \
- android.hardware.audio.service \
+ android.hardware.audio.service-caremu \
android.hardware.audio.effect@6.0-impl:32
PRODUCT_PACKAGES += audio.primary.caremu
diff --git a/emulator/audio/driver/Android.bp b/emulator/audio/driver/Android.bp
index 8f1843f..945c628 100644
--- a/emulator/audio/driver/Android.bp
+++ b/emulator/audio/driver/Android.bp
@@ -38,7 +38,9 @@ cc_library_shared {
],
include_dirs: ["external/tinyalsa/include"],
-
+ export_include_dirs: [
+ "include"
+ ],
shared_libs: [
"libcutils",
"liblog",
diff --git a/emulator/audio/driver/audio_hw.c b/emulator/audio/driver/audio_hw.c
index bc27e90..3ced724 100644
--- a/emulator/audio/driver/audio_hw.c
+++ b/emulator/audio/driver/audio_hw.c
@@ -19,37 +19,45 @@
* Changes made to adding support of AUDIO_DEVICE_OUT_BUS
*/
-#define LOG_TAG "audio_hw_generic"
+#define LOG_TAG "audio_hw_generic_caremu"
+// #define LOG_NDEBUG 0
+
+#include "audio_hw.h"
+#include "include/audio_hw_control.h"
#include <assert.h>
+#include <cutils/hashmap.h>
+#include <cutils/properties.h>
+#include <cutils/str_parms.h>
+#include <dlfcn.h>
#include <errno.h>
+#include <fcntl.h>
+#include <hardware/hardware.h>
#include <inttypes.h>
+#include <log/log.h>
#include <math.h>
+#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/time.h>
-#include <dlfcn.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <log/log.h>
-#include <cutils/properties.h>
-#include <cutils/str_parms.h>
-
-#include <hardware/hardware.h>
#include <system/audio.h>
+#include <unistd.h>
-#include "audio_hw.h"
#include "ext_pcm.h"
#define PCM_CARD 0
#define PCM_DEVICE 0
-#define OUT_PERIOD_MS 15
-#define OUT_PERIOD_COUNT 4
+#define DEFAULT_OUT_PERIOD_MS 15
+#define DEFAULT_OUT_PERIOD_COUNT 4
+
+#define DEFAULT_IN_PERIOD_MS 15
+#define DEFAULT_IN_PERIOD_COUNT 4
-#define IN_PERIOD_MS 15
-#define IN_PERIOD_COUNT 4
+static const char* PROP_KEY_OUT_PERIOD_MS = "ro.vendor.caremu.audiohal.out_period_ms";
+static const char* PROP_KEY_OUT_PERIOD_COUNT = "ro.vendor.caremu.audiohal.out_period_count";
+static const char* PROP_KEY_IN_PERIOD_MS = "ro.vendor.caremu.audiohal.in_period_ms";
+static const char* PROP_KEY_IN_PERIOD_COUNT = "ro.vendor.caremu.audiohal.in_period_count";
#define PI 3.14159265
#define TWO_PI (2*PI)
@@ -61,6 +69,9 @@
// Max tone frequency to auto assign, don't want to generate too high of a pitch
#define MAX_TONE_FREQUENCY 500
+// -14dB to match the volume curve in PlaybackActivityMonitor
+#define DUCKING_MULTIPLIER 0.2
+
#define _bool_str(x) ((x)?"true":"false")
static const char * const PROP_KEY_SIMULATE_MULTI_ZONE_AUDIO = "ro.aae.simulateMultiZoneAudio";
@@ -73,15 +84,103 @@ static const char * const AAE_PARAMETER_KEY_FOR_SELECTED_ZONE = "com.android.car
static const char * const TONE_ADDRESS_KEYWORD = "_tone_";
static const char * const AUDIO_ZONE_KEYWORD = "_audio_zone_";
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+
+static bool is_audio_enabled = 1; // Protected by lock
+
#define SIZE_OF_PARSE_BUFFER 32
static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state);
+static int get_out_period_ms() {
+ static int out_period_ms = -1;
+ if (out_period_ms == -1) {
+ out_period_ms = property_get_int32(PROP_KEY_OUT_PERIOD_MS, DEFAULT_OUT_PERIOD_MS);
+ }
+ return out_period_ms;
+}
+
+static int get_out_period_count() {
+ static int out_period_count = -1;
+ if (out_period_count == -1) {
+ out_period_count = property_get_int32(PROP_KEY_OUT_PERIOD_COUNT, DEFAULT_OUT_PERIOD_COUNT);
+ }
+ return out_period_count;
+}
+
+static int get_in_period_ms() {
+ static int in_period_ms = -1;
+ if (in_period_ms == -1) {
+ in_period_ms = property_get_int32(PROP_KEY_IN_PERIOD_MS, DEFAULT_IN_PERIOD_MS);
+ }
+ return in_period_ms;
+}
+
+static int get_in_period_count() {
+ static int in_period_count = -1;
+ if (in_period_count == -1) {
+ in_period_count = property_get_int32(PROP_KEY_IN_PERIOD_COUNT, DEFAULT_IN_PERIOD_COUNT);
+ }
+ return in_period_count;
+}
+
+static struct generic_stream_out * get_audio_device(const char *address, const char *caller) {
+ pthread_mutex_lock(&lock);
+ if(device_handle == 0) {
+ ALOGE("%s no device handle available", caller);
+ pthread_mutex_unlock(&lock);
+ return NULL;
+ }
+
+ struct generic_stream_out *out = hashmapGet(device_handle->out_bus_stream_map, address);
+ pthread_mutex_unlock(&lock);
+
+ return out;
+}
+
+void set_device_address_is_ducked(const char *device_address, bool is_ducked) {
+ struct generic_stream_out *out = get_audio_device(device_address, __func__);
+
+ if (!out) {
+ ALOGW("%s no device found with address %s", __func__, device_address);
+ return;
+ }
+
+ pthread_mutex_lock(&out->lock);
+ out->is_ducked = is_ducked;
+ pthread_mutex_unlock(&out->lock);
+}
+
+void set_device_address_is_muted(const char *device_address, bool is_muted){
+ struct generic_stream_out *out = get_audio_device(device_address, __func__);
+
+ if (!out) {
+ ALOGW("%s no device found with address %s", __func__, device_address);
+ return;
+ }
+
+ pthread_mutex_lock(&out->lock);
+ out->is_muted = is_muted;
+ pthread_mutex_unlock(&out->lock);
+}
+
+void set_audio_enabled(bool is_enabled) {
+ pthread_mutex_lock(&lock);
+ is_audio_enabled = is_enabled;
+ pthread_mutex_unlock(&lock);
+}
+
+bool get_is_audio_enabled() {
+ pthread_mutex_lock(&lock);
+ bool is_enabled = is_audio_enabled;
+ pthread_mutex_unlock(&lock);
+ return is_enabled;
+}
+
static struct pcm_config pcm_config_out = {
.channels = 2,
.rate = 0,
.period_size = 0,
- .period_count = OUT_PERIOD_COUNT,
.format = PCM_FORMAT_S16_LE,
.start_threshold = 0,
};
@@ -106,13 +205,11 @@ static struct pcm_config pcm_config_in = {
.channels = 2,
.rate = 0,
.period_size = 0,
- .period_count = IN_PERIOD_COUNT,
.format = PCM_FORMAT_S16_LE,
.start_threshold = 0,
.stop_threshold = INT_MAX,
};
-static pthread_mutex_t adev_init_lock = PTHREAD_MUTEX_INITIALIZER;
static unsigned int audio_device_ref_count = 0;
static bool is_zone_selected_to_play(struct audio_hw_device *dev, int zone_id) {
@@ -160,6 +257,8 @@ static int out_set_format(struct audio_stream *stream, audio_format_t format) {
static int out_dump(const struct audio_stream *stream, int fd) {
struct generic_stream_out *out = (struct generic_stream_out *)stream;
+ bool is_enabled = get_is_audio_enabled();
+
pthread_mutex_lock(&out->lock);
dprintf(fd, "\tout_dump:\n"
"\t\taddress: %s\n"
@@ -170,6 +269,9 @@ static int out_dump(const struct audio_stream *stream, int fd) {
"\t\tdevice: %08x\n"
"\t\tamplitude ratio: %f\n"
"\t\tenabled channels: %d\n"
+ "\t\tis ducked: %s\n"
+ "\t\tis muted: %s\n"
+ "\t\tis audio enabled: %s\n"
"\t\taudio dev: %p\n\n",
out->bus_address,
out_get_sample_rate(stream),
@@ -179,6 +281,9 @@ static int out_dump(const struct audio_stream *stream, int fd) {
out->device,
out->amplitude_ratio,
out->enabled_channels,
+ _bool_str(out->is_ducked),
+ _bool_str(out->is_muted),
+ _bool_str(is_enabled),
out->dev);
pthread_mutex_unlock(&out->lock);
return 0;
@@ -328,6 +433,7 @@ static void *out_write_worker(void *args) {
}
}
int frames = audio_vbuffer_read(&out->buffer, buffer, buffer_frames);
+ pthread_cond_signal(&out->write_wake);
pthread_mutex_unlock(&out->lock);
if (is_zone_selected_to_play(out->dev, zone_id)) {
@@ -349,7 +455,7 @@ static void *out_write_worker(void *args) {
return NULL;
}
-// Call with in->lock held
+// Call with out->lock held
static void get_current_output_position(struct generic_stream_out *out,
uint64_t *position, struct timespec * timestamp) {
struct timespec curtime = { .tv_sec = 0, .tv_nsec = 0 };
@@ -398,6 +504,10 @@ static void out_apply_gain(struct generic_stream_out *out, const void *buffer, s
int16_buffer[i] = 0;
} else {
float multiplied = int16_buffer[i] * out->amplitude_ratio;
+ if (out->is_ducked) {
+ multiplied = multiplied * DUCKING_MULTIPLIER;
+ }
+
if (multiplied > INT16_MAX) int16_buffer[i] = INT16_MAX;
else if (multiplied < INT16_MIN) int16_buffer[i] = INT16_MIN;
else int16_buffer[i] = (int16_t)multiplied;
@@ -408,7 +518,10 @@ static void out_apply_gain(struct generic_stream_out *out, const void *buffer, s
static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, size_t bytes) {
struct generic_stream_out *out = (struct generic_stream_out *)stream;
ALOGV("%s: to device %s", __func__, out->bus_address);
- const size_t frames = bytes / audio_stream_out_frame_size(stream);
+ const size_t frame_size = audio_stream_out_frame_size(stream);
+ const size_t frames = bytes / frame_size;
+
+ bool is_enabled = get_is_audio_enabled();
pthread_mutex_lock(&out->lock);
@@ -420,8 +533,6 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, si
struct timespec current_time;
get_current_output_position(out, &current_position, &current_time);
- const uint64_t now_us = (current_time.tv_sec * 1000000000LL +
- current_time.tv_nsec) / 1000;
if (out->standby) {
out->standby = false;
out->underrun_time = current_time;
@@ -430,12 +541,38 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, si
}
size_t frames_written = frames;
- if (out->dev->master_mute) {
- ALOGV("%s: ignored due to master mute", __func__);
+
+ const int available_frames_in_buffer = audio_vbuffer_dead(&out->buffer);
+ const int frames_sleep =
+ available_frames_in_buffer > frames ? 0 : frames - available_frames_in_buffer;
+ const uint64_t sleep_time_us =
+ frames_sleep * 1000000LL / out_get_sample_rate(&stream->common);
+
+ if (sleep_time_us > 0) {
+ pthread_mutex_unlock(&out->lock);
+ usleep(sleep_time_us);
+ pthread_mutex_lock(&out->lock);
+ }
+
+ if (out->dev->master_mute || out->is_muted || !is_enabled) {
+ ALOGV("%s: ignored due to mute", __func__);
} else {
out_apply_gain(out, buffer, bytes);
- frames_written = audio_vbuffer_write(&out->buffer, buffer, frames);
- pthread_cond_signal(&out->worker_wake);
+ frames_written = 0;
+
+ bool write_incomplete = true;
+ do {
+ frames_written += audio_vbuffer_write(
+ &out->buffer,
+ (const char *)buffer + frames_written * frame_size,
+ frames - frames_written);
+ pthread_cond_signal(&out->worker_wake);
+ write_incomplete = frames_written < frames;
+ if (write_incomplete) {
+ // Wait for write worker to consume the buffer
+ pthread_cond_wait(&out->write_wake, &out->lock);
+ }
+ } while (write_incomplete);
}
/* Implementation just consumes bytes if we start getting backed up */
@@ -443,32 +580,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, si
out->frames_rendered += frames;
out->frames_total_buffered += frames;
- // We simulate the audio device blocking when it's write buffers become
- // full.
-
- // At the beginning or after an underrun, try to fill up the vbuffer.
- // This will be throttled by the PlaybackThread
- int frames_sleep = out->frames_total_buffered < out->buffer.frame_count ? 0 : frames;
-
- uint64_t sleep_time_us = frames_sleep * 1000000LL /
- out_get_sample_rate(&stream->common);
-
- // If the write calls are delayed, subtract time off of the sleep to
- // compensate
- uint64_t time_since_last_write_us = now_us - out->last_write_time_us;
- if (time_since_last_write_us < sleep_time_us) {
- sleep_time_us -= time_since_last_write_us;
- } else {
- sleep_time_us = 0;
- }
- out->last_write_time_us = now_us + sleep_time_us;
-
pthread_mutex_unlock(&out->lock);
- if (sleep_time_us > 0) {
- usleep(sleep_time_us);
- }
-
if (frames_written < frames) {
ALOGW("%s Hardware backing HAL too slow, could only write %zu of %zu frames",
__func__, frames_written, frames);
@@ -654,7 +767,7 @@ static size_t get_input_buffer_size(uint32_t sample_rate, audio_format_t format,
if (refine_input_parameters(&sample_rate, &format, &channel_mask) != 0)
return 0;
- size = sample_rate*IN_PERIOD_MS/1000;
+ size = sample_rate * get_in_period_ms() / 1000;
// Audioflinger expects audio buffers to be multiple of 16 frames
size = ((size + 15) / 16) * 16;
size *= sizeof(short) * channel_count;
@@ -1068,7 +1181,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
memcpy(&out->req_config, config, sizeof(struct audio_config));
memcpy(&out->pcm_config, &pcm_config_out, sizeof(struct pcm_config));
out->pcm_config.rate = config->sample_rate;
- out->pcm_config.period_size = out->pcm_config.rate*OUT_PERIOD_MS/1000;
+ out->pcm_config.period_size = out->pcm_config.rate * get_out_period_ms() / 1000;
out->standby = true;
out->underrun_position = 0;
@@ -1091,6 +1204,11 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
}
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));
@@ -1308,7 +1426,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
memcpy(&in->req_config, config, sizeof(struct audio_config));
memcpy(&in->pcm_config, &pcm_config_in, sizeof(struct pcm_config));
in->pcm_config.rate = config->sample_rate;
- in->pcm_config.period_size = in->pcm_config.rate*IN_PERIOD_MS/1000;
+ in->pcm_config.period_size = in->pcm_config.rate * get_in_period_ms() / 1000;
in->stereo_to_mono_buf = NULL;
in->stereo_to_mono_buf_size = 0;
@@ -1369,6 +1487,8 @@ static int adev_set_audio_port_config(struct audio_hw_device *dev,
int minDb = out->gain_stage.min_value / 100;
int maxDb = out->gain_stage.max_value / 100;
// curve: 10^((minDb + (maxDb - minDb) * gainIndex / totalSteps) / 20)
+ // 2x10, where 10 comes from the log 10 conversion from power ratios,
+ // which are the square (2) of amplitude
out->amplitude_ratio = pow(10,
(minDb + (maxDb - minDb) * (gainIndex / (float)totalSteps)) / 20);
pthread_mutex_unlock(&out->lock);
@@ -1423,7 +1543,7 @@ static int adev_close(hw_device_t *dev) {
if (!adev)
return 0;
- pthread_mutex_lock(&adev_init_lock);
+ pthread_mutex_lock(&lock);
if (audio_device_ref_count == 0) {
ALOGE("adev_close called when ref_count 0");
@@ -1441,11 +1561,13 @@ static int adev_close(hw_device_t *dev) {
if (adev->in_bus_tone_frequency_map) {
hashmapFree(adev->in_bus_tone_frequency_map);
}
+
+ device_handle = 0;
free(adev);
}
error:
- pthread_mutex_unlock(&adev_init_lock);
+ pthread_mutex_unlock(&lock);
return ret;
}
@@ -1477,7 +1599,7 @@ static int adev_open(const hw_module_t *module,
if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
return -EINVAL;
- pthread_mutex_lock(&adev_init_lock);
+ pthread_mutex_lock(&lock);
if (audio_device_ref_count != 0) {
*device = &adev->device.common;
audio_device_ref_count++;
@@ -1485,6 +1607,10 @@ static int adev_open(const hw_module_t *module,
ALOGV("%s: exit", __func__);
goto unlock;
}
+
+ pcm_config_in.period_count = get_in_period_count();
+ pcm_config_out.period_count = get_out_period_count();
+
adev = calloc(1, sizeof(struct generic_audio_device));
pthread_mutex_init(&adev->lock, (const pthread_mutexattr_t *) NULL);
@@ -1557,10 +1683,12 @@ static int adev_open(const hw_module_t *module,
adev->last_zone_selected_to_play = DEFAULT_ZONE_TO_LEFT_SPEAKER;
+ device_handle = adev;
+
audio_device_ref_count++;
unlock:
- pthread_mutex_unlock(&adev_init_lock);
+ pthread_mutex_unlock(&lock);
return 0;
}
diff --git a/emulator/audio/driver/audio_hw.h b/emulator/audio/driver/audio_hw.h
index d195a53..1f9aa51 100644
--- a/emulator/audio/driver/audio_hw.h
+++ b/emulator/audio/driver/audio_hw.h
@@ -39,6 +39,8 @@ struct generic_audio_device {
int last_zone_selected_to_play; // Protected by this->lock
};
+static struct generic_audio_device *device_handle;
+
enum output_channel_enable {
LEFT_CHANNEL = 1,
RIGHT_CHANNEL = 1 << 1,
@@ -57,6 +59,8 @@ struct generic_stream_out {
struct audio_gain gain_stage; // Constant after init
float amplitude_ratio; // Protected by this->lock
enum output_channel_enable enabled_channels; // Constant after init
+ bool is_ducked; // Protected by this->lock
+ bool is_muted; // Protected by this->lock
// Time & Position Keeping
bool standby; // Protected by this->lock
@@ -70,6 +74,7 @@ struct generic_stream_out {
// Worker
pthread_t worker_thread; // Constant after init
pthread_cond_t worker_wake; // Protected by this->lock
+ pthread_cond_t write_wake; // Protected by this->lock
bool worker_standby; // Protected by this->lock
bool worker_exit; // Protected by this->lock
};
diff --git a/emulator/audio/driver/ext_pcm.c b/emulator/audio/driver/ext_pcm.c
index b1519f5..df3e1f1 100644
--- a/emulator/audio/driver/ext_pcm.c
+++ b/emulator/audio/driver/ext_pcm.c
@@ -83,6 +83,7 @@ static void *mixer_thread_loop(void *context) {
ext_pcm->mixer_pipeline.position * sizeof(int16_t));
}
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);
} while (1);
@@ -97,13 +98,23 @@ static int mixer_pipeline_write(struct ext_pcm *ext_pcm, const char *bus_address
pipeline = calloc(1, sizeof(struct ext_mixer_pipeline));
hashmapPut(ext_pcm->mixer_pipeline_map, bus_address, pipeline);
}
- unsigned int byteCount = MIN(count,
- (MIXER_BUFFER_SIZE - pipeline->position) * sizeof(int16_t));
- unsigned int int16Count = byteCount / sizeof(int16_t);
- if (int16Count > 0) {
- memcpy(&pipeline->buffer[pipeline->position], data, byteCount);
- pipeline->position += int16Count;
- }
+ unsigned int byteWritten = 0;
+ bool write_incomplete = true;
+ do {
+ const unsigned int byteCount = MIN(count - byteWritten,
+ (MIXER_BUFFER_SIZE - pipeline->position) * sizeof(int16_t));
+ const unsigned int int16Count = byteCount / sizeof(int16_t);
+ if (int16Count > 0) {
+ memcpy(&pipeline->buffer[pipeline->position], (const char*)data + byteWritten, byteCount);
+ pipeline->position += int16Count;
+ }
+ byteWritten += byteCount;
+ write_incomplete = byteWritten < count;
+ if (write_incomplete) {
+ // wait for mixer thread to consume the pipeline buffer
+ pthread_cond_wait(&ext_pcm->mixer_wake, &ext_pcm->mixer_lock);
+ }
+ } while (write_incomplete);
pthread_mutex_unlock(&ext_pcm->mixer_lock);
return 0;
}
diff --git a/emulator/audio/driver/ext_pcm.h b/emulator/audio/driver/ext_pcm.h
index 0bc8df5..c038b86 100644
--- a/emulator/audio/driver/ext_pcm.h
+++ b/emulator/audio/driver/ext_pcm.h
@@ -33,6 +33,7 @@ struct ext_mixer_pipeline {
struct ext_pcm {
struct pcm *pcm;
pthread_mutex_t lock;
+ pthread_cond_t mixer_wake;
unsigned int ref_count;
pthread_mutex_t mixer_lock;
struct ext_mixer_pipeline mixer_pipeline;
diff --git a/emulator/audio/driver/include/audio_hw_control.h b/emulator/audio/driver/include/audio_hw_control.h
new file mode 100644
index 0000000..21d30d0
--- /dev/null
+++ b/emulator/audio/driver/include/audio_hw_control.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 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_CONTROL_UTILS
+#define AUDIO_CONTROL_UTILS
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+// Sets the device address specified to ducked state
+// device_address is the device address to set ducked
+// is_ducked is the new ducked state
+//
+// Note: The device address must be defined in
+// audio_policy_configuration.xml
+void set_device_address_is_ducked(const char *device_address, bool is_ducked);
+
+
+// Sets the device address specified to muted state
+// device_address is the device address to set muted
+// is_muted is the new mute state
+//
+// Note: The device address must be defined in
+// audio_policy_configuration.xml
+void set_device_address_is_muted(const char *device_address, bool is_muted);
+
+// Sets whether audio component is enabled or disabled.
+// Results in muting of all audio leaving the HAL if it is disabled
+void set_audio_enabled(bool is_enabled);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif // AUDIO_CONTROL_UTILS \ No newline at end of file
diff --git a/emulator/audio/halservice/Android.bp b/emulator/audio/halservice/Android.bp
new file mode 100644
index 0000000..01828af
--- /dev/null
+++ b/emulator/audio/halservice/Android.bp
@@ -0,0 +1,89 @@
+// Copyright (C) 2021 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.
+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"],
+}
+
+cc_binary {
+ name: "android.hardware.audio.service-caremu",
+
+ init_rc: ["android.hardware.audio.service-caremu.rc"],
+
+ relative_install_path: "hw",
+ vendor: true,
+ // Prefer 32 bit as the binary must always be installed at the same
+ // location for init to start it and the build system does not support
+ // having two binaries installable to the same location even if they are
+ // not installed in the same build.
+ compile_multilib: "prefer32",
+ srcs: [
+ "service.cpp",
+ "PowerPolicyClient.cpp",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ ],
+
+ shared_libs: [
+ "android.hardware.audio@6.0",
+ "android.hardware.audio.common@6.0",
+ "android.hardware.audio.effect@6.0",
+ "android.hardware.automotive.audiocontrol-V1-ndk_platform",
+ "android.frameworks.automotive.powerpolicy-V1-ndk_platform",
+ "audiocontrol-caremu",
+ "libbase",
+ "libbinder",
+ "libbinder_ndk",
+ "libhardware",
+ "libhidlbase",
+ "liblog",
+ "libpowerpolicyclient",
+ ],
+
+ header_libs: [
+ "libhardware_headers",
+ ],
+}
+
+cc_library {
+ name: "audiocontrol-caremu",
+ vendor: true,
+ vintf_fragments: ["audiocontrol-caremu.xml"],
+
+ shared_libs: [
+ "android.hardware.audio.common@7.0-enums",
+ "android.hardware.automotive.audiocontrol-V1-ndk_platform",
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "liblog",
+ "audio.primary.caremu",
+ ],
+
+ srcs: [
+ "AudioControl.cpp",
+ ],
+
+ include_dirs: [
+ "device/generic/car/emulator/audio/driver/include"
+ ],
+}
diff --git a/emulator/audio/halservice/AudioControl.cpp b/emulator/audio/halservice/AudioControl.cpp
new file mode 100644
index 0000000..87d77d8
--- /dev/null
+++ b/emulator/audio/halservice/AudioControl.cpp
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#define LOG_TAG "AudioControl"
+// #define LOG_NDEBUG 0
+
+#include "AudioControl.h"
+#include "audio_hw_control.h"
+
+#include <aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.h>
+#include <aidl/android/hardware/automotive/audiocontrol/DuckingInfo.h>
+#include <aidl/android/hardware/automotive/audiocontrol/IFocusListener.h>
+
+#include <android-base/logging.h>
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+
+#include <android_audio_policy_configuration_V7_0-enums.h>
+#include <private/android_filesystem_config.h>
+
+#include <stdio.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace audiocontrol {
+
+using ::android::base::EqualsIgnoreCase;
+using ::android::base::ParseInt;
+using ::std::shared_ptr;
+using ::std::string;
+
+namespace xsd {
+using namespace ::android::audio::policy::configuration::V7_0;
+}
+
+namespace {
+const float kLowerBound = -1.0f;
+const float kUpperBound = 1.0f;
+bool checkCallerHasWritePermissions(int fd) {
+ // Double check that's only called by root - it should be be blocked at debug() level,
+ // but it doesn't hurt to make sure...
+ if (AIBinder_getCallingUid() != AID_ROOT) {
+ dprintf(fd, "Must be root\n");
+ return false;
+ }
+ return true;
+}
+
+bool isValidValue(float value) {
+ return (value >= kLowerBound) && (value <= kUpperBound);
+}
+
+bool safelyParseInt(string s, int* out) {
+ if (!ParseInt(s, out)) {
+ return false;
+ }
+ return true;
+}
+} // namespace
+
+ndk::ScopedAStatus AudioControl::registerFocusListener(
+ const shared_ptr<IFocusListener>& in_listener) {
+
+ if (in_listener) {
+ std::atomic_store(&mFocusListener, in_listener);
+ } else {
+ LOG(ERROR) << "Unexpected nullptr for listener resulting in no-op.";
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::setBalanceTowardRight(float value) {
+ if (isValidValue(value)) {
+ // Just log in this default mock implementation
+ LOG(INFO) << "Balance set to " << value;
+ return ndk::ScopedAStatus::ok();
+ }
+
+ LOG(ERROR) << "Balance value out of range -1 to 1 at " << value;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::setFadeTowardFront(float value) {
+ if (isValidValue(value)) {
+ // Just log in this default mock implementation
+ LOG(INFO) << "Fader set to " << value;
+ return ndk::ScopedAStatus::ok();
+ }
+ LOG(ERROR) << "Fader value out of range -1 to 1 at " << value;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::onAudioFocusChange(const string& in_usage, int32_t in_zoneId,
+ AudioFocusChange in_focusChange) {
+ LOG(INFO) << "Focus changed: " << toString(in_focusChange).c_str() << " for usage "
+ << in_usage.c_str() << " in zone " << in_zoneId;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::onDevicesToDuckChange(
+ const std::vector<DuckingInfo>& in_duckingInfos) {
+ LOG(DEBUG) << "AudioControl::onDevicesToDuckChange";
+ for (const DuckingInfo& duckingInfo : in_duckingInfos) {
+ LOG(DEBUG) << "zone: " << duckingInfo.zoneId;
+ LOG(DEBUG) << "Devices to duck:";
+ for (const auto& addressToDuck : duckingInfo.deviceAddressesToDuck) {
+ LOG(DEBUG) << addressToDuck;
+ set_device_address_is_ducked(addressToDuck.c_str(), true);
+ }
+
+ LOG(DEBUG) << "Devices to unduck:";
+ for (const auto& addressToUnduck : duckingInfo.deviceAddressesToUnduck) {
+ LOG(DEBUG) << addressToUnduck;
+ set_device_address_is_ducked(addressToUnduck.c_str(), false);
+ }
+ LOG(DEBUG) << "Usages holding focus:";
+ for (const auto& usage : duckingInfo.usagesHoldingFocus) {
+ LOG(DEBUG) << usage;
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::onDevicesToMuteChange(
+ const std::vector<MutingInfo>& in_mutingInfos) {
+ LOG(DEBUG) << "AudioControl::onDevicesToMuteChange";
+ for (const MutingInfo& mutingInfo : in_mutingInfos) {
+ LOG(DEBUG) << "zone: " << mutingInfo.zoneId;
+ LOG(DEBUG) << "Devices to mute:";
+ for (const auto& addressToMute : mutingInfo.deviceAddressesToMute) {
+ LOG(DEBUG) << addressToMute;
+ set_device_address_is_muted(addressToMute.c_str(), true);
+ }
+ LOG(DEBUG) << "Devices to unmute:";
+ for (const auto& addressToUnmute : mutingInfo.deviceAddressesToUnmute) {
+ LOG(DEBUG) << addressToUnmute;
+ set_device_address_is_muted(addressToUnmute.c_str(), false);
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+binder_status_t AudioControl::dump(int fd, const char** args, uint32_t numArgs) {
+ if (numArgs == 0) {
+ return dumpsys(fd);
+ }
+
+ string option = string(args[0]);
+ if (EqualsIgnoreCase(option, "--help")) {
+ return cmdHelp(fd);
+ } else if (EqualsIgnoreCase(option, "--request")) {
+ return cmdRequestFocus(fd, args, numArgs);
+ } else if (EqualsIgnoreCase(option, "--abandon")) {
+ return cmdAbandonFocus(fd, args, numArgs);
+ } else {
+ dprintf(fd, "Invalid option: %s\n", option.c_str());
+ return STATUS_BAD_VALUE;
+ }
+}
+
+void AudioControl::setAudioEnabled(bool isEnabled) {
+ LOG(DEBUG) << "setAudioEnabled called with value: " << isEnabled;
+ set_audio_enabled(isEnabled);
+}
+
+binder_status_t AudioControl::dumpsys(int fd) {
+ dprintf(fd, "*%s*\n", LOG_TAG);
+ std::shared_ptr<IFocusListener> focusListener = std::atomic_load(&mFocusListener);
+ if (focusListener == nullptr) {
+ dprintf(fd, "No focus listener registered\n");
+ } else {
+ dprintf(fd, "Focus listener registered\n");
+ }
+ return STATUS_OK;
+}
+
+binder_status_t AudioControl::cmdHelp(int fd) const {
+ dprintf(fd, "Usage: \n\n");
+ dprintf(fd, "[no args]: dumps focus listener status\n");
+ dprintf(fd, "--help: shows this help\n");
+ dprintf(fd,
+ "--request <USAGE> <ZONE_ID> <FOCUS_GAIN>: requests audio focus for specified "
+ "usage (string), audio zone ID (int), and focus gain type (int)\n");
+ dprintf(fd,
+ "--abandon <USAGE> <ZONE_ID>: abandons audio focus for specified usage (string) and "
+ "audio zone ID (int)\n");
+ dprintf(fd, "See audio_policy_configuration.xsd for valid AudioUsage values.\n");
+ return STATUS_OK;
+}
+
+binder_status_t AudioControl::cmdRequestFocus(int fd, const char** args, uint32_t numArgs) {
+ if (!checkCallerHasWritePermissions(fd)) {
+ return STATUS_PERMISSION_DENIED;
+ }
+ if (numArgs != 4) {
+ dprintf(fd,
+ "Invalid number of arguments: please provide --request <USAGE> <ZONE_ID> "
+ "<FOCUS_GAIN>\n");
+ return STATUS_BAD_VALUE;
+ }
+
+ string usage = string(args[1]);
+ if (xsd::isUnknownAudioUsage(usage)) {
+ dprintf(fd,
+ "Unknown usage provided: %s. Please see audio_policy_configuration.xsd V7_0 "
+ "for supported values\n",
+ usage.c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ int zoneId;
+ if (!safelyParseInt(string(args[2]), &zoneId)) {
+ dprintf(fd, "Non-integer zoneId provided with request: %s\n", string(args[2]).c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ int focusGainValue;
+ if (!safelyParseInt(string(args[3]), &focusGainValue)) {
+ dprintf(fd, "Non-integer focusGain provided with request: %s\n", string(args[3]).c_str());
+ return STATUS_BAD_VALUE;
+ }
+ AudioFocusChange focusGain = AudioFocusChange(focusGainValue);
+
+ std::shared_ptr<IFocusListener> focusListener = std::atomic_load(&mFocusListener);
+ if (focusListener == nullptr) {
+ dprintf(fd, "Unable to request focus - no focus listener registered\n");
+ return STATUS_BAD_VALUE;
+ }
+
+ focusListener->requestAudioFocus(usage, zoneId, focusGain);
+ dprintf(fd, "Requested focus for usage %s, zoneId %d, and focusGain %d\n", usage.c_str(),
+ zoneId, focusGain);
+ return STATUS_OK;
+}
+
+binder_status_t AudioControl::cmdAbandonFocus(int fd, const char** args, uint32_t numArgs) {
+ if (!checkCallerHasWritePermissions(fd)) {
+ return STATUS_PERMISSION_DENIED;
+ }
+ if (numArgs != 3) {
+ dprintf(fd, "Invalid number of arguments: please provide --abandon <USAGE> <ZONE_ID>\n");
+ return STATUS_BAD_VALUE;
+ }
+
+ string usage = string(args[1]);
+ if (xsd::isUnknownAudioUsage(usage)) {
+ dprintf(fd,
+ "Unknown usage provided: %s. Please see audio_policy_configuration.xsd V7_0 "
+ "for supported values\n",
+ usage.c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ int zoneId;
+ if (!safelyParseInt(string(args[2]), &zoneId)) {
+ dprintf(fd, "Non-integer zoneId provided with abandon: %s\n", string(args[2]).c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ std::shared_ptr<IFocusListener> focusListener = std::atomic_load(&mFocusListener);
+ if (focusListener == nullptr) {
+ dprintf(fd, "Unable to abandon focus - no focus listener registered\n");
+ return STATUS_BAD_VALUE;
+ }
+
+ focusListener->abandonAudioFocus(usage, zoneId);
+ dprintf(fd, "Abandoned focus for usage %s and zoneId %d\n", usage.c_str(), zoneId);
+ return STATUS_OK;
+}
+
+} // namespace audiocontrol
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/emulator/audio/halservice/AudioControl.h b/emulator/audio/halservice/AudioControl.h
new file mode 100644
index 0000000..af11448
--- /dev/null
+++ b/emulator/audio/halservice/AudioControl.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 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 ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_AUDIOCONTROL_H
+#define ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_AUDIOCONTROL_H
+
+#include <aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.h>
+#include <aidl/android/hardware/automotive/audiocontrol/BnAudioControl.h>
+#include <aidl/android/hardware/automotive/audiocontrol/DuckingInfo.h>
+#include <aidl/android/hardware/automotive/audiocontrol/MutingInfo.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace audiocontrol {
+
+class AudioControl : public BnAudioControl {
+ public:
+ ndk::ScopedAStatus onAudioFocusChange(const std::string& in_usage, int32_t in_zoneId,
+ AudioFocusChange in_focusChange) override;
+ ndk::ScopedAStatus onDevicesToDuckChange(
+ const std::vector<DuckingInfo>& in_duckingInfos) override;
+ ndk::ScopedAStatus onDevicesToMuteChange(
+ const std::vector<MutingInfo>& in_mutingInfos) override;
+ ndk::ScopedAStatus registerFocusListener(
+ const std::shared_ptr<IFocusListener>& in_listener) override;
+ ndk::ScopedAStatus setBalanceTowardRight(float in_value) override;
+ ndk::ScopedAStatus setFadeTowardFront(float in_value) override;
+ binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+ void setAudioEnabled(bool isEnabled);
+
+ private:
+ // This focus listener will only be used by this HAL instance to communicate with
+ // a single instance of CarAudioService. As such, it doesn't have explicit serialization.
+ // If a different AudioControl implementation were to have multiple threads leveraging this
+ // listener, then it should also include mutexes or make the listener atomic.
+ std::shared_ptr<IFocusListener> mFocusListener;
+
+ binder_status_t cmdHelp(int fd) const;
+ binder_status_t cmdRequestFocus(int fd, const char** args, uint32_t numArgs);
+ binder_status_t cmdAbandonFocus(int fd, const char** args, uint32_t numArgs);
+ binder_status_t dumpsys(int fd);
+};
+
+} // namespace audiocontrol
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_AUDIOCONTROL_H
diff --git a/emulator/audio/halservice/PowerPolicyClient.cpp b/emulator/audio/halservice/PowerPolicyClient.cpp
new file mode 100644
index 0000000..cc431c6
--- /dev/null
+++ b/emulator/audio/halservice/PowerPolicyClient.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+ #define LOG_TAG "AudioPowerPolicyClient"
+
+#include "PowerPolicyClient.h"
+#include "AudioControl.h"
+
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace audiocontrol {
+
+namespace aafap = ::aidl::android::frameworks::automotive::powerpolicy;
+
+using aafap::CarPowerPolicy;
+using aafap::CarPowerPolicyFilter;
+using aafap::PowerComponent;
+using ::android::frameworks::automotive::powerpolicy::hasComponent;
+using ::ndk::ScopedAStatus;
+
+namespace {
+
+constexpr PowerComponent kAudioComponent = PowerComponent::AUDIO;
+
+} // namespace
+
+PowerPolicyClient::PowerPolicyClient(const std::shared_ptr<AudioControl>& audioControl)
+ : mAudioControl(audioControl) {}
+
+void PowerPolicyClient::onInitFailed() {
+ LOG(ERROR) << "Initializing power policy client failed";
+}
+
+std::vector<PowerComponent> PowerPolicyClient::getComponentsOfInterest() {
+ std::vector<PowerComponent> components{kAudioComponent};
+ return components;
+}
+
+ScopedAStatus PowerPolicyClient::onPolicyChanged(const CarPowerPolicy& powerPolicy) {
+ if (hasComponent(powerPolicy.enabledComponents, kAudioComponent)) {
+ mAudioControl->setAudioEnabled(true);
+ } else if (hasComponent(powerPolicy.disabledComponents, kAudioComponent)) {
+ mAudioControl->setAudioEnabled(false);
+ }
+
+ return ScopedAStatus::ok();
+}
+
+} // namespace audiocontrol
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/emulator/audio/halservice/PowerPolicyClient.h b/emulator/audio/halservice/PowerPolicyClient.h
new file mode 100644
index 0000000..a4772c6
--- /dev/null
+++ b/emulator/audio/halservice/PowerPolicyClient.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 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 AUTOMOTIVE_AUDIOCONTROL_AIDL_DEFAULT_POWERPOLICYCLIENT_H_
+#define AUTOMOTIVE_AUDIOCONTROL_AIDL_DEFAULT_POWERPOLICYCLIENT_H_
+
+#include "PowerPolicyClientBase.h"
+
+#include <memory>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace audiocontrol {
+
+class AudioControl;
+
+class PowerPolicyClient
+ : public ::android::frameworks::automotive::powerpolicy::PowerPolicyClientBase {
+ public:
+ explicit PowerPolicyClient(const std::shared_ptr<AudioControl>& audioControl);
+
+ void onInitFailed();
+ std::vector<::aidl::android::frameworks::automotive::powerpolicy::PowerComponent>
+ getComponentsOfInterest() override;
+ ::ndk::ScopedAStatus onPolicyChanged(
+ const ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicy&) override;
+
+ private:
+ std::shared_ptr<AudioControl> mAudioControl;
+};
+
+} // namespace audiocontrol
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // AUTOMOTIVE_AUDIOCONTROL_AIDL_DEFAULT_POWERPOLICYCLIENT_H_
diff --git a/emulator/audio/halservice/android.hardware.audio.service-caremu.rc b/emulator/audio/halservice/android.hardware.audio.service-caremu.rc
new file mode 100644
index 0000000..768425f
--- /dev/null
+++ b/emulator/audio/halservice/android.hardware.audio.service-caremu.rc
@@ -0,0 +1,10 @@
+service vendor.audio-hal /vendor/bin/hw/android.hardware.audio.service-caremu
+ override
+ class hal
+ user audioserver
+ # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
+ group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock context_hub
+ capabilities BLOCK_SUSPEND
+ ioprio rt 4
+ task_profiles ProcessCapacityHigh HighPerformance
+ onrestart restart audioserver
diff --git a/emulator/audio/halservice/audiocontrol-caremu.xml b/emulator/audio/halservice/audiocontrol-caremu.xml
new file mode 100644
index 0000000..7bc44da
--- /dev/null
+++ b/emulator/audio/halservice/audiocontrol-caremu.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.automotive.audiocontrol</name>
+ <fqname>IAudioControl/default</fqname>
+ </hal>
+</manifest> \ No newline at end of file
diff --git a/emulator/audio/halservice/service.cpp b/emulator/audio/halservice/service.cpp
new file mode 100644
index 0000000..e658cf4
--- /dev/null
+++ b/emulator/audio/halservice/service.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "audiohalservice"
+
+#include "AudioControl.h"
+#include "PowerPolicyClient.h"
+
+#include <string>
+#include <vector>
+
+#include <log/log.h>
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/LegacySupport.h>
+
+#include <android/hardware/audio/6.0/IDevicesFactory.h>
+#include <android/hardware/audio/effect/6.0/IEffectsFactory.h>
+
+using namespace android::hardware;
+using android::OK;
+using aidl::android::hardware::automotive::audiocontrol::AudioControl;
+using aidl::android::hardware::automotive::audiocontrol::PowerPolicyClient;
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::registerPassthroughServiceImplementation;
+
+using android::hardware::audio::effect::V6_0::IEffectsFactory;
+using android::hardware::audio::V6_0::IDevicesFactory;
+using android::hardware::registerPassthroughServiceImplementation;
+
+int main(int /* argc */, char* /* argv */ []) {
+ // Setup HIDL Audio HAL
+ configureRpcThreadpool(16, false /*callerWillJoin*/);
+ android::status_t status;
+ status = registerPassthroughServiceImplementation<IDevicesFactory>();
+ LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering audio service: %d", status);
+ status = registerPassthroughServiceImplementation<IEffectsFactory>();
+ LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering audio effects service: %d", status);
+
+ // Setup AudioControl HAL
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ 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());
+ CHECK(aidlStatus == STATUS_OK);
+
+ PowerPolicyClient powerPolicyClient = PowerPolicyClient(audioControl);
+ powerPolicyClient.init();
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // should not reach
+}
diff --git a/emulator/audio/overlay/packages/services/Car/service/res/values/config.xml b/emulator/audio/overlay/packages/services/Car/service/res/values/config.xml
index 28857b3..38ad500 100644
--- a/emulator/audio/overlay/packages/services/Car/service/res/values/config.xml
+++ b/emulator/audio/overlay/packages/services/Car/service/res/values/config.xml
@@ -23,4 +23,9 @@
-->
<resources>
<bool name="audioUseDynamicRouting">true</bool>
+ <!-- Configuration to enable muting of individual volume groups. If this is set to
+ false, muting of individual volume groups is disabled, instead muting will toggle master
+ mute. If this is set to true, car volume group muting is enabled and each individual
+ volume group can be muted separately. -->
+ <bool name="audioUseCarVolumeGroupMuting">true</bool>
</resources>
diff --git a/emulator/cluster/display_settings.xml b/emulator/cluster/display_settings.xml
new file mode 100644
index 0000000..1014c59
--- /dev/null
+++ b/emulator/cluster/display_settings.xml
@@ -0,0 +1,8 @@
+<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+<display-settings>
+ <!-- Use physical port number instead of local id -->
+ <config identifier="1" />
+
+ <!-- Display settings for cluster -->
+ <display name="port:1" forcedDensity="120" dontMoveToTop="true" />
+</display-settings>
diff --git a/emulator/cluster/osdouble_overlay/packages/services/Car/service/res/values/config.xml b/emulator/cluster/osdouble_overlay/packages/services/Car/service/res/values/config.xml
new file mode 100644
index 0000000..a637a8f
--- /dev/null
+++ b/emulator/cluster/osdouble_overlay/packages/services/Car/service/res/values/config.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2021, 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.
+*/
+-->
+
+<!-- Resources to configure car service based on each OEM's preference. -->
+<resources>
+ <!--
+ Specifies configuration of displays in system telling its usage / type and assigned
+ occupant.
+
+ Some examples are:
+ <item>displayPort=0,displayType=MAIN,occupantZoneId=0</item>
+ <item>displayPort=1,displayType=INSTRUMENT_CLUSTER,occupantZoneId=0</item>
+ <item>displayPort=2,displayType=MAIN,occupantZoneId=1</item>
+ <item>displayPort=3,displayType=MAIN,occupantZoneId=2</item>
+ <item>displayPort=4,displayType=MAIN,occupantZoneId=3</item>
+
+ displayPort: Unique port id for the display.
+ displayType: Display type for the display. Use * part from
+ CarOccupantZoneManager.DISPLAY_TYPE_* like MAIN, INSTRUMENT_CLUSTER and
+ etc.
+ occupantZoneId: occupantZoneId specified from config_occupant_zones.
+
+ -->
+ <string-array translatable="false" name="config_occupant_display_mapping">
+ <item>displayPort=0,displayType=MAIN,occupantZoneId=0</item>
+ <item>displayUniqueId=virtual:com.android.car.cluster.osdouble:ClusterDisplay,displayType=INSTRUMENT_CLUSTER,occupantZoneId=0</item>
+ </string-array>
+
+ <!--
+ Specifies optional features that can be enabled by this image. Note that vhal can disable
+ them depending on product variation.
+ Feature name can be either service name defined in Car.*_SERVICE for Car*Manager or any
+ optional feature defined under @OptionalFeature annotation.
+ Note that '/' is used to have subfeature under main feature like "MAIN_FEATURE/SUB_FEATURE".
+
+ Some examples are:
+ <item>storage_monitoring</item>
+ <item>com.android.car.user.CarUserNoticeService</item>
+ <item>com.example.Feature/SubFeature</item>
+
+ The default list defined below will enable all optional features defined.
+ -->
+ <!-- Override cluster_service with cluster_home_service. -->
+ <string-array translatable="false" name="config_allowed_optional_car_features">
+ <item>car_navigation_service</item>
+ <item>cluster_home_service</item>
+ <item>com.android.car.user.CarUserNoticeService</item>
+ <item>diagnostic</item>
+ <item>storage_monitoring</item>
+ <item>vehicle_map_service</item>
+ <item>car_evs_service</item>
+ <item>car_telemetry_service</item>
+ </string-array>
+</resources>
diff --git a/emulator/cluster/overlay/packages/services/Car/service/res/values/config.xml b/emulator/cluster/overlay/packages/services/Car/service/res/values/config.xml
new file mode 100644
index 0000000..4d45871
--- /dev/null
+++ b/emulator/cluster/overlay/packages/services/Car/service/res/values/config.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2020, 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.
+*/
+-->
+
+<!-- Resources to configure car service based on each OEM's preference. -->
+<resources>
+ <!--
+ Specifies configuration of displays in system telling its usage / type and assigned
+ occupant.
+
+ Some examples are:
+ <item>displayPort=0,displayType=MAIN,occupantZoneId=0</item>
+ <item>displayPort=1,displayType=INSTRUMENT_CLUSTER,occupantZoneId=0</item>
+ <item>displayPort=2,displayType=MAIN,occupantZoneId=1</item>
+ <item>displayPort=3,displayType=MAIN,occupantZoneId=2</item>
+ <item>displayPort=4,displayType=MAIN,occupantZoneId=3</item>
+
+ displayPort: Unique port id for the display.
+ displayType: Display type for the display. Use * part from
+ CarOccupantZoneManager.DISPLAY_TYPE_* like MAIN, INSTRUMENT_CLUSTER and
+ etc.
+ occupantZoneId: occupantZoneId specified from config_occupant_zones.
+
+ -->
+ <string-array translatable="false" name="config_occupant_display_mapping">
+ <item>displayPort=0,displayType=MAIN,occupantZoneId=0</item>
+ <item>displayPort=1,displayType=INSTRUMENT_CLUSTER,occupantZoneId=0</item>
+ </string-array>
+</resources>
diff --git a/emulator/rotary/car_rotary.mk b/emulator/rotary/car_rotary.mk
index e58a4f4..f910724 100644
--- a/emulator/rotary/car_rotary.mk
+++ b/emulator/rotary/car_rotary.mk
@@ -19,5 +19,4 @@ PRODUCT_PACKAGES += \
CarRotaryController \
RotaryPlayground \
RotaryIME \
-
-DEVICE_PACKAGE_OVERLAYS += device/generic/car/emulator/rotary/overlay
+ CarRotaryImeRRO \
diff --git a/gsi_car_arm64.mk b/gsi_car_arm64.mk
new file mode 100644
index 0000000..0977da4
--- /dev/null
+++ b/gsi_car_arm64.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2021 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.
+
+$(call inherit-product, device/generic/car/gsi_car_base.mk)
+$(call inherit-product, device/generic/common/gsi_arm64.mk)
+
+PRODUCT_NAME := gsi_car_arm64
+PRODUCT_DEVICE := generic_arm64
+PRODUCT_BRAND := Android
+PRODUCT_MODEL := Car GSI on arm64 \ No newline at end of file
diff --git a/gsi_car_base.mk b/gsi_car_base.mk
new file mode 100644
index 0000000..85d1277
--- /dev/null
+++ b/gsi_car_base.mk
@@ -0,0 +1,160 @@
+#
+# Copyright (C) 2021 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.
+
+PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := relaxed
+PRODUCT_PACKAGES += android.frameworks.automotive.display@1.0-service
+
+PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
+ root/init.bootstat.rc \
+ root/init.car.rc \
+ system/app/CarFrameworkPackageStubs/CarFrameworkPackageStubs.apk \
+ system/app/CarFrameworkPackageStubs/oat/arm64/CarFrameworkPackageStubs.odex \
+ system/app/CarFrameworkPackageStubs/oat/arm64/CarFrameworkPackageStubs.vdex \
+ system/app/CarHTMLViewer/CarHTMLViewer.apk \
+ system/app/CarLatinIME/CarLatinIME.apk \
+ system/app/CarMapsPlaceholder/CarMapsPlaceholder.apk \
+ system/app/CarPermissionControllerRRO/CarPermissionControllerRRO.apk \
+ system/app/RotaryIME/RotaryIME.apk \
+ system/app/RotaryIME/oat/arm64/RotaryIME.odex \
+ system/app/RotaryIME/oat/arm64/RotaryIME.vdex \
+ system/app/CarRotaryImeRRO/CarRotaryImeRRO.apk \
+ system/app/RotaryPlayground/RotaryPlayground.apk \
+ system/app/SampleCustomInputService/SampleCustomInputService.apk \
+ system/app/SampleRearViewCamera/SampleRearViewCamera.apk \
+ system/app/SampleRearViewCamera/oat/arm64/SampleRearViewCamera.odex \
+ system/app/SampleRearViewCamera/oat/arm64/SampleRearViewCamera.vdex \
+ system/app/SystemUpdater/SystemUpdater.apk \
+ system/bin/android.automotive.evs.manager@1.1 \
+ system/bin/carbugreportd \
+ system/bin/carpowerpolicyd \
+ system/bin/carwatchdogd \
+ system/bin/com.android.car.procfsinspector \
+ system/etc/apns-conf.xml \
+ system/etc/init/android.automotive.evs.manager@1.1.rc \
+ system/etc/init/carbugreportd.rc \
+ system/etc/init/carpowerpolicyd.rc \
+ system/etc/init/carwatchdogd.rc \
+ system/etc/init/com.android.car.procfsinspector.rc \
+ system/etc/init/init.bootstat.car.rc \
+ system/etc/init/init.car.rc \
+ system/etc/old-apns-conf.xml \
+ system/etc/permissions/android.car.cluster.xml \
+ system/etc/permissions/android.car.usb.handler.xml \
+ system/etc/permissions/android.hardware.broadcastradio.xml \
+ system/etc/permissions/android.hardware.type.automotive.xml \
+ system/etc/permissions/com.android.car.activityresolver.xml \
+ system/etc/permissions/com.android.car.bugreport.xml \
+ system/etc/permissions/com.android.car.carlauncher.xml \
+ system/etc/permissions/com.android.car.cluster.home.xml \
+ system/etc/permissions/com.android.car.dialer.xml \
+ system/etc/permissions/com.android.car.hvac.xml \
+ system/etc/permissions/com.android.car.media.xml \
+ system/etc/permissions/com.android.car.messenger.xml \
+ system/etc/permissions/com.android.car.radio.xml \
+ system/etc/permissions/com.android.car.rotary.xml \
+ system/etc/permissions/com.android.car.settings.xml \
+ system/etc/permissions/com.android.car.shell.xml \
+ system/etc/permissions/com.android.car.xml \
+ system/etc/permissions/com.google.android.car.defaultstoragemonitoringcompanionapp.xml \
+ system/etc/permissions/com.google.android.car.garagemode.testapp.xml \
+ system/etc/permissions/com.google.android.car.kitchensink.xml \
+ system/etc/permissions/com.google.android.car.networking.preferenceupdater.xml \
+ system/etc/sysconfig/preinstalled-packages-product-car-base.xml \
+ system/etc/vintf/manifest/carpowerpolicyd.xml \
+ system/etc/vintf/manifest/carwatchdogd.xml \
+ system/etc/vintf/manifest/manifest_android.automotive.evs.manager@1.1.xml \
+ system/framework/android.car.jar \
+ system/framework/car-frameworks-service.jar \
+ system/framework/oat/arm64/car-frameworks-service.odex \
+ system/framework/oat/arm64/car-frameworks-service.vdex \
+ system/lib/libcar-framework-service-jni.so \
+ system/lib/libsuspend.so \
+ system/lib64/android.automotive.watchdog-V3-cpp.so \
+ system/lib64/android.automotive.watchdog.internal-cpp.so \
+ system/lib64/android.frameworks.automotive.display@1.0.so \
+ system/lib64/android.frameworks.automotive.powerpolicy-V1-cpp.so \
+ system/lib64/android.frameworks.automotive.powerpolicy.internal-cpp.so \
+ system/lib64/android.hardware.automotive.evs@1.0.so \
+ system/lib64/android.hardware.automotive.evs@1.1.so \
+ system/lib64/android.hardware.automotive.vehicle@2.0.so \
+ system/lib64/libcar-framework-service-jni.so \
+ system/lib64/libscriptexecutor.so \
+ system/lib64/libscriptexecutorjni.so \
+ system/lib64/libsuspend.so \
+ system/lib64/libwatchdog_binder_mediator.so \
+ system/lib64/libwatchdog_package_info_resolver.so \
+ system/lib64/libwatchdog_perf_service.so \
+ system/lib64/libwatchdog_process_service.so \
+ system/media/bootanimation.zip \
+ system/priv-app/BugReportApp/BugReportApp.apk \
+ system/priv-app/CarActivityResolver/CarActivityResolver.apk \
+ system/priv-app/CarActivityResolver/oat/arm64/CarActivityResolver.odex \
+ system/priv-app/CarActivityResolver/oat/arm64/CarActivityResolver.vdex \
+ system/priv-app/CarDialerApp/CarDialerApp.apk \
+ system/priv-app/CarHvacApp/CarHvacApp.apk \
+ system/priv-app/CarLauncher/CarLauncher.apk \
+ system/priv-app/CarMediaApp/CarMediaApp.apk \
+ system/priv-app/CarMessengerApp/CarMessengerApp.apk \
+ system/priv-app/CarRadioApp/CarRadioApp.apk \
+ system/priv-app/CarRotaryController/CarRotaryController.apk \
+ system/priv-app/CarService/CarService.apk \
+ system/priv-app/CarService/lib/arm64/libscriptexecutorjni.so \
+ system/priv-app/CarService/lib/x86_64/libscriptexecutorjni.so \
+ system/priv-app/CarService/oat/arm64/CarService.odex \
+ system/priv-app/CarService/oat/arm64/CarService.vdex \
+ system/priv-app/CarSettings/CarSettings.apk \
+ system/priv-app/CarShell/CarShell.apk \
+ system/priv-app/CarShell/oat/arm64/CarShell.odex \
+ system/priv-app/CarShell/oat/arm64/CarShell.vdex \
+ system/priv-app/CarUsbHandler/CarUsbHandler.apk \
+ system/priv-app/CarUsbHandler/oat/arm64/CarUsbHandler.odex \
+ system/priv-app/CarUsbHandler/oat/arm64/CarUsbHandler.vdex \
+ system/priv-app/ClusterHomeSample/ClusterHomeSample.apk \
+ system/priv-app/ClusterHomeSample/oat/arm64/ClusterHomeSample.odex \
+ system/priv-app/ClusterHomeSample/oat/arm64/ClusterHomeSample.vdex \
+ system/priv-app/DefaultStorageMonitoringCompanionApp/DefaultStorageMonitoringCompanionApp.apk \
+ system/priv-app/DirectRenderingCluster/DirectRenderingCluster.apk \
+ system/priv-app/DirectRenderingCluster/oat/arm64/DirectRenderingCluster.odex \
+ system/priv-app/DirectRenderingCluster/oat/arm64/DirectRenderingCluster.vdex \
+ system/priv-app/EmbeddedKitchenSinkApp/EmbeddedKitchenSinkApp.apk \
+ system/priv-app/ExperimentalCarService/ExperimentalCarService.apk \
+ system/priv-app/ExperimentalCarService/oat/arm64/ExperimentalCarService.odex \
+ system/priv-app/ExperimentalCarService/oat/arm64/ExperimentalCarService.vdex \
+ system/priv-app/GarageModeTestApp/GarageModeTestApp.apk \
+ system/priv-app/LocalMediaPlayer/LocalMediaPlayer.apk \
+ system/priv-app/NetworkPreferenceApp/NetworkPreferenceApp.apk \
+ system/lib64/libcarservicejni.so \
+ system/priv-app/CarService/lib/arm64/libcarservicejni.so \
+ system/priv-app/CarService/lib/x86_64/libcarservicejni.so \
+ system/bin/android.automotive.telemetryd@1.0 \
+ system/etc/init/android.automotive.telemetryd@1.0.rc \
+ system/etc/vintf/manifest/android.automotive.telemetryd@1.0.xml \
+ system/lib64/android.automotive.telemetryd@1.0-impl.so \
+ system/lib64/android.frameworks.automotive.telemetry-V1-cpp.so \
+ system/lib64/android.automotive.telemetry.internal-ndk_platform.so \
+ system/lib64/android.frameworks.automotive.telemetry-V1-ndk_platform.so \
+ system/etc/automotive/watchdog/system_resource_overuse_configuration.xml \
+ system/etc/automotive/watchdog/third_party_resource_overuse_configuration.xml \
+ system/bin/android.frameworks.automotive.display@1.0-service \
+ system/etc/init/android.frameworks.automotive.display@1.0-service.rc \
+ system/etc/vintf/manifest/manifest_android.frameworks.automotive.display@1.0.xml \
+
+PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += %.odex %.vdex %.art
+
+PRODUCT_PACKAGE_OVERLAYS := device/generic/car/common/overlay
+EMULATOR_VENDOR_NO_SENSORS := true
+PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true
+$(call inherit-product, device/generic/car/emulator/aosp_car_emulator.mk)
+EMULATOR_VENDOR_NO_SOUND := true
diff --git a/gsi_car_x86_64.mk b/gsi_car_x86_64.mk
new file mode 100644
index 0000000..378fa5c
--- /dev/null
+++ b/gsi_car_x86_64.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2021 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.
+
+$(call inherit-product, device/generic/car/gsi_car_base.mk)
+$(call inherit-product, device/generic/common/gsi_x86_64.mk)
+
+PRODUCT_NAME := gsi_car_x86_64
+PRODUCT_DEVICE := generic_x86_64
+PRODUCT_BRAND := Android
+PRODUCT_MODEL := Car GSI on x86_64 \ No newline at end of file
diff --git a/setup/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml b/setup/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
new file mode 100644
index 0000000..eee765b
--- /dev/null
+++ b/setup/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2020, 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.
+ */
+-->
+<resources>
+ <bool name="def_device_provisioned">false</bool>
+
+ <bool name="def_user_setup_complete">false</bool>
+</resources>
diff --git a/setup/overlay/packages/services/Car/service/res/values/config.xml b/setup/overlay/packages/services/Car/service/res/values/config.xml
new file mode 100644
index 0000000..5add0cd
--- /dev/null
+++ b/setup/overlay/packages/services/Car/service/res/values/config.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2020, 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.
+*/
+-->
+
+<!-- Resources to configure car service based on each OEM's preference. -->
+<resources>
+
+ <!-- Specifies notice UI that will be launched when user starts a car or do user
+ switching. It is recommended to use dialog with at least TYPE_APPLICATION_OVERLAY window
+ type to show the UI regardless of activity launches. Target package will be auto-granted
+ necessary permission for TYPE_APPLICATION_OVERLAY window type. The UI package should
+ resolve permission by itself to use any higher priority window type.
+ Setting this string to empty will disable the feature. -->
+ <string name="config_userNoticeUiService" translatable="false">com.google.android.car.setupwizard/.account.ShortNoticeService</string>
+</resources>