Merge "[RTT] Condition RTT Controller on availability of a STA mode"
diff --git a/audio/4.1/config/audio_policy_configuration.xsd b/audio/4.1/config/audio_policy_configuration.xsd
new file mode 100644
index 0000000..311b9c1
--- /dev/null
+++ b/audio/4.1/config/audio_policy_configuration.xsd
@@ -0,0 +1,595 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+<!-- TODO: define a targetNamespace. Note that it will break retrocompatibility -->
+<xs:schema version="2.0"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <!-- List the config versions supported by audio policy. -->
+ <xs:simpleType name="version">
+ <xs:restriction base="xs:decimal">
+ <xs:enumeration value="1.0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="halVersion">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Version of the interface the hal implements.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:decimal">
+ <!-- List of HAL versions supported by the framework. -->
+ <xs:enumeration value="2.0"/>
+ <xs:enumeration value="3.0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="audioPolicyConfiguration">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="globalConfiguration" type="globalConfiguration"/>
+ <xs:element name="modules" type="modules" maxOccurs="unbounded"/>
+ <xs:element name="volumes" type="volumes" maxOccurs="unbounded"/>
+ <xs:element name="surroundSound" type="surroundSound" />
+ </xs:sequence>
+ <xs:attribute name="version" type="version"/>
+ </xs:complexType>
+ <xs:key name="moduleNameKey">
+ <xs:selector xpath="modules/module"/>
+ <xs:field xpath="@name"/>
+ </xs:key>
+ <xs:unique name="volumeTargetUniqueness">
+ <xs:selector xpath="volumes/volume"/>
+ <xs:field xpath="@stream"/>
+ <xs:field xpath="@deviceCategory"/>
+ </xs:unique>
+ <xs:key name="volumeCurveNameKey">
+ <xs:selector xpath="volumes/reference"/>
+ <xs:field xpath="@name"/>
+ </xs:key>
+ <xs:keyref name="volumeCurveRef" refer="volumeCurveNameKey">
+ <xs:selector xpath="volumes/volume"/>
+ <xs:field xpath="@ref"/>
+ </xs:keyref>
+ </xs:element>
+ <xs:complexType name="globalConfiguration">
+ <xs:attribute name="speaker_drc_enabled" type="xs:boolean" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="modules">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ There should be one section per audio HW module present on the platform.
+ Each <module/> contains two mandatory tags: “halVersion” and “name”.
+ The module "name" is the same as in previous .conf file.
+ Each module must contain the following sections:
+ - <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.
+ - <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.
+ A <route/> is defined by a set of 3 attributes:
+ -"type": mux|mix means all sources are mutual exclusive (mux) or can be mixed (mix)
+ -"sink": the sink involved in this route
+ -"sources": all the sources than can be connected to the sink via this route
+ - <attachedDevices/>: permanently attached devices.
+ The attachedDevices section is a list of devices names.
+ Their names correspond to device names defined in "devicePorts" section.
+ - <defaultOutputDevice/> is the device to be used when no policy rule applies
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="module" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="attachedDevices" type="attachedDevices" minOccurs="0">
+ <xs:unique name="attachedDevicesUniqueness">
+ <xs:selector xpath="item"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ </xs:element>
+ <xs:element name="defaultOutputDevice" type="xs:token" minOccurs="0"/>
+ <xs:element name="mixPorts" type="mixPorts" minOccurs="0"/>
+ <xs:element name="devicePorts" type="devicePorts" minOccurs="0"/>
+ <xs:element name="routes" type="routes" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="halVersion" type="halVersion" use="required"/>
+ </xs:complexType>
+ <xs:unique name="mixPortNameUniqueness">
+ <xs:selector xpath="mixPorts/mixPort"/>
+ <xs:field xpath="@name"/>
+ </xs:unique>
+ <xs:key name="devicePortNameKey">
+ <xs:selector xpath="devicePorts/devicePort"/>
+ <xs:field xpath="@tagName"/>
+ </xs:key>
+ <xs:unique name="devicePortUniqueness">
+ <xs:selector xpath="devicePorts/devicePort"/>
+ <xs:field xpath="@type"/>
+ <xs:field xpath="@address"/>
+ </xs:unique>
+ <xs:keyref name="defaultOutputDeviceRef" refer="devicePortNameKey">
+ <xs:selector xpath="defaultOutputDevice"/>
+ <xs:field xpath="."/>
+ </xs:keyref>
+ <xs:keyref name="attachedDeviceRef" refer="devicePortNameKey">
+ <xs:selector xpath="attachedDevices/item"/>
+ <xs:field xpath="."/>
+ </xs:keyref>
+ <!-- The following 3 constraints try to make sure each sink port
+ is reference in one an only one route. -->
+ <xs:key name="routeSinkKey">
+ <!-- predicate [@type='sink'] does not work in xsd 1.0 -->
+ <xs:selector xpath="devicePorts/devicePort|mixPorts/mixPort"/>
+ <xs:field xpath="@tagName|@name"/>
+ </xs:key>
+ <xs:keyref name="routeSinkRef" refer="routeSinkKey">
+ <xs:selector xpath="routes/route"/>
+ <xs:field xpath="@sink"/>
+ </xs:keyref>
+ <xs:unique name="routeUniqueness">
+ <xs:selector xpath="routes/route"/>
+ <xs:field xpath="@sink"/>
+ </xs:unique>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="attachedDevices">
+ <xs:sequence>
+ <xs:element name="item" type="xs:token" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <!-- TODO: separate values by space for better xsd validations. -->
+ <xs:simpleType name="audioInOutFlags">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ "|" separated list of audio_output_flags_t or audio_input_flags_t.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:pattern value="|[_A-Z]+(\|[_A-Z]+)*"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="role">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="sink"/>
+ <xs:enumeration value="source"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="mixPorts">
+ <xs:sequence>
+ <xs:element name="mixPort" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="gains" type="gains" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:token" use="required"/>
+ <xs:attribute name="role" type="role" use="required"/>
+ <xs:attribute name="flags" type="audioInOutFlags"/>
+ <xs:attribute name="maxOpenCount" type="xs:unsignedInt"/>
+ <xs:attribute name="maxActiveCount" type="xs:unsignedInt"/>
+ <xs:attribute name="preferredUsage" type="audioUsageList">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ When choosing the mixPort of an audio track, the audioPolicy
+ first considers the mixPorts with a preferredUsage including
+ the track AudioUsage preferred .
+ If non support the track format, the other mixPorts are considered.
+ Eg: a <mixPort preferredUsage="AUDIO_USAGE_MEDIA" /> will receive
+ the audio of all apps playing with a MEDIA usage.
+ It may receive audio from ALARM if there are no audio compatible
+ <mixPort preferredUsage="AUDIO_USAGE_ALARM" />.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ <xs:unique name="mixPortProfileUniqueness">
+ <xs:selector xpath="profile"/>
+ <xs:field xpath="format"/>
+ <xs:field xpath="samplingRate"/>
+ <xs:field xpath="channelMasks"/>
+ </xs:unique>
+ <xs:unique name="mixPortGainUniqueness">
+ <xs:selector xpath="gains/gain"/>
+ <xs:field xpath="@name"/>
+ </xs:unique>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <!-- Enum values of audio_device_t in audio.h
+ TODO: generate from hidl to avoid manual sync.
+ TODO: separate source and sink in the xml for better xsd validations. -->
+ <xs:simpleType name="audioDevice">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_DEVICE_NONE"/>
+
+ <xs:enumeration value="AUDIO_DEVICE_OUT_EARPIECE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_WIRED_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_WIRED_HEADPHONE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_DIGITAL"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_USB_ACCESSORY"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_USB_DEVICE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_REMOTE_SUBMIX"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_TELEPHONY_TX"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_LINE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI_ARC"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_SPDIF"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_FM"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_LINE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER_SAFE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_IP"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BUS"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_PROXY"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_USB_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_HEARING_AID"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_ECHO_CANCELLER"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_DEFAULT"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_STUB"/>
+
+ <!-- Due to the xml format, IN types can not be a separated from OUT types -->
+ <xs:enumeration value="AUDIO_DEVICE_IN_COMMUNICATION"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_AMBIENT"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BUILTIN_MIC"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_WIRED_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_AUX_DIGITAL"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_HDMI"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_VOICE_CALL"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_TELEPHONY_RX"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BACK_MIC"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_REMOTE_SUBMIX"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_USB_ACCESSORY"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_USB_DEVICE"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_FM_TUNER"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_TV_TUNER"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_LINE"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_SPDIF"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_A2DP"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_LOOPBACK"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_IP"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BUS"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_PROXY"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_USB_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_BLE"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_DEFAULT"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_STUB"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <!-- Enum values of audio_format_t in audio.h
+ TODO: generate from hidl to avoid manual sync. -->
+ <xs:simpleType name="audioFormat">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_FORMAT_PCM_16_BIT" />
+ <xs:enumeration value="AUDIO_FORMAT_PCM_8_BIT"/>
+ <xs:enumeration value="AUDIO_FORMAT_PCM_32_BIT"/>
+ <xs:enumeration value="AUDIO_FORMAT_PCM_8_24_BIT"/>
+ <xs:enumeration value="AUDIO_FORMAT_PCM_FLOAT"/>
+ <xs:enumeration value="AUDIO_FORMAT_PCM_24_BIT_PACKED"/>
+ <xs:enumeration value="AUDIO_FORMAT_MP3"/>
+ <xs:enumeration value="AUDIO_FORMAT_AMR_NB"/>
+ <xs:enumeration value="AUDIO_FORMAT_AMR_WB"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_MAIN"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_LC"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_SSR"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_LTP"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_HE_V1"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_SCALABLE"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ERLC"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_LD"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_HE_V2"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ELD"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_MAIN"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LC"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_SSR"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LTP"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_HE_V1"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_SCALABLE"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_ERLC"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LD"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_HE_V2"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_ELD"/>
+ <xs:enumeration value="AUDIO_FORMAT_VORBIS"/>
+ <xs:enumeration value="AUDIO_FORMAT_HE_AAC_V1"/>
+ <xs:enumeration value="AUDIO_FORMAT_HE_AAC_V2"/>
+ <xs:enumeration value="AUDIO_FORMAT_OPUS"/>
+ <xs:enumeration value="AUDIO_FORMAT_AC3"/>
+ <xs:enumeration value="AUDIO_FORMAT_E_AC3"/>
+ <xs:enumeration value="AUDIO_FORMAT_DTS"/>
+ <xs:enumeration value="AUDIO_FORMAT_DTS_HD"/>
+ <xs:enumeration value="AUDIO_FORMAT_IEC61937"/>
+ <xs:enumeration value="AUDIO_FORMAT_DOLBY_TRUEHD"/>
+ <xs:enumeration value="AUDIO_FORMAT_EVRC"/>
+ <xs:enumeration value="AUDIO_FORMAT_EVRCB"/>
+ <xs:enumeration value="AUDIO_FORMAT_EVRCWB"/>
+ <xs:enumeration value="AUDIO_FORMAT_EVRCNW"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADIF"/>
+ <xs:enumeration value="AUDIO_FORMAT_WMA"/>
+ <xs:enumeration value="AUDIO_FORMAT_WMA_PRO"/>
+ <xs:enumeration value="AUDIO_FORMAT_AMR_WB_PLUS"/>
+ <xs:enumeration value="AUDIO_FORMAT_MP2"/>
+ <xs:enumeration value="AUDIO_FORMAT_QCELP"/>
+ <xs:enumeration value="AUDIO_FORMAT_DSD"/>
+ <xs:enumeration value="AUDIO_FORMAT_FLAC"/>
+ <xs:enumeration value="AUDIO_FORMAT_ALAC"/>
+ <xs:enumeration value="AUDIO_FORMAT_APE"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS"/>
+ <xs:enumeration value="AUDIO_FORMAT_SBC"/>
+ <xs:enumeration value="AUDIO_FORMAT_APTX"/>
+ <xs:enumeration value="AUDIO_FORMAT_APTX_HD"/>
+ <xs:enumeration value="AUDIO_FORMAT_AC4"/>
+ <xs:enumeration value="AUDIO_FORMAT_LDAC"/>
+ <xs:enumeration value="AUDIO_FORMAT_E_AC3_JOC"/>
+ <xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/>
+ <xs:enumeration value="AUDIO_FORMAT_MAT_2_0"/>
+ <xs:enumeration value="AUDIO_FORMAT_MAT_2_1"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_XHE"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_XHE"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <!-- Enum values of audio::common::4_0::AudioUsage
+ TODO: generate from HIDL to avoid manual sync. -->
+ <xs:simpleType name="audioUsage">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_USAGE_UNKNOWN" />
+ <xs:enumeration value="AUDIO_USAGE_MEDIA" />
+ <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+ <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+ <xs:enumeration value="AUDIO_USAGE_ALARM" />
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION" />
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <xs:enumeration value="AUDIO_USAGE_GAME" />
+ <xs:enumeration value="AUDIO_USAGE_VIRTUAL_SOURCE" />
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANT" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="audioUsageList">
+ <xs:list itemType="audioUsage"/>
+ </xs:simpleType>
+ <!-- TODO: Change to a space separated list to xsd enforce correctness. -->
+ <xs:simpleType name="samplingRates">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[0-9]+(,[0-9]+)*"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <!-- TODO: Change to a space separated list to xsd enforce correctness. -->
+ <xs:simpleType name="channelMask">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Comma (",") separated list of channel flags
+ from audio_channel_mask_t.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[_A-Z][_A-Z0-9]*(,[_A-Z][_A-Z0-9]*)*"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="profile">
+ <xs:attribute name="name" type="xs:token" use="optional"/>
+ <xs:attribute name="format" type="audioFormat" use="optional"/>
+ <xs:attribute name="samplingRates" type="samplingRates" use="optional"/>
+ <xs:attribute name="channelMasks" type="channelMask" use="optional"/>
+ </xs:complexType>
+ <xs:simpleType name="gainMode">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_GAIN_MODE_JOINT"/>
+ <xs:enumeration value="AUDIO_GAIN_MODE_CHANNELS"/>
+ <xs:enumeration value="AUDIO_GAIN_MODE_RAMP"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="gains">
+ <xs:sequence>
+ <xs:element name="gain" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:token" use="required"/>
+ <xs:attribute name="mode" type="gainMode" use="required"/>
+ <xs:attribute name="channel_mask" type="channelMask" use="optional"/>
+ <xs:attribute name="minValueMB" type="xs:int" use="optional"/>
+ <xs:attribute name="maxValueMB" type="xs:int" use="optional"/>
+ <xs:attribute name="defaultValueMB" type="xs:int" use="optional"/>
+ <xs:attribute name="stepValueMB" type="xs:int" use="optional"/>
+ <xs:attribute name="minRampMs" type="xs:int" use="optional"/>
+ <xs:attribute name="maxRampMs" type="xs:int" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="devicePorts">
+ <xs:sequence>
+ <xs:element name="devicePort" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="gains" type="gains" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="tagName" type="xs:token" use="required"/>
+ <xs:attribute name="type" type="audioDevice" use="required"/>
+ <xs:attribute name="role" type="role" use="required"/>
+ <xs:attribute name="address" type="xs:string" use="optional" default=""/>
+ <!-- Note that XSD 1.0 can not check that a type only has one default. -->
+ <xs:attribute name="default" type="xs:boolean" use="optional">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ The default device will be used if multiple have the same type
+ and no explicit route request exists for a specific device of
+ that type.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ <xs:unique name="devicePortProfileUniqueness">
+ <xs:selector xpath="profile"/>
+ <xs:field xpath="format"/>
+ <xs:field xpath="samplingRate"/>
+ <xs:field xpath="channelMasks"/>
+ </xs:unique>
+ <xs:unique name="devicePortGainUniqueness">
+ <xs:selector xpath="gains/gain"/>
+ <xs:field xpath="@name"/>
+ </xs:unique>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:simpleType name="mixType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="mix"/>
+ <xs:enumeration value="mux"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="routes">
+ <xs:sequence>
+ <xs:element name="route" minOccurs="0" maxOccurs="unbounded">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ List all available sources for a given sink.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:attribute name="type" type="mixType" use="required"/>
+ <xs:attribute name="sink" type="xs:string" use="required"/>
+ <xs:attribute name="sources" type="xs:string" use="required"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="volumes">
+ <xs:sequence>
+ <xs:element name="volume" type="volume" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="reference" type="reference" minOccurs="0" maxOccurs="unbounded">
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <!-- TODO: Always require a ref for better xsd validations.
+ Currently a volume could have no points nor ref
+ as it can not be forbidden by xsd 1.0.-->
+ <xs:simpleType name="volumePoint">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Comma separated pair of number.
+ The fist one is the framework level (between 0 and 100).
+ The second one is the volume to send to the HAL.
+ The framework will interpolate volumes not specified.
+ Their MUST be at least 2 points specified.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:pattern value="([0-9]{1,2}|100),-?[0-9]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <!-- Enum values of audio_stream_type_t in audio-base.h
+ TODO: generate from hidl to avoid manual sync. -->
+ <xs:simpleType name="stream">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_STREAM_VOICE_CALL"/>
+ <xs:enumeration value="AUDIO_STREAM_SYSTEM"/>
+ <xs:enumeration value="AUDIO_STREAM_RING"/>
+ <xs:enumeration value="AUDIO_STREAM_MUSIC"/>
+ <xs:enumeration value="AUDIO_STREAM_ALARM"/>
+ <xs:enumeration value="AUDIO_STREAM_NOTIFICATION"/>
+ <xs:enumeration value="AUDIO_STREAM_BLUETOOTH_SCO"/>
+ <xs:enumeration value="AUDIO_STREAM_ENFORCED_AUDIBLE"/>
+ <xs:enumeration value="AUDIO_STREAM_DTMF"/>
+ <xs:enumeration value="AUDIO_STREAM_TTS"/>
+ <xs:enumeration value="AUDIO_STREAM_ACCESSIBILITY"/>
+ <xs:enumeration value="AUDIO_STREAM_REROUTING"/>
+ <xs:enumeration value="AUDIO_STREAM_PATCH"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <!-- Enum values of device_category from Volume.h.
+ TODO: generate from hidl to avoid manual sync. -->
+ <xs:simpleType name="deviceCategory">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="DEVICE_CATEGORY_HEADSET"/>
+ <xs:enumeration value="DEVICE_CATEGORY_SPEAKER"/>
+ <xs:enumeration value="DEVICE_CATEGORY_EARPIECE"/>
+ <xs:enumeration value="DEVICE_CATEGORY_EXT_MEDIA"/>
+ <xs:enumeration value="DEVICE_CATEGORY_HEARING_AID"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="volume">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Volume section defines a volume curve for a given use case and device category.
+ It contains a list of points of this curve expressing the attenuation in Millibels
+ for a given volume index from 0 to 100.
+ <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-9600</point>
+ <point>100,0</point>
+ </volume>
+
+ It may also reference a reference/@name to avoid duplicating curves.
+ <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER"
+ ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+ <reference name="DEFAULT_MEDIA_VOLUME_CURVE">
+ <point>0,-9600</point>
+ <point>100,0</point>
+ </reference>
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="point" type="volumePoint" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="stream" type="stream"/>
+ <xs:attribute name="deviceCategory" type="deviceCategory"/>
+ <xs:attribute name="ref" type="xs:token" use="optional"/>
+ </xs:complexType>
+ <xs:complexType name="reference">
+ <xs:sequence>
+ <xs:element name="point" type="volumePoint" minOccurs="2" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:token" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="surroundSound">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Surround Sound section provides configuration related to handling of
+ multi-channel formats.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="formats" type="surroundFormats"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:simpleType name="surroundFormatsList">
+ <xs:list itemType="audioFormat" />
+ </xs:simpleType>
+ <xs:complexType name="surroundFormats">
+ <xs:sequence>
+ <xs:element name="format" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="audioFormat" use="required"/>
+ <xs:attribute name="subformats" type="surroundFormatsList" />
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+</xs:schema>
diff --git a/biometrics/face/1.0/IBiometricsFace.hal b/biometrics/face/1.0/IBiometricsFace.hal
index 1c7bfb9..0ac788e 100644
--- a/biometrics/face/1.0/IBiometricsFace.hal
+++ b/biometrics/face/1.0/IBiometricsFace.hal
@@ -225,7 +225,10 @@
* Authenticates the active user.
*
* An optional operationId can be specified as a token from the transaction
- * being authorized.
+ * being authorized. The hardware may enter a standby state during
+ * authentication, where the device is idle to conserve power while
+ * authenticating, e.g. after 3 seconds without finding a face. See
+ * IBiometricsFace#userActivity() for more info.
*
* @param operationId A non-zero operation id associated with a crypto
* object instance; or 0 if not being used.
@@ -233,4 +236,17 @@
*/
@callflow(next={"cancel", "generateChallenge", "remove"})
authenticate(uint64_t operationId) generates (Status status);
+
+ /**
+ * A hint to the HAL to continue looking for faces.
+ *
+ * This method should only be used when the HAL is in the authenticating
+ * or standby state. Using this method when the HAL is not in one of the
+ * mentioned states must return OPERATION_NOT_SUPPORTED. Calling this
+ * method while the HAL is already authenticating may extend the duration
+ * where it's looking for a face.
+ *
+ * @return status The status of this method call.
+ */
+ userActivity() generates (Status status);
};
diff --git a/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp
index eb840a7..392ebbc 100644
--- a/camera/common/1.0/default/CameraModule.cpp
+++ b/camera/common/1.0/default/CameraModule.cpp
@@ -235,7 +235,7 @@
chars.update(keyTag, availableKeys);
}
-CameraModule::CameraModule(camera_module_t *module) {
+CameraModule::CameraModule(camera_module_t *module) : mNumberOfCameras(0) {
if (module == NULL) {
ALOGE("%s: camera hardware module must not be null", __FUNCTION__);
assert(0);
@@ -264,7 +264,8 @@
res = mModule->init();
ATRACE_END();
}
- mCameraInfoMap.setCapacity(getNumberOfCameras());
+ mNumberOfCameras = getNumberOfCameras();
+ mCameraInfoMap.setCapacity(mNumberOfCameras);
return res;
}
@@ -322,7 +323,7 @@
int CameraModule::getPhysicalCameraInfo(int physicalCameraId, camera_metadata_t **physicalInfo) {
ATRACE_CALL();
Mutex::Autolock lock(mCameraInfoLock);
- if (physicalCameraId < 0) {
+ if (physicalCameraId < mNumberOfCameras) {
ALOGE("%s: Invalid physical camera ID %d", __FUNCTION__, physicalCameraId);
return -EINVAL;
}
@@ -334,6 +335,10 @@
__FUNCTION__);
return -ENODEV;
}
+ if (mModule->get_physical_camera_info == nullptr) {
+ ALOGE("%s: get_physical_camera is NULL for module version 2.5", __FUNCTION__);
+ return -EINVAL;
+ }
ssize_t index = mPhysicalCameraInfoMap.indexOfKey(physicalCameraId);
if (index == NAME_NOT_FOUND) {
diff --git a/camera/common/1.0/default/include/CameraModule.h b/camera/common/1.0/default/include/CameraModule.h
index ed853bf..aee9654 100644
--- a/camera/common/1.0/default/include/CameraModule.h
+++ b/camera/common/1.0/default/include/CameraModule.h
@@ -75,6 +75,7 @@
int32_t keyTag, const Vector<int32_t>& appendKeys);
status_t filterOpenErrorCode(status_t err);
camera_module_t *mModule;
+ int mNumberOfCameras;
KeyedVector<int, camera_info> mCameraInfoMap;
KeyedVector<int, int> mDeviceVersionMap;
KeyedVector<int, camera_metadata_t*> mPhysicalCameraInfoMap;
diff --git a/camera/device/3.5/ICameraDevice.hal b/camera/device/3.5/ICameraDevice.hal
index e7e8dd3..a77380f 100644
--- a/camera/device/3.5/ICameraDevice.hal
+++ b/camera/device/3.5/ICameraDevice.hal
@@ -36,11 +36,24 @@
* this logical camera device. This information may not change between consecutive calls.
*
* Note that HAL must support this function for physical camera IDs that are
- * not exposed via ICameraProvider::getCameraIdList().
+ * not exposed via ICameraProvider::getCameraIdList(). Calling
+ * getCameraDeviceInterface_V3_x() on these camera IDs must return ILLEGAL_ARGUMENT.
+ *
+ * The characteristics of all cameras returned by
+ * ICameraProvider::getCameraIdList() must be queried via
+ * getCameraCharacteristics(). Calling getPhysicalCameraCharacteristics() on
+ * those cameras must return ILLEGAL_ARGUMENT.
+ *
+ * @param physicalCameraId The physical camera id parsed from the logical
+ * camera's ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS static metadata
+ * key. The framework assumes that this ID is just the <id> part of fully
+ * qualified camera device name "device@<major>.<minor>/<type>/<id>". And
+ * the physical camera must be of the same version and type as the parent
+ * logical camera device.
*
* @return status Status code for the operation, one of:
* OK:
- * On a successful query of the camera device characteristics
+ * On a successful query of the physical camera device characteristics
* INTERNAL_ERROR:
* The camera device cannot be opened due to an internal
* error.
@@ -50,6 +63,9 @@
* instance must be acquired if the device is reconnected. All
* subsequent calls on this interface must return
* CAMERA_DISCONNECTED.
+ * ILLEGAL_ARGUMENT:
+ * If the physicalCameraId is not a valid physical camera Id outside
+ * of ICameraProvider::getCameraIdList().
*
* @return cameraCharacteristics
* The static metadata for this logical camera device's physical device, or an empty
diff --git a/camera/device/3.5/default/CameraDevice.cpp b/camera/device/3.5/default/CameraDevice.cpp
index c5d6c57..a6969af 100644
--- a/camera/device/3.5/default/CameraDevice.cpp
+++ b/camera/device/3.5/default/CameraDevice.cpp
@@ -79,6 +79,10 @@
int ret = mModule->getPhysicalCameraInfo((int)id, &physicalInfo);
if (ret == OK) {
V3_2::implementation::convertToHidl(physicalInfo, &cameraCharacteristics);
+ } else if (ret == -EINVAL) {
+ ALOGE("%s: %s is not a valid physical camera Id outside of getCameraIdList()",
+ __FUNCTION__, physicalCameraId.c_str());
+ status = Status::ILLEGAL_ARGUMENT;
} else {
ALOGE("%s: Failed to get physical camera %s info: %s (%d)!", __FUNCTION__,
physicalCameraId.c_str(), strerror(-ret), ret);
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index ead4083..eb8d43e 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -37,6 +37,7 @@
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.3",
"android.hardware.camera.device@3.4",
+ "android.hardware.camera.device@3.5",
"android.hardware.camera.provider@2.4",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.common@1.0",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index fd9396c..94d06e8 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -28,6 +28,7 @@
#include <android/hardware/camera/device/1.0/ICameraDevice.h>
#include <android/hardware/camera/device/3.2/ICameraDevice.h>
+#include <android/hardware/camera/device/3.5/ICameraDevice.h>
#include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
@@ -144,10 +145,12 @@
namespace {
// "device@<version>/legacy/<id>"
const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
+ const int CAMERA_DEVICE_API_VERSION_3_5 = 0x305;
const int CAMERA_DEVICE_API_VERSION_3_4 = 0x304;
const int CAMERA_DEVICE_API_VERSION_3_3 = 0x303;
const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
+ const char *kHAL3_5 = "3.5";
const char *kHAL3_4 = "3.4";
const char *kHAL3_3 = "3.3";
const char *kHAL3_2 = "3.2";
@@ -182,7 +185,9 @@
return -1;
}
- if (version.compare(kHAL3_4) == 0) {
+ if (version.compare(kHAL3_5) == 0) {
+ return CAMERA_DEVICE_API_VERSION_3_5;
+ } else if (version.compare(kHAL3_4) == 0) {
return CAMERA_DEVICE_API_VERSION_3_4;
} else if (version.compare(kHAL3_3) == 0) {
return CAMERA_DEVICE_API_VERSION_3_3;
@@ -670,12 +675,19 @@
HalStreamConfiguration *halStreamConfig /*out*/,
bool *supportsPartialResults /*out*/,
uint32_t *partialResultCount /*out*/);
+
+ void verifyLogicalCameraMetadata(const std::string& cameraName,
+ const ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice>& device,
+ const CameraMetadata& chars, int deviceVersion,
+ const hidl_vec<hidl_string>& deviceNames);
+ void verifyCameraCharacteristics(Status status, const CameraMetadata& chars);
+
static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
std::vector<AvailableStream> &outputStreams,
const AvailableStream *threshold = nullptr);
static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta);
- static Status isLogicalMultiCamera(camera_metadata_t *staticMeta);
- static Status getPhysicalCameraIds(camera_metadata_t *staticMeta,
+ static Status isLogicalMultiCamera(const camera_metadata_t *staticMeta);
+ static Status getPhysicalCameraIds(const camera_metadata_t *staticMeta,
std::unordered_set<std::string> *physicalIds/*out*/);
static Status getSupportedKeys(camera_metadata_t *staticMeta,
uint32_t tagId, std::unordered_set<int32_t> *requestIDs/*out*/);
@@ -1266,6 +1278,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_3:
case CAMERA_DEVICE_API_VERSION_3_2: {
@@ -1307,6 +1320,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_3:
case CAMERA_DEVICE_API_VERSION_3_2: {
@@ -2047,6 +2061,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_3:
case CAMERA_DEVICE_API_VERSION_3_2: {
@@ -2063,41 +2078,31 @@
ASSERT_TRUE(ret.isOk());
ret = device3_x->getCameraCharacteristics([&](auto status, const auto& chars) {
- ALOGI("getCameraCharacteristics returns status:%d", (int)status);
- ASSERT_EQ(Status::OK, status);
- const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
- size_t expectedSize = chars.size();
- int result = validate_camera_metadata_structure(metadata, &expectedSize);
- ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
- size_t entryCount = get_camera_metadata_entry_count(metadata);
- // TODO: we can do better than 0 here. Need to check how many required
- // characteristics keys we've defined.
- ASSERT_GT(entryCount, 0u);
- ALOGI("getCameraCharacteristics metadata entry count is %zu", entryCount);
+ verifyCameraCharacteristics(status, chars);
- camera_metadata_ro_entry entry;
- int retcode = find_camera_metadata_ro_entry(metadata,
- ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &entry);
- if ((0 == retcode) && (entry.count > 0)) {
- uint8_t hardwareLevel = entry.data.u8[0];
- ASSERT_TRUE(
- hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED ||
- hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL ||
- hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3 ||
- hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL);
- } else {
- ADD_FAILURE() << "Get camera hardware level failed!";
- }
-
- entry.count = 0;
- retcode = find_camera_metadata_ro_entry(metadata,
- ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION, &entry);
- if ((0 == retcode) || (entry.count > 0)) {
- ADD_FAILURE() << "ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION "
- << " per API contract should never be set by Hal!";
- }
+ verifyLogicalCameraMetadata(name, device3_x, chars, deviceVersion,
+ cameraDeviceNames);
});
ASSERT_TRUE(ret.isOk());
+
+ //getPhysicalCameraCharacteristics will fail for publicly
+ //advertised camera IDs.
+ if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5) {
+ auto castResult = device::V3_5::ICameraDevice::castFrom(device3_x);
+ ASSERT_TRUE(castResult.isOk());
+ ::android::sp<::android::hardware::camera::device::V3_5::ICameraDevice>
+ device3_5 = castResult;
+ ASSERT_NE(device3_5, nullptr);
+
+ std::string version, cameraId;
+ ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &cameraId));
+ Return<void> ret = device3_5->getPhysicalCameraCharacteristics(cameraId,
+ [&](auto status, const auto& chars) {
+ ASSERT_TRUE(Status::ILLEGAL_ARGUMENT == status);
+ ASSERT_EQ(0, chars.size());
+ });
+ ASSERT_TRUE(ret.isOk());
+ }
}
break;
case CAMERA_DEVICE_API_VERSION_1_0: {
@@ -2134,6 +2139,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_3:
case CAMERA_DEVICE_API_VERSION_3_2: {
@@ -2259,6 +2265,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_3:
case CAMERA_DEVICE_API_VERSION_3_2: {
@@ -2323,6 +2330,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_3:
case CAMERA_DEVICE_API_VERSION_3_2: {
@@ -2351,7 +2359,8 @@
sp<device::V3_3::ICameraDeviceSession> sessionV3_3;
sp<device::V3_4::ICameraDeviceSession> sessionV3_4;
castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4);
- if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) {
+ if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4 ||
+ deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
ASSERT_TRUE(sessionV3_4.get() != nullptr);
} else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_3) {
ASSERT_TRUE(sessionV3_3.get() != nullptr);
@@ -2409,6 +2418,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_3:
case CAMERA_DEVICE_API_VERSION_3_2: {
@@ -4152,7 +4162,7 @@
}
// Check if the camera device has logical multi-camera capability.
-Status CameraHidlTest::isLogicalMultiCamera(camera_metadata_t *staticMeta) {
+Status CameraHidlTest::isLogicalMultiCamera(const camera_metadata_t *staticMeta) {
Status ret = Status::METHOD_NOT_SUPPORTED;
if (nullptr == staticMeta) {
return Status::ILLEGAL_ARGUMENT;
@@ -4176,7 +4186,7 @@
}
// Generate a list of physical camera ids backing a logical multi-camera.
-Status CameraHidlTest::getPhysicalCameraIds(camera_metadata_t *staticMeta,
+Status CameraHidlTest::getPhysicalCameraIds(const camera_metadata_t *staticMeta,
std::unordered_set<std::string> *physicalIds) {
if ((nullptr == staticMeta) || (nullptr == physicalIds)) {
return Status::ILLEGAL_ARGUMENT;
@@ -4649,6 +4659,7 @@
ASSERT_NE(nullptr, session3_4);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4: {
auto castResult = device::V3_4::ICameraDeviceSession::castFrom(session);
ASSERT_TRUE(castResult.isOk());
@@ -4667,6 +4678,101 @@
}
}
+// Verify logical camera static metadata
+void CameraHidlTest::verifyLogicalCameraMetadata(const std::string& cameraName,
+ const ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice>& device,
+ const CameraMetadata &chars, int deviceVersion,
+ const hidl_vec<hidl_string>& deviceNames) {
+ const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
+ ASSERT_NE(nullptr, metadata);
+
+ Status rc = isLogicalMultiCamera(metadata);
+ ASSERT_TRUE(Status::OK == rc || Status::METHOD_NOT_SUPPORTED == rc);
+ if (Status::METHOD_NOT_SUPPORTED == rc) {
+ return;
+ }
+
+ std::string version, cameraId;
+ ASSERT_TRUE(::matchDeviceName(cameraName, mProviderType, &version, &cameraId));
+ std::unordered_set<std::string> physicalIds;
+ ASSERT_TRUE(Status::OK == getPhysicalCameraIds(metadata, &physicalIds));
+ for (auto physicalId : physicalIds) {
+ ASSERT_NE(physicalId, cameraId);
+ bool isPublicId = false;
+ for (auto& deviceName : deviceNames) {
+ std::string publicVersion, publicId;
+ ASSERT_TRUE(::matchDeviceName(deviceName, mProviderType, &publicVersion, &publicId));
+ if (physicalId == publicId) {
+ isPublicId = true;
+ break;
+ }
+ }
+ if (isPublicId) {
+ continue;
+ }
+
+ ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
+ auto castResult = device::V3_5::ICameraDevice::castFrom(device);
+ ASSERT_TRUE(castResult.isOk());
+ ::android::sp<::android::hardware::camera::device::V3_5::ICameraDevice> device3_5 =
+ castResult;
+ ASSERT_NE(device3_5, nullptr);
+
+ // Check camera characteristics for hidden camera id
+ Return<void> ret = device3_5->getPhysicalCameraCharacteristics(physicalId,
+ [&](auto status, const auto& chars) {
+ verifyCameraCharacteristics(status, chars);
+ });
+ ASSERT_TRUE(ret.isOk());
+
+ // Check calling getCameraDeviceInterface_V3_x() on hidden camera id returns
+ // ILLEGAL_ARGUMENT.
+ std::stringstream s;
+ s << "device@" << version << "/" << mProviderType << "/" << physicalId;
+ hidl_string fullPhysicalId(s.str());
+ ret = mProvider->getCameraDeviceInterface_V3_x(fullPhysicalId,
+ [&](auto status, const auto& device3_x) {
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
+ ASSERT_EQ(device3_x, nullptr);
+ });
+ ASSERT_TRUE(ret.isOk());
+ }
+}
+
+void CameraHidlTest::verifyCameraCharacteristics(Status status, const CameraMetadata& chars) {
+ ASSERT_EQ(Status::OK, status);
+ const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
+ size_t expectedSize = chars.size();
+ int result = validate_camera_metadata_structure(metadata, &expectedSize);
+ ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+ size_t entryCount = get_camera_metadata_entry_count(metadata);
+ // TODO: we can do better than 0 here. Need to check how many required
+ // characteristics keys we've defined.
+ ASSERT_GT(entryCount, 0u);
+
+ camera_metadata_ro_entry entry;
+ int retcode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &entry);
+ if ((0 == retcode) && (entry.count > 0)) {
+ uint8_t hardwareLevel = entry.data.u8[0];
+ ASSERT_TRUE(
+ hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED ||
+ hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL ||
+ hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3 ||
+ hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL);
+ } else {
+ ADD_FAILURE() << "Get camera hardware level failed!";
+ }
+
+ entry.count = 0;
+ retcode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION, &entry);
+ if ((0 == retcode) || (entry.count > 0)) {
+ ADD_FAILURE() << "ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION "
+ << " per API contract should never be set by Hal!";
+ }
+}
+
// Open a device session with empty callbacks and return static metadata.
void CameraHidlTest::openEmptyDeviceSession(const std::string &name,
sp<ICameraProvider> provider,
diff --git a/fastboot/1.0/IFastboot.hal b/fastboot/1.0/IFastboot.hal
index a96755e..dce3ad7 100644
--- a/fastboot/1.0/IFastboot.hal
+++ b/fastboot/1.0/IFastboot.hal
@@ -34,7 +34,7 @@
* Executes a fastboot OEM command.
*
* @param oemCmdArgs The oem command that is passed to the fastboot HAL.
- * @response result Returns the status SUCCESS if the operation is successful,
+ * @return result Returns the status SUCCESS if the operation is successful,
* INVALID_ARGUMENT for bad arguments,
* FAILURE_UNKNOWN for an invalid/unsupported command.
*/
@@ -44,8 +44,8 @@
* Returns an OEM-defined string indicating the variant of the device, for
* example, US and ROW.
*
- * @response variant Indicates the device variant.
- * @response result Returns the status SUCCESS if the operation is successful,
+ * @return variant Indicates the device variant.
+ * @return result Returns the status SUCCESS if the operation is successful,
* FAILURE_UNKNOWN otherwise.
*/
getVariant() generates (string variant, Result result);
@@ -54,9 +54,19 @@
* Returns whether off-mode-charging is enabled. If enabled, the device
* autoboots into a special mode when power is applied.
*
- * @response state Returns whether off mode charging is enabled.
- * @response result Returns the status SUCCESS if the operation is successful,
+ * @return state Returns whether off mode charging is enabled.
+ * @return result Returns the status SUCCESS if the operation is successful,
* FAILURE_UNKNOWN otherwise.
*/
getOffModeChargeState() generates (bool state, Result result);
+
+ /**
+ * Returns the minimum battery voltage required for flashing in mV.
+ *
+ * @return batteryVoltage Minimum batterery voltage (in mV) required for
+ * flashing to be successful.
+ * @return result Returns the status SUCCESS if the operation is successful,
+ * FAILURE_UNKNOWN otherwise.
+ */
+ getBatteryVoltageFlashingThreshold() generates (int32_t batteryVoltage, Result result);
};
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
index db4c914..da8858e 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
@@ -193,9 +193,6 @@
}
void TearDown() override {
- mWriter->validateDisplay();
- mWriter->presentDisplay();
- execute();
ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF));
EXPECT_EQ(0, mReader->mErrors.size());
EXPECT_EQ(0, mReader->mCompositionChanges.size());
@@ -207,6 +204,11 @@
VtsHalHidlTargetTestBase::TearDown();
}
+ void clearCommandReaderState() {
+ mReader->mCompositionChanges.clear();
+ mReader->mErrors.clear();
+ }
+
void execute() {
ASSERT_NO_FATAL_FAILURE(mComposerClient->execute(mReader.get(), mWriter.get()));
}
@@ -489,6 +491,7 @@
// if hwc cannot handle and asks for composition change,
// just succeed the test
if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
GTEST_SUCCEED();
return;
}
@@ -533,6 +536,7 @@
execute();
if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
GTEST_SUCCEED();
return;
}
@@ -586,6 +590,7 @@
execute();
if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
GTEST_SUCCEED();
return;
}
@@ -760,6 +765,7 @@
mWriter->validateDisplay();
execute();
if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
GTEST_SUCCEED();
return;
}
@@ -801,6 +807,7 @@
mWriter->validateDisplay();
execute();
if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
GTEST_SUCCEED();
return;
}
@@ -864,6 +871,7 @@
mWriter->validateDisplay();
execute();
if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
GTEST_SUCCEED();
return;
}
@@ -912,6 +920,7 @@
mWriter->validateDisplay();
execute();
if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
GTEST_SUCCEED();
return;
}
@@ -962,6 +971,7 @@
mWriter->validateDisplay();
execute();
if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
GTEST_SUCCEED();
return;
}
@@ -1094,6 +1104,7 @@
mWriter->validateDisplay();
execute();
if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
GTEST_SUCCEED();
return;
}
@@ -1131,6 +1142,7 @@
mWriter->validateDisplay();
execute();
if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
GTEST_SUCCEED();
return;
}
@@ -1164,6 +1176,7 @@
mWriter->validateDisplay();
execute();
if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
GTEST_SUCCEED();
return;
}
@@ -1181,10 +1194,6 @@
protected:
void SetUp() override {
GraphicsComposerReadbackTest::SetUp();
- if (!mHasReadbackBuffer) {
- GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
- return;
- }
mWriter->selectDisplay(mPrimaryDisplay);
ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
@@ -1222,6 +1231,10 @@
};
TEST_F(GraphicsComposerTransformReadbackTest, FLIP_H) {
+ if (!mHasReadbackBuffer) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
mDisplayHeight, mPixelFormat, mDataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
@@ -1237,6 +1250,7 @@
mWriter->validateDisplay();
execute();
if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
GTEST_SUCCEED();
return;
}
@@ -1249,6 +1263,10 @@
}
TEST_F(GraphicsComposerTransformReadbackTest, FLIP_V) {
+ if (!mHasReadbackBuffer) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
mDisplayHeight, mPixelFormat, mDataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
@@ -1266,6 +1284,7 @@
mWriter->validateDisplay();
execute();
if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
GTEST_SUCCEED();
return;
}
@@ -1277,6 +1296,10 @@
}
TEST_F(GraphicsComposerTransformReadbackTest, ROT_180) {
+ if (!mHasReadbackBuffer) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
mDisplayHeight, mPixelFormat, mDataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
@@ -1293,6 +1316,7 @@
mWriter->validateDisplay();
execute();
if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
GTEST_SUCCEED();
return;
}
diff --git a/media/bufferpool/2.0/Android.bp b/media/bufferpool/2.0/Android.bp
index 405990e..1f8bbdb 100644
--- a/media/bufferpool/2.0/Android.bp
+++ b/media/bufferpool/2.0/Android.bp
@@ -11,12 +11,14 @@
"IAccessor.hal",
"IClientManager.hal",
"IConnection.hal",
+ "IObserver.hal",
],
interfaces: [
"android.hidl.base@1.0",
],
types: [
"Buffer",
+ "BufferInvalidationMessage",
"BufferStatus",
"BufferStatusMessage",
"ResultStatus",
diff --git a/media/bufferpool/2.0/IAccessor.hal b/media/bufferpool/2.0/IAccessor.hal
index ab7c02d..66707fe 100644
--- a/media/bufferpool/2.0/IAccessor.hal
+++ b/media/bufferpool/2.0/IAccessor.hal
@@ -17,6 +17,7 @@
package android.hardware.media.bufferpool@2.0;
import IConnection;
+import IObserver;
/**
* IAccessor creates IConnection which is used from IClientManager in order to
* use functionality of the specified buffer pool.
@@ -49,6 +50,13 @@
* made and kept private. Also part of transaction ID is a sender ID in
* order to prevent fake transactions from other clients. This must be
* verified with an FMQ message from a buffer pool.
+
+ * @param observer The buffer pool event observer from the client.
+ * Observer is provided to ensure FMQ messages are processed even when
+ * client processes are idle. Buffer invalidation caused by
+ * reconfiguration does not call observer. Buffer invalidation caused
+ * by termination of pipeline call observer in order to ensure
+ * invalidation is done after pipeline completion.
*
* @return status The status of the call.
* OK - A connection is made successfully.
@@ -64,7 +72,7 @@
* @return fromFmqDesc FMQ descriptor. The descriptor is used to
* receive buffer invalidation messages from the buffer pool.
*/
- connect()
+ connect(IObserver observer)
generates (ResultStatus status, IConnection connection,
int64_t connectionId,
fmq_sync<BufferStatusMessage> toFmqDesc,
diff --git a/media/bufferpool/2.0/IObserver.hal b/media/bufferpool/2.0/IObserver.hal
new file mode 100644
index 0000000..a998836
--- /dev/null
+++ b/media/bufferpool/2.0/IObserver.hal
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 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 android.hardware.media.bufferpool@2.0;
+
+/**
+ * IObserver listens on notifications from the buffer pool. On receiving
+ * notifications, FMQ messages from the specific buffer pool which are already
+ * in the FMQ are processed.
+ */
+interface IObserver {
+
+ /**
+ * The specific buffer pool sent a message to the client. Calling this
+ * method from the buffer pool enforces a buffer pool client process the
+ * message.
+ *
+ * @param connectionId the connection Id of the specific buffer pool client
+ */
+ oneway onMessage(int64_t connectionId);
+};
diff --git a/media/bufferpool/2.0/types.hal b/media/bufferpool/2.0/types.hal
index 456e4aa..597e7b3 100644
--- a/media/bufferpool/2.0/types.hal
+++ b/media/bufferpool/2.0/types.hal
@@ -65,6 +65,8 @@
TRANSFER_OK = 7,
/** Buffer transaction failure. */
TRANSFER_ERROR = 8,
+ /** Buffer invalidation ack. */
+ INVALIDATION_ACK = 9,
};
/**
@@ -98,6 +100,7 @@
* buffers as soon as possible upon receiving the message.
*/
struct BufferInvalidationMessage {
+ uint32_t messageId;
/**
* Buffers from fromBufferId to toBufferId must be invalidated.
* fromBufferId is inclusive, but toBufferId is not inclusive.
diff --git a/neuralnetworks/1.0/vts/OWNERS b/neuralnetworks/1.0/vts/OWNERS
index 87e322b..b5a8e1f 100644
--- a/neuralnetworks/1.0/vts/OWNERS
+++ b/neuralnetworks/1.0/vts/OWNERS
@@ -2,9 +2,14 @@
butlermichael@google.com
dgross@google.com
jeanluc@google.com
+levp@google.com
miaowang@google.com
mikie@google.com
+mks@google.com
pszczepaniak@google.com
+slavash@google.com
+vddang@google.com
+xusongw@google.com
# VTS team
yim@google.com
diff --git a/neuralnetworks/1.1/vts/OWNERS b/neuralnetworks/1.1/vts/OWNERS
index 87e322b..b5a8e1f 100644
--- a/neuralnetworks/1.1/vts/OWNERS
+++ b/neuralnetworks/1.1/vts/OWNERS
@@ -2,9 +2,14 @@
butlermichael@google.com
dgross@google.com
jeanluc@google.com
+levp@google.com
miaowang@google.com
mikie@google.com
+mks@google.com
pszczepaniak@google.com
+slavash@google.com
+vddang@google.com
+xusongw@google.com
# VTS team
yim@google.com
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 4377131..bed1d5c 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -30,7 +30,7 @@
ARGMAX = 38,
ARGMIN = 39,
PAD_V2 = 40,
- BBOX_TRANSFORM = 41,
+ AXIS_ALIGNED_BBOX_TRANSFORM = 41,
BIDIRECTIONAL_SEQUENCE_LSTM = 42,
BIDIRECTIONAL_SEQUENCE_RNN = 43,
BOX_WITH_NMS_LIMIT = 44,
@@ -76,6 +76,7 @@
TRANSPOSE_CONV_2D = 84,
UNIDIRECTIONAL_SEQUENCE_LSTM = 85,
UNIDIRECTIONAL_SEQUENCE_RNN = 86,
+ ROTATED_BBOX_TRANSFORM = 87,
};
/**
diff --git a/neuralnetworks/1.2/vts/OWNERS b/neuralnetworks/1.2/vts/OWNERS
index 8f25436..b5a8e1f 100644
--- a/neuralnetworks/1.2/vts/OWNERS
+++ b/neuralnetworks/1.2/vts/OWNERS
@@ -8,6 +8,8 @@
mks@google.com
pszczepaniak@google.com
slavash@google.com
+vddang@google.com
+xusongw@google.com
# VTS team
yim@google.com
diff --git a/radio/1.3/Android.bp b/radio/1.3/Android.bp
index 9424a85..6a9b1d0 100644
--- a/radio/1.3/Android.bp
+++ b/radio/1.3/Android.bp
@@ -20,6 +20,7 @@
],
types: [
"AccessNetwork",
+ "DataProfileInfo",
"DataRegStateResult",
"EmergencyNumber",
"EmergencyNumberSource",
diff --git a/radio/1.3/IRadio.hal b/radio/1.3/IRadio.hal
index 2b14488..dde9d71 100644
--- a/radio/1.3/IRadio.hal
+++ b/radio/1.3/IRadio.hal
@@ -16,7 +16,7 @@
package android.hardware.radio@1.3;
-import @1.0::DataProfileInfo;
+import @1.3::DataProfileInfo;
import @1.0::Dial;
import @1.2::DataRequestReason;
import @1.2::IRadio;
@@ -56,13 +56,7 @@
* @param accessNetwork The access network to setup the data call. If the data connection cannot
* be established on the specified access network, the setup request must be failed.
* @param dataProfileInfo Data profile info.
- * @param modemCognitive Indicates that the requested profile has previously been provided via
- * setDataProfile().
* @param roamingAllowed Indicates whether or not data roaming is allowed by the user.
- * @param isRoaming Indicates whether or not the framework has requested this setupDataCall for
- * a roaming network. The 'protocol' parameter in the old RIL API must be filled
- * accordingly based on the roaming condition. Note this is for backward compatibility with
- * the old radio modem. The modem must not use this param for any other reason.
* @param reason The request reason. Must be DataRequestReason.NORMAL or
* DataRequestReason.HANDOVER.
* @param addresses If the reason is DataRequestReason.HANDOVER, this indicates the list of link
@@ -82,8 +76,28 @@
* Note this API is same as 1.2 version except using the 1.3 AccessNetwork as the input param.
*/
oneway setupDataCall_1_3(int32_t serial, AccessNetwork accessNetwork,
- DataProfileInfo dataProfileInfo, bool modemCognitive, bool roamingAllowed,
- bool isRoaming, DataRequestReason reason, vec<string> addresses, vec<string> dnses);
+ DataProfileInfo dataProfileInfo, bool roamingAllowed,
+ DataRequestReason reason, vec<string> addresses, vec<string> dnses);
+
+ /**
+ * Set an apn to initial attach network
+ *
+ * @param serial Serial number of request.
+ * @param dataProfileInfo data profile containing APN settings
+ *
+ * Response callback is IRadioResponse.setInitialAttachApnResponse()
+ */
+ oneway setInitialAttachApn_1_3(int32_t serial, DataProfileInfo dataProfileInfo);
+
+ /**
+ * Send data profiles of the current carrier to the modem.
+ *
+ * @param serial Serial number of request.
+ * @param profiles Array of DataProfile to set.
+ *
+ * Response callback is IRadioResponse.setDataProfileResponse()
+ */
+ oneway setDataProfile_1_3(int32_t serial, vec<DataProfileInfo> profiles);
/**
* Initiate emergency voice call, with zero or more emergency service category(s).
diff --git a/radio/1.3/types.hal b/radio/1.3/types.hal
index 09202a5..a41f4b2 100644
--- a/radio/1.3/types.hal
+++ b/radio/1.3/types.hal
@@ -16,6 +16,11 @@
package android.hardware.radio@1.3;
+import @1.0::ApnAuthType;
+import @1.0::ApnTypes;
+import @1.0::DataProfileId;
+import @1.0::DataProfileInfoType;
+import @1.0::RadioAccessFamily;
import @1.0::RegState;
import @1.2::AccessNetwork;
import @1.2::CellIdentity;
@@ -160,3 +165,71 @@
LteVopsInfo lteVopsInfo; // LTE network capability
} vopsInfo;
};
+
+/**
+ * Overwritten from @1.0::DataProfileInfo in order to deprecate 'mvnoType', 'mvnoMatchData',
+ * 'maxConnsTime', and 'maxConns'. In the future, this must be extended instead of overwritten.
+ * Added 'preferred' and 'persistent' in this version.
+ */
+struct DataProfileInfo {
+ /** id of the data profile */
+ DataProfileId profileId;
+
+ /** The APN name */
+ string apn;
+
+ /**
+ * One of the PDP_type values in TS 27.007 section 10.1.1. For example, "IP", "IPV6", "IPV4V6",
+ * or "PPP".
+ */
+ string protocol;
+
+ /**
+ * one of the PDP_type values in TS 27.007 section 10.1.1 used on roaming network. For example,
+ * "IP", "IPV6", "IPV4V6", or "PPP".
+ */
+ string roamingProtocol;
+
+ /** APN authentication type */
+ ApnAuthType authType;
+
+ /** The username for APN, or empty string */
+ string user;
+
+ /** The password for APN, or empty string */
+ string password;
+
+ /** Data profile technology type */
+ DataProfileInfoType type;
+
+ /**
+ * The required wait time in seconds after a successful UE initiated disconnect of a given PDN
+ * connection before the device can send a new PDN connection request for that given PDN.
+ */
+ int32_t waitTime;
+
+ /** True to enable the profile, false to disable */
+ bool enabled;
+
+ /** Supported APN types bitmap. See ApnTypes for the value of each bit. */
+ bitfield<ApnTypes> supportedApnTypesBitmap;
+
+ /** The bearer bitmap. See RadioAccessFamily for the value of each bit. */
+ bitfield<RadioAccessFamily> bearerBitmap;
+
+ /** Maximum transmission unit (MTU) size in bytes */
+ int32_t mtu;
+
+ /**
+ * True if this data profile was used to bring up the last default (i.e internet) data
+ * connection successfully.
+ */
+ bool preferred;
+
+ /**
+ * If true, modem must persist this data profile and profileId must not be
+ * set to DataProfileId.INVALID. If the same data profile exists, this data profile must
+ * overwrite it.
+ */
+ bool persistent;
+};
diff --git a/sensors/1.0/vts/functional/Android.bp b/sensors/1.0/vts/functional/Android.bp
index 0ea400e..d93e339 100644
--- a/sensors/1.0/vts/functional/Android.bp
+++ b/sensors/1.0/vts/functional/Android.bp
@@ -18,13 +18,13 @@
name: "VtsHalSensorsV1_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
srcs: [
- "GrallocWrapper.cpp",
"VtsHalSensorsV1_0TargetTest.cpp"
],
static_libs: [
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.mapper@2.0",
"android.hardware.sensors@1.0",
+ "VtsHalSensorsTargetTestUtils",
],
}
diff --git a/sensors/1.0/vts/functional/GrallocWrapper.cpp b/sensors/1.0/vts/functional/GrallocWrapper.cpp
deleted file mode 100644
index e422d62..0000000
--- a/sensors/1.0/vts/functional/GrallocWrapper.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2017 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 "GrallocWrapper"
-
-#include "GrallocWrapper.h"
-
-#include <utils/Log.h>
-
-namespace android {
-
-GrallocWrapper::GrallocWrapper() { init(); }
-
-void GrallocWrapper::init() {
- mAllocator = allocator2::IAllocator::getService();
- if (mAllocator == nullptr) {
- ALOGE("Failed to get allocator service");
- }
-
- mMapper = mapper2::IMapper::getService();
- if (mMapper == nullptr) {
- ALOGE("Failed to get mapper service");
- }
- if (mMapper->isRemote()) {
- ALOGE("Mapper is not in passthrough mode");
- }
-}
-
-GrallocWrapper::~GrallocWrapper() {
- for (auto bufferHandle : mClonedBuffers) {
- auto buffer = const_cast<native_handle_t*>(bufferHandle);
- native_handle_close(buffer);
- native_handle_delete(buffer);
- }
- mClonedBuffers.clear();
-
- for (auto bufferHandle : mImportedBuffers) {
- auto buffer = const_cast<native_handle_t*>(bufferHandle);
- if (mMapper->freeBuffer(buffer) != mapper2::Error::NONE) {
- ALOGE("Failed to free buffer %p", buffer);
- }
- }
- mImportedBuffers.clear();
-}
-
-sp<allocator2::IAllocator> GrallocWrapper::getAllocator() const {
- return mAllocator;
-}
-
-std::string GrallocWrapper::dumpDebugInfo() {
- std::string debugInfo;
- mAllocator->dumpDebugInfo(
- [&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
-
- return debugInfo;
-}
-
-const native_handle_t* GrallocWrapper::cloneBuffer(
- const hardware::hidl_handle& rawHandle) {
- const native_handle_t* bufferHandle =
- native_handle_clone(rawHandle.getNativeHandle());
-
- if (bufferHandle) {
- mClonedBuffers.insert(bufferHandle);
- }
- return bufferHandle;
-}
-
-std::vector<const native_handle_t*> GrallocWrapper::allocate(
- const mapper2::BufferDescriptor& descriptor, uint32_t count, bool import,
- uint32_t* outStride) {
- std::vector<const native_handle_t*> bufferHandles;
- bufferHandles.reserve(count);
- mAllocator->allocate(
- descriptor, count,
- [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
- if (mapper2::Error::NONE != tmpError) {
- ALOGE("Failed to allocate buffers");
- }
- if (count != tmpBuffers.size()) {
- ALOGE("Invalid buffer array");
- }
-
- for (uint32_t i = 0; i < count; i++) {
- if (import) {
- bufferHandles.push_back(importBuffer(tmpBuffers[i]));
- } else {
- bufferHandles.push_back(cloneBuffer(tmpBuffers[i]));
- }
- }
-
- if (outStride) {
- *outStride = tmpStride;
- }
- });
-
- return bufferHandles;
-}
-
-const native_handle_t* GrallocWrapper::allocate(
- const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo, bool import,
- uint32_t* outStride) {
- mapper2::BufferDescriptor descriptor = createDescriptor(descriptorInfo);
- ALOGE("QQ");
- auto buffers = allocate(descriptor, 1, import, outStride);
- return buffers[0];
-}
-
-sp<mapper2::IMapper> GrallocWrapper::getMapper() const { return mMapper; }
-
-mapper2::BufferDescriptor GrallocWrapper::createDescriptor(
- const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo) {
- mapper2::BufferDescriptor descriptor;
- mMapper->createDescriptor(
- descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
- if (tmpError != mapper2::Error::NONE) {
- ALOGE("Failed to create descriptor");
- }
- descriptor = tmpDescriptor;
- });
-
- return descriptor;
-}
-
-const native_handle_t* GrallocWrapper::importBuffer(
- const hardware::hidl_handle& rawHandle) {
- const native_handle_t* bufferHandle = nullptr;
- mMapper->importBuffer(
- rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
- if (tmpError != mapper2::Error::NONE) {
- ALOGE("Failed to import buffer %p", rawHandle.getNativeHandle());
- }
- bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
- });
-
- if (bufferHandle) {
- mImportedBuffers.insert(bufferHandle);
- }
-
- return bufferHandle;
-}
-
-void GrallocWrapper::freeBuffer(const native_handle_t* bufferHandle) {
- auto buffer = const_cast<native_handle_t*>(bufferHandle);
-
- if (mImportedBuffers.erase(bufferHandle)) {
- mapper2::Error error = mMapper->freeBuffer(buffer);
- if (error != mapper2::Error::NONE) {
- ALOGE("Failed to free %p", buffer);
- }
- } else {
- mClonedBuffers.erase(bufferHandle);
- native_handle_close(buffer);
- native_handle_delete(buffer);
- }
-}
-
-void* GrallocWrapper::lock(const native_handle_t* bufferHandle,
- uint64_t cpuUsage,
- const mapper2::IMapper::Rect& accessRegion,
- int acquireFence) {
- auto buffer = const_cast<native_handle_t*>(bufferHandle);
-
- NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
- hardware::hidl_handle acquireFenceHandle;
- if (acquireFence >= 0) {
- auto h = native_handle_init(acquireFenceStorage, 1, 0);
- h->data[0] = acquireFence;
- acquireFenceHandle = h;
- }
-
- void* data = nullptr;
- mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpData) {
- if (tmpError != mapper2::Error::NONE) {
- ALOGE("Failed to lock buffer %p", buffer);
- }
- data = tmpData;
- });
-
- if (acquireFence >= 0) {
- close(acquireFence);
- }
-
- return data;
-}
-
-int GrallocWrapper::unlock(const native_handle_t* bufferHandle) {
- auto buffer = const_cast<native_handle_t*>(bufferHandle);
-
- int releaseFence = -1;
- mMapper->unlock(buffer, [&](const auto& tmpError,
- const auto& tmpReleaseFence) {
- if (tmpError != mapper2::Error::NONE) {
- ALOGE("Failed to unlock buffer %p", buffer);
- }
-
- auto fenceHandle = tmpReleaseFence.getNativeHandle();
- if (fenceHandle) {
- if (fenceHandle->numInts != 0) {
- ALOGE("Invalid fence handle %p", fenceHandle);
- }
- if (fenceHandle->numFds == 1) {
- releaseFence = dup(fenceHandle->data[0]);
- if (releaseFence < 0){
- ALOGE("Failed to dup fence fd");
- }
- } else {
- if (fenceHandle->numFds != 0) {
- ALOGE("Invalid fence handle %p", fenceHandle);
- }
- }
- }
- });
-
- return releaseFence;
-}
-
-} // namespace android
diff --git a/sensors/1.0/vts/functional/GrallocWrapper.h b/sensors/1.0/vts/functional/GrallocWrapper.h
deleted file mode 100644
index e506fe1..0000000
--- a/sensors/1.0/vts/functional/GrallocWrapper.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2017 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 GRALLO_WRAPPER_H_
-#define GRALLO_WRAPPER_H_
-
-#include <unordered_set>
-
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
-
-namespace allocator2 = ::android::hardware::graphics::allocator::V2_0;
-namespace mapper2 = ::android::hardware::graphics::mapper::V2_0;
-
-namespace android {
-
-// Modified from hardware/interfaces/graphics/mapper/2.0/vts/functional/
-class GrallocWrapper {
- public:
- GrallocWrapper();
- ~GrallocWrapper();
-
- sp<allocator2::IAllocator> getAllocator() const;
- sp<mapper2::IMapper> getMapper() const;
-
- std::string dumpDebugInfo();
-
- // When import is false, this simply calls IAllocator::allocate. When import
- // is true, the returned buffers are also imported into the mapper.
- //
- // Either case, the returned buffers must be freed with freeBuffer.
- std::vector<const native_handle_t*> allocate(
- const mapper2::BufferDescriptor& descriptor, uint32_t count, bool import = true,
- uint32_t* outStride = nullptr);
- const native_handle_t* allocate(
- const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo, bool import = true,
- uint32_t* outStride = nullptr);
-
- mapper2::BufferDescriptor createDescriptor(
- const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo);
-
- const native_handle_t* importBuffer(const hardware::hidl_handle& rawHandle);
- void freeBuffer(const native_handle_t* bufferHandle);
-
- // We use fd instead of hardware::hidl_handle in these functions to pass fences
- // in and out of the mapper. The ownership of the fd is always transferred
- // with each of these functions.
- void* lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
- const mapper2::IMapper::Rect& accessRegion, int acquireFence);
-
- int unlock(const native_handle_t* bufferHandle);
-
- private:
- void init();
- const native_handle_t* cloneBuffer(const hardware::hidl_handle& rawHandle);
-
- sp<allocator2::IAllocator> mAllocator;
- sp<mapper2::IMapper> mMapper;
-
- // Keep track of all cloned and imported handles. When a test fails with
- // ASSERT_*, the destructor will free the handles for the test.
- std::unordered_set<const native_handle_t*> mClonedBuffers;
- std::unordered_set<const native_handle_t*> mImportedBuffers;
-};
-
-} // namespace android
-#endif // GRALLO_WRAPPER_H_
diff --git a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
index c18eedd..d59dd97 100644
--- a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
+++ b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
@@ -15,6 +15,9 @@
*/
#define LOG_TAG "sensors_hidl_hal_test"
+
+#include "sensors-vts-utils/GrallocWrapper.h"
+
#include <VtsHalHidlTargetTestBase.h>
#include <VtsHalHidlTargetTestEnvBase.h>
#include <android-base/logging.h>
@@ -24,7 +27,6 @@
#include <hardware/sensors.h> // for sensor type strings
#include <log/log.h>
#include <utils/SystemClock.h>
-#include "GrallocWrapper.h"
#include <algorithm>
#include <cinttypes>
diff --git a/sensors/common/vts/OWNERS b/sensors/common/vts/OWNERS
new file mode 100644
index 0000000..759d87b
--- /dev/null
+++ b/sensors/common/vts/OWNERS
@@ -0,0 +1,7 @@
+# Sensors team
+bduddie@google.com
+bstack@google.com
+
+# VTS team
+trong@google.com
+yim@google.com
diff --git a/sensors/common/vts/utils/Android.bp b/sensors/common/vts/utils/Android.bp
new file mode 100644
index 0000000..affc56d
--- /dev/null
+++ b/sensors/common/vts/utils/Android.bp
@@ -0,0 +1,33 @@
+//
+// Copyright (C) 2018 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.
+//
+
+cc_library_static {
+ name: "VtsHalSensorsTargetTestUtils",
+ srcs: [
+ "GrallocWrapper.cpp",
+ ],
+ export_include_dirs: [
+ "include",
+ ],
+ local_include_dirs: [
+ "include/sensors-vts-utils",
+ ],
+ static_libs: [
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.mapper@2.0",
+ ],
+}
+
diff --git a/sensors/common/vts/utils/GrallocWrapper.cpp b/sensors/common/vts/utils/GrallocWrapper.cpp
new file mode 100644
index 0000000..7bed16d
--- /dev/null
+++ b/sensors/common/vts/utils/GrallocWrapper.cpp
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2017 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 "GrallocWrapper"
+
+#include "GrallocWrapper.h"
+
+#include <utils/Log.h>
+
+namespace android {
+
+GrallocWrapper::GrallocWrapper() {
+ init();
+}
+
+void GrallocWrapper::init() {
+ mAllocator = allocator2::IAllocator::getService();
+ if (mAllocator == nullptr) {
+ ALOGE("Failed to get allocator service");
+ }
+
+ mMapper = mapper2::IMapper::getService();
+ if (mMapper == nullptr) {
+ ALOGE("Failed to get mapper service");
+ }
+ if (mMapper->isRemote()) {
+ ALOGE("Mapper is not in passthrough mode");
+ }
+}
+
+GrallocWrapper::~GrallocWrapper() {
+ for (auto bufferHandle : mClonedBuffers) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ native_handle_close(buffer);
+ native_handle_delete(buffer);
+ }
+ mClonedBuffers.clear();
+
+ for (auto bufferHandle : mImportedBuffers) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ if (mMapper->freeBuffer(buffer) != mapper2::Error::NONE) {
+ ALOGE("Failed to free buffer %p", buffer);
+ }
+ }
+ mImportedBuffers.clear();
+}
+
+sp<allocator2::IAllocator> GrallocWrapper::getAllocator() const {
+ return mAllocator;
+}
+
+std::string GrallocWrapper::dumpDebugInfo() {
+ std::string debugInfo;
+ mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
+
+ return debugInfo;
+}
+
+const native_handle_t* GrallocWrapper::cloneBuffer(const hardware::hidl_handle& rawHandle) {
+ const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
+
+ if (bufferHandle) {
+ mClonedBuffers.insert(bufferHandle);
+ }
+ return bufferHandle;
+}
+
+std::vector<const native_handle_t*> GrallocWrapper::allocate(
+ const mapper2::BufferDescriptor& descriptor, uint32_t count, bool import, uint32_t* outStride) {
+ std::vector<const native_handle_t*> bufferHandles;
+ bufferHandles.reserve(count);
+ mAllocator->allocate(descriptor, count,
+ [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
+ if (mapper2::Error::NONE != tmpError) {
+ ALOGE("Failed to allocate buffers");
+ }
+ if (count != tmpBuffers.size()) {
+ ALOGE("Invalid buffer array");
+ }
+
+ for (uint32_t i = 0; i < count; i++) {
+ if (import) {
+ bufferHandles.push_back(importBuffer(tmpBuffers[i]));
+ } else {
+ bufferHandles.push_back(cloneBuffer(tmpBuffers[i]));
+ }
+ }
+
+ if (outStride) {
+ *outStride = tmpStride;
+ }
+ });
+
+ return bufferHandles;
+}
+
+const native_handle_t* GrallocWrapper::allocate(
+ const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo, bool import,
+ uint32_t* outStride) {
+ mapper2::BufferDescriptor descriptor = createDescriptor(descriptorInfo);
+ auto buffers = allocate(descriptor, 1, import, outStride);
+ return buffers[0];
+}
+
+sp<mapper2::IMapper> GrallocWrapper::getMapper() const {
+ return mMapper;
+}
+
+mapper2::BufferDescriptor GrallocWrapper::createDescriptor(
+ const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo) {
+ mapper2::BufferDescriptor descriptor;
+ mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
+ if (tmpError != mapper2::Error::NONE) {
+ ALOGE("Failed to create descriptor");
+ }
+ descriptor = tmpDescriptor;
+ });
+
+ return descriptor;
+}
+
+const native_handle_t* GrallocWrapper::importBuffer(const hardware::hidl_handle& rawHandle) {
+ const native_handle_t* bufferHandle = nullptr;
+ mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
+ if (tmpError != mapper2::Error::NONE) {
+ ALOGE("Failed to import buffer %p", rawHandle.getNativeHandle());
+ }
+ bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
+ });
+
+ if (bufferHandle) {
+ mImportedBuffers.insert(bufferHandle);
+ }
+
+ return bufferHandle;
+}
+
+void GrallocWrapper::freeBuffer(const native_handle_t* bufferHandle) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ if (mImportedBuffers.erase(bufferHandle)) {
+ mapper2::Error error = mMapper->freeBuffer(buffer);
+ if (error != mapper2::Error::NONE) {
+ ALOGE("Failed to free %p", buffer);
+ }
+ } else {
+ mClonedBuffers.erase(bufferHandle);
+ native_handle_close(buffer);
+ native_handle_delete(buffer);
+ }
+}
+
+void* GrallocWrapper::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
+ const mapper2::IMapper::Rect& accessRegion, int acquireFence) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+ hardware::hidl_handle acquireFenceHandle;
+ if (acquireFence >= 0) {
+ auto h = native_handle_init(acquireFenceStorage, 1, 0);
+ h->data[0] = acquireFence;
+ acquireFenceHandle = h;
+ }
+
+ void* data = nullptr;
+ mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpData) {
+ if (tmpError != mapper2::Error::NONE) {
+ ALOGE("Failed to lock buffer %p", buffer);
+ }
+ data = tmpData;
+ });
+
+ if (acquireFence >= 0) {
+ close(acquireFence);
+ }
+
+ return data;
+}
+
+int GrallocWrapper::unlock(const native_handle_t* bufferHandle) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ int releaseFence = -1;
+ mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
+ if (tmpError != mapper2::Error::NONE) {
+ ALOGE("Failed to unlock buffer %p", buffer);
+ }
+
+ auto fenceHandle = tmpReleaseFence.getNativeHandle();
+ if (fenceHandle) {
+ if (fenceHandle->numInts != 0) {
+ ALOGE("Invalid fence handle %p", fenceHandle);
+ }
+ if (fenceHandle->numFds == 1) {
+ releaseFence = dup(fenceHandle->data[0]);
+ if (releaseFence < 0) {
+ ALOGE("Failed to dup fence fd");
+ }
+ } else {
+ if (fenceHandle->numFds != 0) {
+ ALOGE("Invalid fence handle %p", fenceHandle);
+ }
+ }
+ }
+ });
+
+ return releaseFence;
+}
+
+} // namespace android
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/GrallocWrapper.h b/sensors/common/vts/utils/include/sensors-vts-utils/GrallocWrapper.h
new file mode 100644
index 0000000..3bd73c3
--- /dev/null
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/GrallocWrapper.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2017 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 GRALLO_WRAPPER_H_
+#define GRALLO_WRAPPER_H_
+
+#include <unordered_set>
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+
+namespace allocator2 = ::android::hardware::graphics::allocator::V2_0;
+namespace mapper2 = ::android::hardware::graphics::mapper::V2_0;
+
+namespace android {
+
+// Modified from hardware/interfaces/graphics/mapper/2.0/vts/functional/
+class GrallocWrapper {
+ public:
+ GrallocWrapper();
+ ~GrallocWrapper();
+
+ sp<allocator2::IAllocator> getAllocator() const;
+ sp<mapper2::IMapper> getMapper() const;
+
+ std::string dumpDebugInfo();
+
+ // When import is false, this simply calls IAllocator::allocate. When import
+ // is true, the returned buffers are also imported into the mapper.
+ //
+ // Either case, the returned buffers must be freed with freeBuffer.
+ std::vector<const native_handle_t*> allocate(const mapper2::BufferDescriptor& descriptor,
+ uint32_t count, bool import = true,
+ uint32_t* outStride = nullptr);
+ const native_handle_t* allocate(const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo,
+ bool import = true, uint32_t* outStride = nullptr);
+
+ mapper2::BufferDescriptor createDescriptor(
+ const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo);
+
+ const native_handle_t* importBuffer(const hardware::hidl_handle& rawHandle);
+ void freeBuffer(const native_handle_t* bufferHandle);
+
+ // We use fd instead of hardware::hidl_handle in these functions to pass fences
+ // in and out of the mapper. The ownership of the fd is always transferred
+ // with each of these functions.
+ void* lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
+ const mapper2::IMapper::Rect& accessRegion, int acquireFence);
+
+ int unlock(const native_handle_t* bufferHandle);
+
+ private:
+ void init();
+ const native_handle_t* cloneBuffer(const hardware::hidl_handle& rawHandle);
+
+ sp<allocator2::IAllocator> mAllocator;
+ sp<mapper2::IMapper> mMapper;
+
+ // Keep track of all cloned and imported handles. When a test fails with
+ // ASSERT_*, the destructor will free the handles for the test.
+ std::unordered_set<const native_handle_t*> mClonedBuffers;
+ std::unordered_set<const native_handle_t*> mImportedBuffers;
+};
+
+} // namespace android
+#endif // GRALLO_WRAPPER_H_
diff --git a/tests/foo/1.0/IFoo.hal b/tests/foo/1.0/IFoo.hal
index 4a930a2..9642e2a 100644
--- a/tests/foo/1.0/IFoo.hal
+++ b/tests/foo/1.0/IFoo.hal
@@ -103,7 +103,6 @@
union U {
int8_t number;
int8_t[1][2] multidimArray;
- pointer p;
Fumble anotherStruct;
bitfield<BitField> bf;
} u;