]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android/platform-hardware-interfaces.git/commitdiff
Update for Soong java makefiles.
authorSteven Moreland <smoreland@google.com>
Wed, 11 Oct 2017 16:23:54 +0000 (16:23 +0000)
committerandroid-build-merger <android-build-merger@google.com>
Wed, 11 Oct 2017 16:23:54 +0000 (16:23 +0000)
am: c3e80fa01e

Change-Id: Ia8835f9c95bd98a96f5fd3aff11191e7d3726fb9

226 files changed:
CleanSpec.mk
audio/2.0/config/audio_policy_configuration.xsd
audio/2.0/vts/functional/Android.bp
audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
audio/Android.bp
audio/common/test/utility/Android.bp [new file with mode: 0644]
audio/common/test/utility/include/utility/AssertOk.h [moved from audio/2.0/vts/functional/utility/AssertOk.h with 55% similarity]
audio/common/test/utility/include/utility/Documentation.h [new file with mode: 0644]
audio/common/test/utility/include/utility/EnvironmentTearDown.h [new file with mode: 0644]
audio/common/test/utility/include/utility/PrettyPrintAudioTypes.h [moved from audio/2.0/vts/functional/utility/PrettyPrintAudioTypes.h with 65% similarity]
audio/common/test/utility/include/utility/ReturnIn.h [moved from audio/2.0/vts/functional/utility/ReturnIn.h with 75% similarity]
audio/common/test/utility/include/utility/ValidateXml.h [moved from audio/2.0/vts/functional/utility/ValidateXml.h with 68% similarity]
audio/common/test/utility/src/ValidateXml.cpp [moved from audio/2.0/vts/functional/utility/ValidateXml.cpp with 97% similarity]
automotive/Android.bp
automotive/evs/1.0/default/Android.bp [deleted file]
automotive/evs/1.0/default/Android.mk [new file with mode: 0644]
automotive/evs/1.0/default/android.hardware.automotive.evs@1.0-service.rc
automotive/evs/1.0/vts/functional/FormatConvert.cpp
automotive/vehicle/2.0/default/Android.mk
automotive/vehicle/2.0/default/common/include/vhal_v2_0/RecurrentTimer.h
automotive/vehicle/2.0/default/common/src/VehicleUtils.cpp
automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
automotive/vehicle/2.0/default/impl/vhal_v2_0/PipeComm.cpp
automotive/vehicle/2.1/Android.mk
automotive/vehicle/2.1/default/Android.mk
automotive/vehicle/2.1/default/impl/vhal_v2_1/EmulatedVehicleHal.cpp
automotive/vehicle/2.1/types.hal
broadcastradio/1.0/default/Android.bp [new file with mode: 0644]
broadcastradio/1.0/default/Android.mk [deleted file]
broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
broadcastradio/1.1/Android.mk [deleted file]
broadcastradio/1.1/ITuner.hal
broadcastradio/1.1/ITunerCallback.hal
broadcastradio/1.1/default/Android.bp [new file with mode: 0644]
broadcastradio/1.1/default/Android.mk [deleted file]
broadcastradio/1.1/default/Tuner.cpp
broadcastradio/1.1/default/Tuner.h
broadcastradio/1.1/types.hal
broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
broadcastradio/Android.bp
camera/common/1.0/default/Android.bp
camera/common/1.0/default/CameraParameters.cpp [moved from camera/provider/2.4/vts/functional/CameraParameters.cpp with 99% similarity]
camera/common/1.0/default/include/CameraParameters.h [moved from camera/provider/2.4/vts/functional/CameraParameters.h with 99% similarity]
camera/common/1.0/default/include/HandleImporter.h
camera/device/3.2/default/CameraDeviceSession.cpp
camera/device/3.2/default/CameraDeviceSession.h
camera/provider/2.4/default/Android.bp
camera/provider/2.4/vts/functional/Android.bp
camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
compatibility_matrix.26.xml [moved from compatibility_matrix.xml with 100% similarity]
compatibility_matrix.current.xml [new file with mode: 0644]
compatibility_matrix.legacy.xml [new file with mode: 0644]
configstore/1.0/default/android.hardware.configstore@1.0-service.rc [deleted file]
configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp
configstore/1.1/Android.bp [new file with mode: 0644]
configstore/1.1/Android.mk [new file with mode: 0644]
configstore/1.1/ISurfaceFlingerConfigs.hal [new file with mode: 0644]
configstore/1.1/default/Android.mk [moved from configstore/1.0/default/Android.mk with 75% similarity]
configstore/1.1/default/SurfaceFlingerConfigs.cpp [moved from configstore/1.0/default/SurfaceFlingerConfigs.cpp with 70% similarity]
configstore/1.1/default/SurfaceFlingerConfigs.h [moved from configstore/1.0/default/SurfaceFlingerConfigs.h with 59% similarity]
configstore/1.1/default/android.hardware.configstore@1.1-service.rc [new file with mode: 0644]
configstore/1.1/default/service.cpp [moved from configstore/1.0/default/service.cpp with 76% similarity]
configstore/1.1/default/surfaceflinger.mk [moved from configstore/1.0/default/surfaceflinger.mk with 100% similarity]
configstore/1.1/vts/functional/Android.bp [new file with mode: 0644]
configstore/1.1/vts/functional/VtsHalConfigstoreV1_1TargetTest.cpp [new file with mode: 0644]
configstore/Android.bp
contexthub/1.0/default/Android.bp
contexthub/1.0/default/Android.mk [deleted file]
current.txt
drm/1.0/vts/functional/drm_hal_clearkey_test.cpp
drm/1.0/vts/functional/drm_hal_vendor_test.cpp
dumpstate/1.0/IDumpstateDevice.hal
dumpstate/1.0/default/DumpstateDevice.cpp
dumpstate/1.0/vts/functional/Android.bp [new file with mode: 0644]
dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp [new file with mode: 0644]
dumpstate/Android.bp
gnss/1.0/default/android.hardware.gnss@1.0-service.rc
gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
graphics/allocator/2.0/default/Gralloc1Allocator.cpp
graphics/allocator/2.0/default/service.cpp
graphics/composer/2.1/default/ComposerClient.cpp
graphics/composer/2.1/default/ComposerClient.h
graphics/composer/2.1/vts/functional/Android.bp
graphics/composer/2.1/vts/functional/GraphicsComposerCallback.cpp [new file with mode: 0644]
graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h [new file with mode: 0644]
graphics/composer/2.1/vts/functional/TestCommandReader.cpp [new file with mode: 0644]
graphics/composer/2.1/vts/functional/TestCommandReader.h [new file with mode: 0644]
graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp
graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.h
graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
graphics/mapper/2.0/default/GrallocMapper.h
ir/1.0/vts/functional/VtsHalIrV1_0TargetTest.cpp
keymaster/3.0/default/Android.mk
keymaster/3.0/default/KeymasterDevice.cpp
keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioEncTest.cpp
media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp
media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.h
media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
media/omx/1.0/vts/functional/common/media_hidl_test_common.h
media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp
media/omx/1.0/vts/functional/master/VtsHalMediaOmxV1_0TargetMasterTest.cpp
media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
media/omx/1.0/vts/functional/video/media_video_hidl_test_common.cpp
media/omx/1.0/vts/functional/video/media_video_hidl_test_common.h
oemlock/1.0/Android.bp [new file with mode: 0644]
oemlock/1.0/Android.mk [new file with mode: 0644]
oemlock/1.0/IOemLock.hal [new file with mode: 0644]
oemlock/1.0/types.hal [new file with mode: 0644]
oemlock/1.0/vts/functional/Android.bp [new file with mode: 0644]
oemlock/1.0/vts/functional/VtsHalOemLockV1_0TargetTest.cpp [new file with mode: 0644]
oemlock/Android.bp [new file with mode: 0644]
power/1.1/Android.bp [new file with mode: 0644]
power/1.1/Android.mk [new file with mode: 0644]
power/1.1/IPower.hal [new file with mode: 0644]
power/1.1/default/Android.bp [new file with mode: 0644]
power/1.1/default/Power.cpp [new file with mode: 0644]
power/1.1/default/Power.h [new file with mode: 0644]
power/1.1/default/android.hardware.power@1.1-service.rc [new file with mode: 0644]
power/1.1/default/service.cpp [new file with mode: 0644]
power/1.1/types.hal [new file with mode: 0644]
power/1.1/vts/functional/Android.bp [new file with mode: 0644]
power/1.1/vts/functional/VtsHalPowerV1_1TargetTest.cpp [new file with mode: 0644]
power/Android.bp
radio/1.0/IRadioResponse.hal
radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp
radio/1.0/vts/functional/radio_hidl_hal_data.cpp
radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
radio/1.0/vts/functional/radio_hidl_hal_test.cpp
radio/1.0/vts/functional/radio_hidl_hal_voice.cpp
radio/1.0/vts/functional/sap_hidl_hal_test.cpp
radio/1.1/types.hal
radio/1.1/vts/functional/Android.bp
radio/1.1/vts/functional/radio_hidl_hal_api.cpp
radio/1.1/vts/functional/radio_hidl_hal_test.cpp
radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
radio/1.1/vts/functional/radio_response.cpp
renderscript/1.0/vts/functional/Android.bp
tetheroffload/Android.bp
tetheroffload/config/1.0/vts/functional/Android.bp [new file with mode: 0644]
tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp [new file with mode: 0644]
tetheroffload/control/1.0/vts/functional/Android.bp [new file with mode: 0644]
tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp [new file with mode: 0644]
thermal/1.0/vts/functional/VtsHalThermalV1_0TargetTest.cpp
usb/1.1/Android.bp [new file with mode: 0644]
usb/1.1/Android.mk [new file with mode: 0644]
usb/1.1/IUsb.hal [new file with mode: 0644]
usb/1.1/IUsbCallback.hal [new file with mode: 0644]
usb/1.1/types.hal [new file with mode: 0644]
usb/1.1/vts/functional/Android.bp [new file with mode: 0644]
usb/1.1/vts/functional/VtsHalUsbV1_1TargetTest.cpp [new file with mode: 0644]
usb/Android.bp
vibrator/1.1/Android.bp [new file with mode: 0644]
vibrator/1.1/Android.mk [new file with mode: 0644]
vibrator/1.1/IVibrator.hal [new file with mode: 0644]
vibrator/1.1/types.hal [new file with mode: 0644]
vibrator/1.1/vts/functional/Android.bp [new file with mode: 0644]
vibrator/1.1/vts/functional/VtsHalVibratorV1_1TargetTest.cpp [new file with mode: 0644]
vibrator/Android.bp
weaver/1.0/Android.bp [new file with mode: 0644]
weaver/1.0/Android.mk [new file with mode: 0644]
weaver/1.0/IWeaver.hal [new file with mode: 0644]
weaver/1.0/types.hal [new file with mode: 0644]
weaver/1.0/vts/functional/Android.bp [new file with mode: 0644]
weaver/1.0/vts/functional/VtsHalWeaverV1_0TargetTest.cpp [new file with mode: 0644]
weaver/Android.bp [new file with mode: 0644]
wifi/1.0/vts/functional/Android.bp
wifi/1.0/vts/functional/VtsHalWifiV1_0TargetTest.cpp
wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
wifi/1.0/vts/functional/wifi_hidl_test_utils.h
wifi/1.1/Android.bp [new file with mode: 0644]
wifi/1.1/Android.mk [new file with mode: 0644]
wifi/1.1/IWifi.hal [new file with mode: 0644]
wifi/1.1/IWifiChip.hal [new file with mode: 0644]
wifi/1.1/default/Android.mk [moved from wifi/1.0/default/Android.mk with 96% similarity]
wifi/1.1/default/THREADING.README [moved from wifi/1.0/default/THREADING.README with 100% similarity]
wifi/1.1/default/android.hardware.wifi@1.0-service.rc [moved from wifi/1.0/default/android.hardware.wifi@1.0-service.rc with 100% similarity]
wifi/1.1/default/hidl_callback_util.h [moved from wifi/1.0/default/hidl_callback_util.h with 98% similarity]
wifi/1.1/default/hidl_return_util.h [moved from wifi/1.0/default/hidl_return_util.h with 97% similarity]
wifi/1.1/default/hidl_struct_util.cpp [moved from wifi/1.0/default/hidl_struct_util.cpp with 96% similarity]
wifi/1.1/default/hidl_struct_util.h [moved from wifi/1.0/default/hidl_struct_util.h with 92% similarity]
wifi/1.1/default/hidl_sync_util.cpp [moved from wifi/1.0/default/hidl_sync_util.cpp with 96% similarity]
wifi/1.1/default/hidl_sync_util.h [moved from wifi/1.0/default/hidl_sync_util.h with 96% similarity]
wifi/1.1/default/service.cpp [moved from wifi/1.0/default/service.cpp with 88% similarity]
wifi/1.1/default/wifi.cpp [moved from wifi/1.0/default/wifi.cpp with 97% similarity]
wifi/1.1/default/wifi.h [moved from wifi/1.0/default/wifi.h with 94% similarity]
wifi/1.1/default/wifi_ap_iface.cpp [moved from wifi/1.0/default/wifi_ap_iface.cpp with 98% similarity]
wifi/1.1/default/wifi_ap_iface.h [moved from wifi/1.0/default/wifi_ap_iface.h with 94% similarity]
wifi/1.1/default/wifi_chip.cpp [moved from wifi/1.0/default/wifi_chip.cpp with 95% similarity]
wifi/1.1/default/wifi_chip.h [moved from wifi/1.0/default/wifi_chip.h with 94% similarity]
wifi/1.1/default/wifi_feature_flags.h [moved from wifi/1.0/default/wifi_feature_flags.h with 96% similarity]
wifi/1.1/default/wifi_legacy_hal.cpp [moved from wifi/1.0/default/wifi_legacy_hal.cpp with 98% similarity]
wifi/1.1/default/wifi_legacy_hal.h [moved from wifi/1.0/default/wifi_legacy_hal.h with 98% similarity]
wifi/1.1/default/wifi_legacy_hal_stubs.cpp [moved from wifi/1.0/default/wifi_legacy_hal_stubs.cpp with 97% similarity]
wifi/1.1/default/wifi_legacy_hal_stubs.h [moved from wifi/1.0/default/wifi_legacy_hal_stubs.h with 96% similarity]
wifi/1.1/default/wifi_mode_controller.cpp [moved from wifi/1.0/default/wifi_mode_controller.cpp with 98% similarity]
wifi/1.1/default/wifi_mode_controller.h [moved from wifi/1.0/default/wifi_mode_controller.h with 95% similarity]
wifi/1.1/default/wifi_nan_iface.cpp [moved from wifi/1.0/default/wifi_nan_iface.cpp with 97% similarity]
wifi/1.1/default/wifi_nan_iface.h [moved from wifi/1.0/default/wifi_nan_iface.h with 97% similarity]
wifi/1.1/default/wifi_p2p_iface.cpp [moved from wifi/1.0/default/wifi_p2p_iface.cpp with 98% similarity]
wifi/1.1/default/wifi_p2p_iface.h [moved from wifi/1.0/default/wifi_p2p_iface.h with 92% similarity]
wifi/1.1/default/wifi_rtt_controller.cpp [moved from wifi/1.0/default/wifi_rtt_controller.cpp with 99% similarity]
wifi/1.1/default/wifi_rtt_controller.h [moved from wifi/1.0/default/wifi_rtt_controller.h with 97% similarity]
wifi/1.1/default/wifi_sta_iface.cpp [moved from wifi/1.0/default/wifi_sta_iface.cpp with 99% similarity]
wifi/1.1/default/wifi_sta_iface.h [moved from wifi/1.0/default/wifi_sta_iface.h with 98% similarity]
wifi/1.1/default/wifi_status_util.cpp [moved from wifi/1.0/default/wifi_status_util.cpp with 98% similarity]
wifi/1.1/default/wifi_status_util.h [moved from wifi/1.0/default/wifi_status_util.h with 94% similarity]
wifi/1.1/vts/functional/Android.bp [new file with mode: 0644]
wifi/1.1/vts/functional/VtsHalWifiV1_1TargetTest.cpp [new file with mode: 0644]
wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp [new file with mode: 0644]
wifi/Android.bp
wifi/offload/1.0/Android.bp [new file with mode: 0644]
wifi/offload/1.0/IOffload.hal [new file with mode: 0644]
wifi/offload/1.0/IOffloadCallback.hal [new file with mode: 0644]
wifi/offload/1.0/types.hal [new file with mode: 0644]
wifi/offload/1.0/vts/functional/Android.bp [new file with mode: 0644]
wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp [new file with mode: 0644]
wifi/offload/1.0/vts/functional/hidl_call_util.h [new file with mode: 0644]
wifi/supplicant/1.0/vts/functional/Android.mk
wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp
wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp

index c55763568f6c92a6aa8589cc99c002c793f20ec3..01b5e7b7f9692ed0803c1261f7c048f812156ac9 100644 (file)
@@ -54,3 +54,5 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/android.hardware.bl
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/init/android.hardware.bluetooth*)
 $(call add-clean-step, rm -rf $(OUT)/soong/.intermediates/)
 $(call add-clean-step, rm -rf $(OUT_DIR)/soong/.intermediates/hardware/interfaces/)
+$(call add-clean-step, rm -rf $(OUT_DIR)/soong/.intermediates/hardware/interfaces/)
+$(call add-clean-step, find $(PRODUCT_OUT)/system $(PRODUCT_OUT)/vendor -type f -name "android\.hardware\.configstore*" -print0 | xargs -0 rm -f)
\ No newline at end of file
index 48b9a9b910d6ddbdf9e2e02186334d316262e102..c94da80bfa74c3da02b44f8c427200efad3312ef 100644 (file)
                 <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: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>
         <xs:attribute name="samplingRates" type="samplingRates" use="required"/>
         <xs:attribute name="channelMasks" type="channelMask" use="required"/>
     </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"/>
                 </xs:complexType>
                 <xs:unique name="devicePortProfileUniqueness">
                     <xs:selector xpath="profile"/>
                     <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>
index d72fb2cd16d08d571c7096083dcbb2c6baae5096..b289709fdac680b31a1d677c37803e02ed312e6d 100644 (file)
@@ -18,8 +18,7 @@ cc_test {
     name: "VtsHalAudioV2_0TargetTest",
     defaults: ["hidl_defaults"],
     srcs: ["AudioPrimaryHidlHalTest.cpp",
-           "ValidateAudioConfiguration.cpp",
-           "utility/ValidateXml.cpp"],
+           "ValidateAudioConfiguration.cpp"],
     shared_libs: [
         "libbase",
         "liblog",
@@ -31,7 +30,10 @@ cc_test {
         "android.hardware.audio@2.0",
         "android.hardware.audio.common@2.0",
     ],
-    static_libs: ["VtsHalHidlTargetTestBase"],
+    static_libs: [
+        "VtsHalHidlTargetTestBase",
+        "android.hardware.audio.common.test.utility",
+    ],
     cflags: [
         "-O0",
         "-g",
index 90fec018ef21a772789f36ae7851ec7bb5f007d6..eec2b10d847f10c846a503a3934d2616b62bc870 100644 (file)
@@ -21,9 +21,7 @@
 #include <cstddef>
 #include <cstdio>
 #include <limits>
-#include <list>
 #include <string>
-#include <type_traits>
 #include <vector>
 
 #include <VtsHalHidlTargetTestBase.h>
@@ -37,6 +35,8 @@
 #include <android/hardware/audio/common/2.0/types.h>
 
 #include "utility/AssertOk.h"
+#include "utility/Documentation.h"
+#include "utility/EnvironmentTearDown.h"
 #include "utility/PrettyPrintAudioTypes.h"
 #include "utility/ReturnIn.h"
 
@@ -59,8 +59,7 @@ using ::android::hardware::audio::V2_0::IDevicesFactory;
 using ::android::hardware::audio::V2_0::IStream;
 using ::android::hardware::audio::V2_0::IStreamIn;
 using ::android::hardware::audio::V2_0::TimeSpec;
-using ReadParameters =
-    ::android::hardware::audio::V2_0::IStreamIn::ReadParameters;
+using ReadParameters = ::android::hardware::audio::V2_0::IStreamIn::ReadParameters;
 using ReadStatus = ::android::hardware::audio::V2_0::IStreamIn::ReadStatus;
 using ::android::hardware::audio::V2_0::IStreamOut;
 using ::android::hardware::audio::V2_0::IStreamOutCallback;
@@ -81,61 +80,8 @@ using ::android::hardware::audio::common::V2_0::AudioOutputFlag;
 using ::android::hardware::audio::common::V2_0::AudioSource;
 using ::android::hardware::audio::common::V2_0::ThreadInfo;
 
-using utility::returnIn;
+using namespace ::android::hardware::audio::common::test::utility;
 
-const char* getTestName() {
-    return ::testing::UnitTest::GetInstance()->current_test_info()->name();
-}
-
-namespace doc {
-/** Document the current test case.
- * Eg: calling `doc::test("Dump the state of the hal")` in the "debugDump" test
- * will output:
- *   <testcase name="debugDump" status="run" time="6"
- *             classname="AudioPrimaryHidlTest"
-               description="Dump the state of the hal." />
- * see
- https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#logging-additional-information
- */
-void test(const std::string& testCaseDocumentation) {
-    ::testing::Test::RecordProperty("description", testCaseDocumentation);
-}
-
-/** Document why a test was not fully run. Usually due to an optional feature
- * not implemented. */
-void partialTest(const std::string& reason) {
-    LOG(INFO) << "Test " << getTestName() << " partially run: " << reason;
-    ::testing::Test::RecordProperty("partialyRunTest", reason);
-}
-
-/** Add a note to the test. */
-void note(const std::string& note) {
-    LOG(INFO) << "Test " << getTestName() << " noted: " << note;
-    ::testing::Test::RecordProperty("note", note);
-}
-}
-
-// Register callback for static object destruction
-// Avoid destroying static objects after main return.
-// Post main return destruction leads to incorrect gtest timing measurements as
-// well as harder
-// debuging if anything goes wrong during destruction.
-class Environment : public ::testing::Environment {
-   public:
-    using TearDownFunc = std::function<void()>;
-    void registerTearDown(TearDownFunc&& tearDown) {
-        tearDowns.push_back(std::move(tearDown));
-    }
-
-   private:
-    void TearDown() override {
-        // Call the tear downs in reverse order of insertion
-        for (auto& tearDown : tearDowns) {
-            tearDown();
-        }
-    }
-    std::list<TearDownFunc> tearDowns;
-};
 // Instance to register global tearDown
 static Environment* environment;
 
@@ -743,15 +689,11 @@ TEST_IO_STREAM(
     "Check that the stream frame count == the one it was opened with",
     ASSERT_EQ(audioConfig.frameCount, extract(stream->getFrameCount())))
 
-TEST_IO_STREAM(
-    GetSampleRate,
-    "Check that the stream sample rate == the one it was opened with",
-    stream->getSampleRate())
+TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with",
+               ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
 
-TEST_IO_STREAM(
-    GetChannelMask,
-    "Check that the stream channel mask == the one it was opened with",
-    stream->getChannelMask())
+TEST_IO_STREAM(GetChannelMask, "Check that the stream channel mask == the one it was opened with",
+               ASSERT_EQ(audioConfig.channelMask, extract(stream->getChannelMask())))
 
 TEST_IO_STREAM(GetFormat,
                "Check that the stream format == the one it was opened with",
@@ -853,17 +795,23 @@ TEST_IO_STREAM(
     areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported")
                                : testSetDevice(stream.get(), address))
 
-static void testGetAudioProperties(IStream* stream) {
+static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
     uint32_t sampleRateHz;
     AudioChannelMask mask;
     AudioFormat format;
+
     stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
+
+    // FIXME: the qcom hal it does not currently negotiate the sampleRate &
+    // channel mask
+    EXPECT_EQ(expectedConfig.sampleRateHz, sampleRateHz);
+    EXPECT_EQ(expectedConfig.channelMask, mask);
+    EXPECT_EQ(expectedConfig.format, format);
 }
 
-TEST_IO_STREAM(
-    GetAudioProperties,
-    "Check that the stream audio properties == the ones it was opened with",
-    testGetAudioProperties(stream.get()))
+TEST_IO_STREAM(GetAudioProperties,
+               "Check that the stream audio properties == the ones it was opened with",
+               testGetAudioProperties(stream.get(), audioConfig))
 
 static void testConnectedState(IStream* stream) {
     DeviceAddress address = {};
@@ -1400,6 +1348,5 @@ int main(int argc, char** argv) {
     ::testing::AddGlobalTestEnvironment(environment);
     ::testing::InitGoogleTest(&argc, argv);
     int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
     return status;
 }
index c3c2be1dbd6ea0e01e455d25b3775b058763c16d..8046672abf40b373bdba63109ba1a02353f63be6 100644 (file)
@@ -4,6 +4,7 @@ subdirs = [
     "2.0/vts/functional",
     "common/2.0",
     "common/2.0/default",
+    "common/test/utility",
     "effect/2.0",
     "effect/2.0/vts/functional",
 ]
diff --git a/audio/common/test/utility/Android.bp b/audio/common/test/utility/Android.bp
new file mode 100644 (file)
index 0000000..b796acc
--- /dev/null
@@ -0,0 +1,32 @@
+//
+// 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.
+//
+
+cc_library_static {
+    name: "android.hardware.audio.common.test.utility",
+    defaults : ["hidl_defaults"],
+    srcs: ["src/ValidateXml.cpp"],
+    cflags: [
+        "-O0",
+        "-g",
+        "-Wextra",
+    ],
+    local_include_dirs: ["include/utility"],
+    export_include_dirs: ["include"],
+    shared_libs: ["libxml2", "liblog"],
+    static_libs: ["libgtest"],
+    export_static_lib_headers: ["libgtest"],
+}
+
similarity index 55%
rename from audio/2.0/vts/functional/utility/AssertOk.h
rename to audio/common/test/utility/include/utility/AssertOk.h
index 4c8440e18c7e86c7f7ccad0bc2f9de5fdba1ec1b..d8aa45100531948e61cbf35146ba0721772de032 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_ASSERTOK_H
+#define ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_ASSERTOK_H
 
 #include <algorithm>
 #include <vector>
 
 #include <hidl/Status.h>
 
+namespace android {
+namespace hardware {
+namespace audio {
+namespace common {
+namespace test {
+namespace utility {
+
 namespace detail {
 
 // This is a detail namespace, thus it is OK to import a class as nobody else is
@@ -27,81 +36,65 @@ using ::android::hardware::Return;
 using ::android::hardware::audio::V2_0::Result;
 
 template <class T>
-inline ::testing::AssertionResult assertIsOk(const char* expr,
-                                             const Return<T>& ret) {
+inline ::testing::AssertionResult assertIsOk(const char* expr, const Return<T>& ret) {
     return ::testing::AssertionResult(ret.isOk())
-           << "Expected: " << expr
-           << "\n to be an OK Return but it is not: " << ret.description();
+           << "Expected: " << expr << "\n to be an OK Return but it is not: " << ret.description();
 }
 
 // Call continuation if the provided result isOk
 template <class T, class Continuation>
-inline ::testing::AssertionResult continueIfIsOk(const char* expr,
-                                                 const Return<T>& ret,
+inline ::testing::AssertionResult continueIfIsOk(const char* expr, const Return<T>& ret,
                                                  Continuation continuation) {
     auto isOkStatus = assertIsOk(expr, ret);
     return !isOkStatus ? isOkStatus : continuation();
 }
 
 // Expect two equal Results
-inline ::testing::AssertionResult assertResult(const char* e_expr,
-                                               const char* r_expr,
+inline ::testing::AssertionResult assertResult(const char* e_expr, const char* r_expr,
                                                Result expected, Result result) {
     return ::testing::AssertionResult(expected == result)
-           << "Value of: " << r_expr
-           << "\n  Actual: " << ::testing::PrintToString(result)
-           << "\nExpected: " << e_expr
-           << "\nWhich is: " << ::testing::PrintToString(expected);
+           << "Value of: " << r_expr << "\n  Actual: " << ::testing::PrintToString(result)
+           << "\nExpected: " << e_expr << "\nWhich is: " << ::testing::PrintToString(expected);
 }
 
 // Expect two equal Results one being wrapped in an OK Return
-inline ::testing::AssertionResult assertResult(const char* e_expr,
-                                               const char* r_expr,
-                                               Result expected,
-                                               const Return<Result>& ret) {
-    return continueIfIsOk(r_expr, ret, [&] {
-        return assertResult(e_expr, r_expr, expected, Result{ret});
-    });
+inline ::testing::AssertionResult assertResult(const char* e_expr, const char* r_expr,
+                                               Result expected, const Return<Result>& ret) {
+    return continueIfIsOk(r_expr, ret,
+                          [&] { return assertResult(e_expr, r_expr, expected, Result{ret}); });
 }
 
 // Expect a Result to be part of a list of Results
-inline ::testing::AssertionResult assertResult(
-    const char* e_expr, const char* r_expr, const std::vector<Result>& expected,
-    Result result) {
+inline ::testing::AssertionResult assertResult(const char* e_expr, const char* r_expr,
+                                               const std::vector<Result>& expected, Result result) {
     if (std::find(expected.begin(), expected.end(), result) != expected.end()) {
         return ::testing::AssertionSuccess();  // result is in expected
     }
     return ::testing::AssertionFailure()
-           << "Value of: " << r_expr
-           << "\n  Actual: " << ::testing::PrintToString(result)
+           << "Value of: " << r_expr << "\n  Actual: " << ::testing::PrintToString(result)
            << "\nExpected one of: " << e_expr
            << "\n       Which is: " << ::testing::PrintToString(expected);
 }
 
 // Expect a Result wrapped in an OK Return to be part of a list of Results
-inline ::testing::AssertionResult assertResult(
-    const char* e_expr, const char* r_expr, const std::vector<Result>& expected,
-    const Return<Result>& ret) {
-    return continueIfIsOk(r_expr, ret, [&] {
-        return assertResult(e_expr, r_expr, expected, Result{ret});
-    });
+inline ::testing::AssertionResult assertResult(const char* e_expr, const char* r_expr,
+                                               const std::vector<Result>& expected,
+                                               const Return<Result>& ret) {
+    return continueIfIsOk(r_expr, ret,
+                          [&] { return assertResult(e_expr, r_expr, expected, Result{ret}); });
 }
 
-inline ::testing::AssertionResult assertOk(const char* expr,
-                                           const Return<void>& ret) {
+inline ::testing::AssertionResult assertOk(const char* expr, const Return<void>& ret) {
     return assertIsOk(expr, ret);
 }
 
 inline ::testing::AssertionResult assertOk(const char* expr, Result result) {
     return ::testing::AssertionResult(result == Result::OK)
-           << "Expected success: " << expr
-           << "\nActual: " << ::testing::PrintToString(result);
+           << "Expected success: " << expr << "\nActual: " << ::testing::PrintToString(result);
 }
 
-inline ::testing::AssertionResult assertOk(const char* expr,
-                                           const Return<Result>& ret) {
-    return continueIfIsOk(expr, ret,
-                          [&] { return assertOk(expr, Result{ret}); });
+inline ::testing::AssertionResult assertOk(const char* expr, const Return<Result>& ret) {
+    return continueIfIsOk(expr, ret, [&] { return assertOk(expr, Result{ret}); });
 }
 }
 
@@ -112,7 +105,14 @@ inline ::testing::AssertionResult assertOk(const char* expr,
 #define ASSERT_OK(ret) ASSERT_PRED_FORMAT1(detail::assertOk, ret)
 #define EXPECT_OK(ret) EXPECT_PRED_FORMAT1(detail::assertOk, ret)
 
-#define ASSERT_RESULT(expected, ret) \
-    ASSERT_PRED_FORMAT2(detail::assertResult, expected, ret)
-#define EXPECT_RESULT(expected, ret) \
-    EXPECT_PRED_FORMAT2(detail::assertResult, expected, ret)
+#define ASSERT_RESULT(expected, ret) ASSERT_PRED_FORMAT2(detail::assertResult, expected, ret)
+#define EXPECT_RESULT(expected, ret) EXPECT_PRED_FORMAT2(detail::assertResult, expected, ret)
+
+}  // utility
+}  // test
+}  // common
+}  // audio
+}  // test
+}  // utility
+
+#endif  // ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_ASSERTOK_H
diff --git a/audio/common/test/utility/include/utility/Documentation.h b/audio/common/test/utility/include/utility/Documentation.h
new file mode 100644 (file)
index 0000000..a45cad6
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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 ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_ENVIRONMENT_TEARDOWN
+#define ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_ENVIRONMENT_TEARDOWN
+
+#include <android-base/logging.h>
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace common {
+namespace test {
+namespace utility {
+
+namespace doc {
+namespace detail {
+const char* getTestName() {
+    return ::testing::UnitTest::GetInstance()->current_test_info()->name();
+}
+}  // namespace detail
+
+/** Document the current test case.
+ * Eg: calling `doc::test("Dump the state of the hal")` in the "debugDump" test
+ * will output:
+ *   <testcase name="debugDump" status="run" time="6"
+ *             classname="AudioPrimaryHidlTest"
+               description="Dump the state of the hal." />
+ * see
+ https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#logging-additional-information
+ */
+void test(const std::string& testCaseDocumentation) {
+    ::testing::Test::RecordProperty("description", testCaseDocumentation);
+}
+
+/** Document why a test was not fully run. Usually due to an optional feature
+ * not implemented. */
+void partialTest(const std::string& reason) {
+    LOG(INFO) << "Test " << detail::getTestName() << " partially run: " << reason;
+    ::testing::Test::RecordProperty("partialyRunTest", reason);
+}
+
+/** Add a note to the test. */
+void note(const std::string& note) {
+    LOG(INFO) << "Test " << detail::getTestName() << " noted: " << note;
+    ::testing::Test::RecordProperty("note", note);
+}
+}  // namespace doc
+
+}  // utility
+}  // test
+}  // common
+}  // audio
+}  // test
+}  // utility
+
+#endif  // ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_ENVIRONMENT_TEARDOWN
diff --git a/audio/common/test/utility/include/utility/EnvironmentTearDown.h b/audio/common/test/utility/include/utility/EnvironmentTearDown.h
new file mode 100644 (file)
index 0000000..15b0bd8
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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 ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_ENVIRONMENT_TEARDOWN_H
+#define ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_ENVIRONMENT_TEARDOWN_H
+
+#include <functional>
+#include <list>
+
+#include <gtest/gtest.h>
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace common {
+namespace test {
+namespace utility {
+
+/** Register callback for static object destruction
+ * Avoid destroying static objects after main return.
+ * Post main return destruction leads to incorrect gtest timing measurements as
+ * well as harder debuging if anything goes wrong during destruction. */
+class Environment : public ::testing::Environment {
+   public:
+    using TearDownFunc = std::function<void()>;
+    void registerTearDown(TearDownFunc&& tearDown) { tearDowns.push_back(std::move(tearDown)); }
+
+   private:
+    void TearDown() override {
+        // Call the tear downs in reverse order of insertion
+        for (auto& tearDown : tearDowns) {
+            tearDown();
+        }
+    }
+    std::list<TearDownFunc> tearDowns;
+};
+
+}  // utility
+}  // test
+}  // common
+}  // audio
+}  // test
+}  // utility
+
+#endif  // ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_ENVIRONMENT_TEARDOWN_H
similarity index 65%
rename from audio/2.0/vts/functional/utility/PrettyPrintAudioTypes.h
rename to audio/common/test/utility/include/utility/PrettyPrintAudioTypes.h
index 025cd1c6a4a1cede8f26d488fbebd1c0f11d8db9..37059e748a8254b9d8d865e372845c79e0dcf3ff 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+#ifndef ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_PRETTY_PRINT_AUDIO_TYPES_H
+#define ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_PRETTY_PRINT_AUDIO_TYPES_H
+
+#include <iosfwd>
 #include <type_traits>
 
+#include <android/hardware/audio/2.0/types.h>
+#include <android/hardware/audio/common/2.0/types.h>
+
 /** @file Use HIDL generated toString methods to pretty print gtest errors */
 
-namespace detail {
+namespace prettyPrintAudioTypesDetail {
 
 // Print the value of an enum as hex
 template <class Enum>
@@ -25,7 +33,7 @@ inline void printUnderlyingValue(Enum value, ::std::ostream* os) {
     *os << std::hex << " (0x" << static_cast<std::underlying_type_t<Enum>>(value) << ")";
 }
 
-} // namespace detail
+}  // namespace detail
 
 namespace android {
 namespace hardware {
@@ -34,10 +42,10 @@ namespace V2_0 {
 
 inline void PrintTo(const Result& result, ::std::ostream* os) {
     *os << toString(result);
-    detail::printUnderlyingValue(result, os);
+    prettyPrintAudioTypesDetail::printUnderlyingValue(result, os);
 }
 
-} // namespace V2_0
+}  // namespace V2_0
 namespace common {
 namespace V2_0 {
 
@@ -47,16 +55,18 @@ inline void PrintTo(const AudioConfig& config, ::std::ostream* os) {
 
 inline void PrintTo(const AudioDevice& device, ::std::ostream* os) {
     *os << toString(device);
-    detail::printUnderlyingValue(device, os);
+    prettyPrintAudioTypesDetail::printUnderlyingValue(device, os);
 }
 
 inline void PrintTo(const AudioChannelMask& channelMask, ::std::ostream* os) {
     *os << toString(channelMask);
-    detail::printUnderlyingValue(channelMask, os);
+    prettyPrintAudioTypesDetail::printUnderlyingValue(channelMask, os);
 }
 
-} // namespace V2_0
-} // namespace common
-} // namespace audio
-} // namespace hardware
-} // namespace android
+}  // namespace V2_0
+}  // namespace common
+}  // namespace audio
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_PRETTY_PRINT_AUDIO_TYPES_H
similarity index 75%
rename from audio/2.0/vts/functional/utility/ReturnIn.h
rename to audio/common/test/utility/include/utility/ReturnIn.h
index bb2389a2fc9fc6d67bd356d76839de9a2b687e76..08d502f2d4bac5ffb7608524342bc5e591fe6213 100644 (file)
  * limitations under the License.
  */
 
+#ifndef ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_RETURN_IN_H
+#define ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_RETURN_IN_H
+
 #include <tuple>
 
+namespace android {
+namespace hardware {
+namespace audio {
+namespace common {
+namespace test {
 namespace utility {
 
 namespace detail {
 // Helper class to generate the HIDL synchronous callback
 template <class... ResultStore>
 class ReturnIn {
- public:
  public:
     // Provide to the constructor the variables where the output parameters must be copied
     // TODO: take pointers to match google output parameter style ?
     ReturnIn(ResultStore&... ts) : results(ts...) {}
     // Synchronous callback
     template <class... Results>
-    void operator() (Results&&...results) {
+    void operator()(Results&&... results) {
         set(std::forward<Results>(results)...);
     }
- private:
+
+   private:
     // Recursively set all output parameters
     template <class Head, class... Tail>
     void set(Head&& head, Tail&&... tail) {
-        std::get<sizeof...(ResultStore) - sizeof...(Tail) - 1>(results)
-                  = std::forward<Head>(head);
+        std::get<sizeof...(ResultStore) - sizeof...(Tail) - 1>(results) = std::forward<Head>(head);
         set(tail...);
     }
     // Trivial case
@@ -45,7 +53,7 @@ class ReturnIn {
     // All variables to set are stored here
     std::tuple<ResultStore&...> results;
 };
-} // namespace detail
+}  // namespace detail
 
 // Generate the HIDL synchronous callback with a copy policy
 // Input: the variables (lvalue reference) where to save the return values
@@ -53,6 +61,15 @@ class ReturnIn {
 // The output parameters *will be copied* do not use this function if you have
 // a zero copy policy
 template <class... ResultStore>
-detail::ReturnIn<ResultStore...> returnIn(ResultStore&... ts) { return {ts...};}
-
+detail::ReturnIn<ResultStore...> returnIn(ResultStore&... ts) {
+    return {ts...};
 }
+
+}  // utility
+}  // test
+}  // common
+}  // audio
+}  // test
+}  // utility
+
+#endif  // ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_RETURN_IN_H
similarity index 68%
rename from audio/2.0/vts/functional/utility/ValidateXml.h
rename to audio/common/test/utility/include/utility/ValidateXml.h
index edb09bf31354cb185a8e220f6af12f0e1353be4b..fdfa50666e5b0eccaacdeb2489ee65676d708783 100644 (file)
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_AUDIO_TEST_VALIDATEXML
-#define ANDROID_HARDWARE_AUDIO_TEST_VALIDATEXML
+#ifndef ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_VALIDATE_XML_H
+#define ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_VALIDATE_XML_H
 
 #include <gtest/gtest.h>
 
 namespace android {
 namespace hardware {
 namespace audio {
+namespace common {
 namespace test {
+namespace utility {
 
 /** Validate the provided XmlFile with the provided xsdFile.
  * Intended to use with ASSERT_PRED_FORMAT2 as such:
@@ -33,12 +35,15 @@ namespace test {
                                        const char* xmlFilePath, const char* xsdPathName);
 
 /** Helper gtest ASSERT to test xml validity against an xsd. */
-#define ASSERT_VALID_XML(xmlFilePath, xsdFilePath) \
-    ASSERT_PRED_FORMAT2(::android::hardware::audio::test::validateXml, xmlFilePath, xsdFilePath)
+#define ASSERT_VALID_XML(xmlFilePath, xsdFilePath)                                      \
+    ASSERT_PRED_FORMAT2(::android::hardware::audio::common::test::utility::validateXml, \
+                        xmlFilePath, xsdFilePath)
 
-}  // namespace test
-}  // namespace audio
-}  // namespace hardware
-}  // namespace android
+}  // utility
+}  // test
+}  // common
+}  // audio
+}  // test
+}  // utility
 
-#endif  // ANDROID_HARDWARE_AUDIO_TEST_VALIDATEXML
+#endif  // ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_VALIDATE_XML_H
similarity index 97%
rename from audio/2.0/vts/functional/utility/ValidateXml.cpp
rename to audio/common/test/utility/src/ValidateXml.cpp
index 2fb828e30788da78af78fa93399049213ee813cb..784f9401ecc7432d1232f493e7128f2a45372e46 100644 (file)
@@ -30,7 +30,9 @@
 namespace android {
 namespace hardware {
 namespace audio {
+namespace common {
 namespace test {
+namespace utility {
 
 /** Map libxml2 structures to their corresponding deleters. */
 template <class T>
@@ -125,7 +127,9 @@ struct Libxml2Global {
     return ::testing::AssertionSuccess();
 }
 
-}  // namespace test
-}  // namespace audio
-}  // namespace hardware
-}  // namespace android
+}  // utility
+}  // test
+}  // common
+}  // audio
+}  // test
+}  // utility
index aec8865f89c9691c8d51b22e950e3ba92e6f2e9b..be588299e36f25c26f0d967a5341ba55bc2a5ed6 100644 (file)
@@ -1,7 +1,6 @@
 // This is an autogenerated file, do not edit.
 subdirs = [
     "evs/1.0",
-    "evs/1.0/default",
     "evs/1.0/vts/functional",
     "vehicle/2.0",
     "vehicle/2.1",
diff --git a/automotive/evs/1.0/default/Android.bp b/automotive/evs/1.0/default/Android.bp
deleted file mode 100644 (file)
index 2574e86..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-cc_binary {
-    name: "android.hardware.automotive.evs@1.0-service",
-    defaults: ["hidl_defaults"],
-    proprietary: true,
-    relative_install_path: "hw",
-    srcs: [
-        "service.cpp",
-        "EvsCamera.cpp",
-        "EvsEnumerator.cpp",
-        "EvsDisplay.cpp"
-    ],
-    init_rc: ["android.hardware.automotive.evs@1.0-service.rc"],
-
-    shared_libs: [
-        "android.hardware.automotive.evs@1.0",
-        "libui",
-        "libbase",
-        "libbinder",
-        "libcutils",
-        "libhardware",
-        "libhidlbase",
-        "libhidltransport",
-        "liblog",
-        "libutils",
-    ],
-
-    cflags: [
-        "-O0",
-        "-g",
-    ],
-}
diff --git a/automotive/evs/1.0/default/Android.mk b/automotive/evs/1.0/default/Android.mk
new file mode 100644 (file)
index 0000000..0ee7071
--- /dev/null
@@ -0,0 +1,29 @@
+LOCAL_PATH:=$(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.automotive.evs@1.0-service
+LOCAL_INIT_RC := android.hardware.automotive.evs@1.0-service.rc
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_VENDOR_MODULE := true
+
+LOCAL_SRC_FILES := \
+    service.cpp \
+    EvsCamera.cpp \
+    EvsEnumerator.cpp \
+    EvsDisplay.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+    android.hardware.automotive.evs@1.0 \
+    libui \
+    libbase \
+    libbinder \
+    libcutils \
+    libhardware \
+    libhidlbase \
+    libhidltransport \
+    liblog \
+    libutils \
+
+LOCAL_CFLAGS := -O0 -g
+
+include $(BUILD_EXECUTABLE)
index 8957ecfca338ce04599fdf2a1e5a90e63db062ac..16d521d71875ca3de56c99116f6c27d15a9caff0 100644 (file)
@@ -1,4 +1,4 @@
-service evs-hal-1-0 /vendor/bin/hw/android.hardware.automotive.evs@1.0-service
+service evs-hal-mock /vendor/bin/hw/android.hardware.automotive.evs@1.0-service
     class hal
-    user cameraserver
-    group camera
+    user automotive_evs
+    group automotive_evs
index e5cc8ee6e4d11b7f638d576ab5a11a6bae402a64..1e8929d6b764e066e6fbc8aff8a9dbf87e7ceccf 100644 (file)
@@ -18,8 +18,6 @@
 
 #include "FormatConvert.h"
 
-#include <algorithm>    // std::min
-
 
 // Round up to the nearest multiple of the given alignment value
 template<unsigned alignment>
index 193609386931370cf9dacd29ab33bd921d0b01ec..72e1364fc69718daf3c0423144d8b751aa0af603 100644 (file)
@@ -121,6 +121,7 @@ LOCAL_SHARED_LIBRARIES := \
     $(vhal_v2_0) \
 
 LOCAL_STATIC_LIBRARIES := \
+    libqemu_pipe \
     $(vhal_v2_0)-libproto-native \
 
 LOCAL_CFLAGS += -Wall -Wextra -Werror
@@ -186,6 +187,7 @@ LOCAL_STATIC_LIBRARIES := \
     $(vhal_v2_0)-manager-lib \
     $(vhal_v2_0)-default-impl-lib \
     $(vhal_v2_0)-libproto-native \
+    libqemu_pipe \
 
 LOCAL_CFLAGS += -Wall -Wextra -Werror
 
index be25adc0ad8c5660be1881400623d69d1b08434d..0ed87422a1ffbf2d8666e0105758c007488c054f 100644 (file)
@@ -26,6 +26,7 @@
 #include <set>
 #include <thread>
 #include <unordered_map>
+#include <vector>
 
 /**
  * This class allows to specify multiple time intervals to receive
index 311cdef1d687fa27d160394ed836f38e59896f6b..9146fa122878ebf801a12aa6b197279922096360 100644 (file)
@@ -102,10 +102,10 @@ void shallowCopyHidlVec(hidl_vec <T>* dest, const hidl_vec <T>& src) {
 }
 
 void shallowCopyHidlStr(hidl_string* dest, const hidl_string& src) {
-    if (!src.empty()) {
+    if (src.empty()) {
+        dest->clear();
+    } else {
         dest->setToExternal(src.c_str(), src.size());
-    } else if (dest->size() > 0) {
-        dest->setToExternal(0, 0);
     }
 }
 
index 009485d4b7bf59e55fc889576d5d4f9f8e623452..c25e0838c51dbb2d8bbdd58fc5fa84b33e1d3089 100644 (file)
 
 #include <utils/SystemClock.h>
 
-#include "VehicleHalProto.pb.h"
-
 #include <vhal_v2_0/RecurrentTimer.h>
 #include <vhal_v2_0/VehicleHal.h>
 #include "vhal_v2_0/VehiclePropertyStore.h"
 
 #include "DefaultConfig.h"
-#include "VehicleHalProto.pb.h"
 #include "VehicleEmulator.h"
 #include "FakeValueGenerator.h"
 
index 2b15aa3b4d1a2bf48f92feb48f40ee6322fe29aa..5a9b2545944020e59c5e5c2238483c7513fc8fdb 100644 (file)
@@ -17,9 +17,8 @@
 #define LOG_TAG "PipeComm"
 
 #include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
-#include <android/log.h>
 #include <log/log.h>
-#include <system/qemu_pipe.h>
+#include <qemu_pipe.h>
 
 #include "PipeComm.h"
 
index 693fe2d07f3895b5c73f4ad0dd30da97483662f5..8e1c0dd321148fa2fe69bb1bfdbebe71e69aa38d 100644 (file)
@@ -208,9 +208,9 @@ $(GEN): $(LOCAL_PATH)/types.hal
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (VmsMessageIntegerValuesIndex)
+# Build types.hal (VmsBaseMessageIntegerValuesIndex)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsMessageIntegerValuesIndex.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsBaseMessageIntegerValuesIndex.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -220,7 +220,7 @@ $(GEN): PRIVATE_CUSTOM_TOOL = \
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.VmsMessageIntegerValuesIndex
+        android.hardware.automotive.vehicle@2.1::types.VmsBaseMessageIntegerValuesIndex
 
 $(GEN): $(LOCAL_PATH)/types.hal
        $(transform-generated-source)
@@ -245,6 +245,63 @@ $(GEN): $(LOCAL_PATH)/types.hal
        $(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
+#
+# Build types.hal (VmsOfferingMessageIntegerValuesIndex)
+#
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsOfferingMessageIntegerValuesIndex.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.automotive.vehicle@2.1::types.VmsOfferingMessageIntegerValuesIndex
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (VmsSimpleMessageIntegerValuesIndex)
+#
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsSimpleMessageIntegerValuesIndex.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.automotive.vehicle@2.1::types.VmsSimpleMessageIntegerValuesIndex
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (VmsSubscriptionResponseFormat)
+#
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsSubscriptionResponseFormat.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.automotive.vehicle@2.1::types.VmsSubscriptionResponseFormat
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
 #
 # Build IVehicle.hal
 #
@@ -472,9 +529,9 @@ $(GEN): $(LOCAL_PATH)/types.hal
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (VmsMessageIntegerValuesIndex)
+# Build types.hal (VmsBaseMessageIntegerValuesIndex)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsMessageIntegerValuesIndex.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsBaseMessageIntegerValuesIndex.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -484,7 +541,7 @@ $(GEN): PRIVATE_CUSTOM_TOOL = \
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.VmsMessageIntegerValuesIndex
+        android.hardware.automotive.vehicle@2.1::types.VmsBaseMessageIntegerValuesIndex
 
 $(GEN): $(LOCAL_PATH)/types.hal
        $(transform-generated-source)
@@ -509,6 +566,63 @@ $(GEN): $(LOCAL_PATH)/types.hal
        $(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
+#
+# Build types.hal (VmsOfferingMessageIntegerValuesIndex)
+#
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsOfferingMessageIntegerValuesIndex.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.automotive.vehicle@2.1::types.VmsOfferingMessageIntegerValuesIndex
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (VmsSimpleMessageIntegerValuesIndex)
+#
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsSimpleMessageIntegerValuesIndex.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.automotive.vehicle@2.1::types.VmsSimpleMessageIntegerValuesIndex
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (VmsSubscriptionResponseFormat)
+#
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsSubscriptionResponseFormat.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.automotive.vehicle@2.1::types.VmsSubscriptionResponseFormat
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
 #
 # Build IVehicle.hal
 #
index 32ec456e2534923e1698c9c318c93d3ea010adde..f19263c7d1f5b8a824448d408929aedb4b64a83c 100644 (file)
@@ -65,6 +65,7 @@ LOCAL_EXPORT_C_INCLUDE_DIRS := \
 LOCAL_STATIC_LIBRARIES := \
     $(vhal_v2_0)-default-impl-lib \
     $(vhal_v2_0)-manager-lib \
+    libqemu_pipe \
     $(vhal_v2_1)-manager-lib \
     $(vhal_v2_0)-libproto-native
 
@@ -101,6 +102,7 @@ LOCAL_STATIC_LIBRARIES := \
     $(vhal_v2_0)-manager-lib \
     $(vhal_v2_0)-default-impl-lib \
     $(vhal_v2_1)-default-impl-lib \
+    libqemu_pipe \
     $(vhal_v2_1)-manager-lib \
 
 LOCAL_SHARED_LIBRARIES := \
index 4dceae0581469851b79e13d5be2146b9239a5690..46e062b86b6c6f23bb40ea64b4501fc0c2d12566 100644 (file)
@@ -23,7 +23,6 @@
 #include <algorithm>
 
 #include "EmulatedVehicleHal.h"
-#include "VehicleHalProto.pb.h"
 
 #define DEBUG_SOCKET    (33452)
 
@@ -139,6 +138,8 @@ void EmulatedVehicleHal::initObd2FreezeFrame(const V2_0::VehiclePropConfig& prop
     for (auto&& dtc : sampleDtcs) {
         auto freezeFrame = createVehiclePropValue(V2_0::VehiclePropertyType::COMPLEX, 0);
         sensorStore->fillPropValue(dtc, freezeFrame.get());
+        freezeFrame->prop = OBD2_FREEZE_FRAME;
+
         mPropStore->writeValue(*freezeFrame);
     }
 }
index 08dc144c705ce56454987a42a2b53e2cf73a3c24..7be611c55bf7404a9744da0b3ac759d7aeadf66a 100644 (file)
@@ -584,22 +584,70 @@ enum VmsMessageType : int32_t {
 
   /** A client publishes a data packet. */
   DATA = 3,
+
+  /* A client declaring layers offering. */
+  OFFERING = 4,
+
+  /* Requesting the list of available layers. */
+  AVAILABILITY_REQUEST = 5,
+
+  /* Returning the list of available layers. */
+  AVAILABILITY_RESPONSE = 6,
+
+  /** Requesting layers that have subscribers. */
+  SUBSCRIPTION_REQUEST = 7,
+
+  /** Returning layers that have subscribers. */
+  SUBSCRIPTION_RESPONSE = 8,
 };
 
 /**
  * This enum provides the canonical mapping for VMS properties that have an
  * integer value.
  */
-enum VmsMessageIntegerValuesIndex : int32_t {
-  /** The message type as enumerated by VmsMessageType enum. */
+enum VmsBaseMessageIntegerValuesIndex : int32_t {
+  /* The message type as enumerated by VmsMessageType enum. */
   VMS_MESSAGE_TYPE = 0,
+};
 
-  /** The layer ID as defined in the vms protocol. */
+/*
+ * This enum provides the canonical mapping for VMS SUBMIT, UNSUBMIT and DATA
+ * messages integer value properties.
+ */
+enum VmsSimpleMessageIntegerValuesIndex : VmsBaseMessageIntegerValuesIndex {
+  /* The layer ID as defined in the vms protocol. */
   VMS_LAYER_ID = 1,
 
-  /** The version of the VMS layer. */
+  /* The version of the VMS layer. */
   VMS_LAYER_VERSION = 2,
+};
+
+/*
+ * This enum provides the canonical mapping for VMS offering messages integer
+ * value properties
+ */
+enum VmsOfferingMessageIntegerValuesIndex : VmsBaseMessageIntegerValuesIndex {
+  /* The number of VMS layer dependencies. */
+  VMS_NUMBER_OF_LAYERS_DEPENDENCIES = 1,
+
+  /* The first index that contain dependencies */
+  FIRST_DEPENDENCIES_INDEX = 2,
+};
+
+/**
+ * A VMS subscription request only contains its message type. The format of a VMS subscription
+ * response is described below.
+ */
+enum VmsSubscriptionResponseFormat : VmsBaseMessageIntegerValuesIndex {
+  /**
+    * Recipients should ignore any packet with a sequence number that is less than the highest
+    * sequence number they have seen thus far.
+    */
+  SEQUENCE_NUMBER = 1,
+
+  /** The number of VMS layers. Each layer has two integers: type and version. */
+  NUMBER_OF_LAYERS = 2,
 
-  /** The number of bytes in the payload */
-  VMS_PAYLOAD_SIZE_BYTES = 3,
+  /** The first index that contains a layer. */
+  FIRST_LAYER = 3,
 };
diff --git a/broadcastradio/1.0/default/Android.bp b/broadcastradio/1.0/default/Android.bp
new file mode 100644 (file)
index 0000000..f961dfd
--- /dev/null
@@ -0,0 +1,41 @@
+//
+// 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.
+//
+
+cc_library_shared {
+    name: "android.hardware.broadcastradio@1.0-impl",
+    vendor: true,
+    relative_install_path: "hw",
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+    srcs: [
+        "BroadcastRadio.cpp",
+        "BroadcastRadioFactory.cpp",
+        "Tuner.cpp",
+        "Utils.cpp",
+    ],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libutils",
+        "liblog",
+        "libhardware",
+        "android.hardware.broadcastradio@1.0",
+        "libradio_metadata",
+    ],
+}
diff --git a/broadcastradio/1.0/default/Android.mk b/broadcastradio/1.0/default/Android.mk
deleted file mode 100644 (file)
index bb32595..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.broadcastradio@1.0-impl
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := \
-    BroadcastRadio.cpp \
-    BroadcastRadioFactory.cpp \
-    Tuner.cpp \
-    Utils.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libhidlbase \
-    libhidltransport \
-    libutils \
-    liblog \
-    libhardware \
-    android.hardware.broadcastradio@1.0 \
-    libradio_metadata
-
-ifeq ($(strip $(AUDIOSERVER_MULTILIB)),)
-LOCAL_MULTILIB := 32
-else
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-endif
-
-include $(BUILD_SHARED_LIBRARY)
index ebeadb13dae19bdddd1c6c4db9c6e49e221ca513..fd048db35d41b6c96ed78b4385a9c61ee8c2ab46 100644 (file)
@@ -46,7 +46,8 @@ using ::android::hardware::broadcastradio::V1_0::BandConfig;
 using ::android::hardware::broadcastradio::V1_0::Direction;
 using ::android::hardware::broadcastradio::V1_0::ProgramInfo;
 using ::android::hardware::broadcastradio::V1_0::MetaData;
-
+using ::android::hardware::broadcastradio::V1_0::MetadataKey;
+using ::android::hardware::broadcastradio::V1_0::MetadataType;
 
 #define RETURN_IF_SKIPPED \
     if (skipped) { \
@@ -229,6 +230,18 @@ class BroadcastRadioHidlTest : public ::testing::VtsHalHidlTargetTestBase,
     bool openTuner();
     bool checkAntenna();
 
+    /**
+     * Retrieves AM/FM band configuration from module properties.
+     *
+     * The configuration may not exist: if radio type is other than AM/FM
+     * or provided index is out of bounds.
+     * In such case, empty configuration is returned.
+     *
+     * @param idx Band index to retrieve.
+     * @return Band configuration reference.
+     */
+    const BandConfig& getBand(unsigned idx);
+
     static const nsecs_t kConnectCallbacktimeoutNs = seconds_to_nanoseconds(1);
     static const nsecs_t kConfigCallbacktimeoutNs = seconds_to_nanoseconds(10);
     static const nsecs_t kTuneCallbacktimeoutNs = seconds_to_nanoseconds(30);
@@ -237,6 +250,7 @@ class BroadcastRadioHidlTest : public ::testing::VtsHalHidlTargetTestBase,
     bool skipped;
     sp<IBroadcastRadio> mRadio;
     Properties mHalProperties;
+    bool mHalPropertiesInitialized = false;
     sp<ITuner> mTuner;
     sp<MyCallback> mTunerCallback;
     Mutex mLock;
@@ -280,23 +294,29 @@ static bool operator==(const BandConfig& l, const BandConfig& r) {
 
 bool BroadcastRadioHidlTest::getProperties()
 {
-    if (mHalProperties.bands.size() == 0) {
-        Result halResult = Result::NOT_INITIALIZED;
-        Return<void> hidlReturn =
-                mRadio->getProperties([&](Result result, const Properties& properties) {
-                        halResult = result;
-                        if (result == Result::OK) {
-                            mHalProperties = properties;
-                        }
-                    });
+    if (mHalPropertiesInitialized) return true;
 
-        EXPECT_TRUE(hidlReturn.isOk());
-        EXPECT_EQ(Result::OK, halResult);
-        EXPECT_EQ(Class::AM_FM, mHalProperties.classId);
-        EXPECT_GT(mHalProperties.numTuners, 0u);
+    Result halResult = Result::NOT_INITIALIZED;
+    auto hidlReturn = mRadio->getProperties([&](Result result, const Properties& properties) {
+        halResult = result;
+        if (result == Result::OK) {
+            mHalProperties = properties;
+        }
+    });
+
+    EXPECT_TRUE(hidlReturn.isOk());
+    EXPECT_EQ(Result::OK, halResult);
+    EXPECT_EQ(radioClass, mHalProperties.classId);
+    EXPECT_GT(mHalProperties.numTuners, 0u);
+    if (radioClass == Class::AM_FM) {
         EXPECT_GT(mHalProperties.bands.size(), 0u);
     }
-    return mHalProperties.bands.size() > 0;
+
+    if (hidlReturn.isOk() && halResult == Result::OK) {
+        mHalPropertiesInitialized = true;
+        return true;
+    }
+    return false;
 }
 
 bool BroadcastRadioHidlTest::openTuner()
@@ -306,17 +326,18 @@ bool BroadcastRadioHidlTest::openTuner()
     }
     if (mTuner.get() == nullptr) {
         Result halResult = Result::NOT_INITIALIZED;
-        Return<void> hidlReturn =
-                mRadio->openTuner(mHalProperties.bands[0], true, mTunerCallback,
-                                  [&](Result result, const sp<ITuner>& tuner) {
-                        halResult = result;
-                        if (result == Result::OK) {
-                            mTuner = tuner;
-                        }
-                    });
+        auto openCb = [&](Result result, const sp<ITuner>& tuner) {
+            halResult = result;
+            if (result == Result::OK) {
+                mTuner = tuner;
+            }
+        };
+        auto hidlReturn = mRadio->openTuner(getBand(0), true, mTunerCallback, openCb);
         EXPECT_TRUE(hidlReturn.isOk());
         EXPECT_EQ(Result::OK, halResult);
-        EXPECT_EQ(true, waitForCallback(kConfigCallbacktimeoutNs));
+        if (radioClass == Class::AM_FM) {
+            EXPECT_EQ(true, waitForCallback(kConfigCallbacktimeoutNs));
+        }
     }
     EXPECT_NE(nullptr, mTuner.get());
     return nullptr != mTuner.get();
@@ -324,6 +345,8 @@ bool BroadcastRadioHidlTest::openTuner()
 
 bool BroadcastRadioHidlTest::checkAntenna()
 {
+    if (radioClass != Class::AM_FM) return true;
+
     BandConfig halConfig;
     Result halResult = Result::NOT_INITIALIZED;
     Return<void> hidlReturn =
@@ -337,6 +360,19 @@ bool BroadcastRadioHidlTest::checkAntenna()
     return ((halResult == Result::OK) && (halConfig.antennaConnected == true));
 }
 
+const BandConfig& BroadcastRadioHidlTest::getBand(unsigned idx) {
+    static BandConfig dummyBandConfig = {};
+    if (radioClass == Class::AM_FM) {
+        EXPECT_GT(mHalProperties.bands.size(), idx);
+        if (mHalProperties.bands.size() > idx) {
+            return mHalProperties.bands[idx];
+        } else {
+            return dummyBandConfig;
+        }
+    } else {
+        return dummyBandConfig;
+    }
+}
 
 /**
  * Test IBroadcastRadio::getProperties() method
@@ -344,7 +380,7 @@ bool BroadcastRadioHidlTest::checkAntenna()
  * Verifies that:
  *  - the HAL implements the method
  *  - the method returns 0 (no error)
- *  - the implementation class is AM_FM
+ *  - the implementation class is radioClass
  *  - the implementation supports at least one tuner
  *  - the implementation supports at one band
  */
@@ -383,22 +419,24 @@ TEST_P(BroadcastRadioHidlTest, ReopenTuner) {
  * Test IBroadcastRadio::openTuner() method called twice.
  *
  * Verifies that:
- *  - the openTuner method fails when called for the second time without deleting previous
- *    ITuner instance
+ *  - the openTuner method fails with INVALID_STATE or succeeds when called for the second time
+ *    without deleting previous ITuner instance
  */
 TEST_P(BroadcastRadioHidlTest, OpenTunerTwice) {
     RETURN_IF_SKIPPED;
     EXPECT_TRUE(openTuner());
 
     Result halResult = Result::NOT_INITIALIZED;
-    Return<void> hidlReturn =
-            mRadio->openTuner(mHalProperties.bands[0], true, mTunerCallback,
-                              [&](Result result, const sp<ITuner>&) {
-                    halResult = result;
-                });
+    auto openCb = [&](Result result, const sp<ITuner>&) { halResult = result; };
+    auto hidlReturn = mRadio->openTuner(getBand(0), true, mTunerCallback, openCb);
     EXPECT_TRUE(hidlReturn.isOk());
-    EXPECT_EQ(Result::INVALID_STATE, halResult);
-    EXPECT_TRUE(waitForCallback(kConfigCallbacktimeoutNs));
+    if (halResult == Result::OK) {
+        if (radioClass == Class::AM_FM) {
+            EXPECT_TRUE(waitForCallback(kConfigCallbacktimeoutNs));
+        }
+    } else {
+        EXPECT_EQ(Result::INVALID_STATE, halResult);
+    }
 }
 
 /**
@@ -409,18 +447,22 @@ TEST_P(BroadcastRadioHidlTest, OpenTunerTwice) {
  *  - the methods return 0 (no error)
  *  - the configuration callback is received within kConfigCallbacktimeoutNs ns
  *  - the configuration read back from HAl has the same class Id
+ *
+ * Skipped for other radio classes than AM/FM, because setConfiguration
+ * applies only for these bands.
  */
 TEST_P(BroadcastRadioHidlTest, SetAndGetConfiguration) {
+    if (radioClass != Class::AM_FM) skipped = true;
     RETURN_IF_SKIPPED;
     ASSERT_EQ(true, openTuner());
     // test setConfiguration
     mCallbackCalled = false;
-    Return<Result> hidlResult = mTuner->setConfiguration(mHalProperties.bands[1]);
+    Return<Result> hidlResult = mTuner->setConfiguration(getBand(1));
     EXPECT_TRUE(hidlResult.isOk());
     EXPECT_EQ(Result::OK, hidlResult);
     EXPECT_EQ(true, waitForCallback(kConfigCallbacktimeoutNs));
     EXPECT_EQ(Result::OK, mResultCallbackData);
-    EXPECT_EQ(mHalProperties.bands[1], mBandConfigCallbackData);
+    EXPECT_EQ(getBand(1), mBandConfigCallbackData);
 
     // test getConfiguration
     BandConfig halConfig;
@@ -434,7 +476,7 @@ TEST_P(BroadcastRadioHidlTest, SetAndGetConfiguration) {
             });
     EXPECT_TRUE(hidlReturn.isOk());
     EXPECT_EQ(Result::OK, halResult);
-    EXPECT_EQ(mHalProperties.bands[1], halConfig);
+    EXPECT_EQ(getBand(1), halConfig);
 }
 
 /**
@@ -443,8 +485,12 @@ TEST_P(BroadcastRadioHidlTest, SetAndGetConfiguration) {
  * Verifies that:
  *  - the methods returns INVALID_ARGUMENTS on invalid arguments
  *  - the method recovers and succeeds after passing correct arguments
+ *
+ * Skipped for other radio classes than AM/FM, because setConfiguration
+ * applies only for these bands.
  */
 TEST_P(BroadcastRadioHidlTest, SetConfigurationFails) {
+    if (radioClass != Class::AM_FM) skipped = true;
     RETURN_IF_SKIPPED;
     ASSERT_EQ(true, openTuner());
 
@@ -463,7 +509,7 @@ TEST_P(BroadcastRadioHidlTest, SetConfigurationFails) {
 
     // Test setConfiguration recovering after passing good data.
     mCallbackCalled = false;
-    setResult = mTuner->setConfiguration(mHalProperties.bands[0]);
+    setResult = mTuner->setConfiguration(getBand(0));
     EXPECT_TRUE(setResult.isOk());
     EXPECT_EQ(Result::OK, setResult);
     EXPECT_EQ(true, waitForCallback(kConfigCallbacktimeoutNs));
@@ -506,8 +552,12 @@ TEST_P(BroadcastRadioHidlTest, Scan) {
  *  - the method returns 0 (no error)
  *  - the tuned callback is received within kTuneCallbacktimeoutNs ns
  *  - skipping sub-channel or not does not fail the call
+ *
+ * Skipped for other radio classes than AM/FM, because step is not possible
+ * on DAB nor satellite.
  */
 TEST_P(BroadcastRadioHidlTest, Step) {
+    if (radioClass != Class::AM_FM) skipped = true;
     RETURN_IF_SKIPPED;
     ASSERT_EQ(true, openTuner());
     ASSERT_TRUE(checkAntenna());
@@ -533,20 +583,26 @@ TEST_P(BroadcastRadioHidlTest, Step) {
  *  - the HAL implements the methods
  *  - the methods return 0 (no error)
  *  - the tuned callback is received within kTuneCallbacktimeoutNs ns after tune()
+ *
+ * Skipped for other radio classes than AM/FM, because tune to frequency
+ * is not possible on DAB nor satellite.
  */
 TEST_P(BroadcastRadioHidlTest, TuneAndGetProgramInformationAndCancel) {
+    if (radioClass != Class::AM_FM) skipped = true;
     RETURN_IF_SKIPPED;
     ASSERT_EQ(true, openTuner());
     ASSERT_TRUE(checkAntenna());
 
+    auto& band = getBand(0);
+
     // test tune
-    ASSERT_GT(mHalProperties.bands[0].spacings.size(), 0u);
-    ASSERT_GT(mHalProperties.bands[0].upperLimit, mHalProperties.bands[0].lowerLimit);
+    ASSERT_GT(band.spacings.size(), 0u);
+    ASSERT_GT(band.upperLimit, band.lowerLimit);
 
     // test scan UP
-    uint32_t lowerLimit = mHalProperties.bands[0].lowerLimit;
-    uint32_t upperLimit = mHalProperties.bands[0].upperLimit;
-    uint32_t spacing = mHalProperties.bands[0].spacings[0];
+    uint32_t lowerLimit = band.lowerLimit;
+    uint32_t upperLimit = band.upperLimit;
+    uint32_t spacing = band.spacings[0];
 
     uint32_t channel =
             lowerLimit + (((upperLimit - lowerLimit) / 2 + spacing - 1) / spacing) * spacing;
@@ -571,11 +627,8 @@ TEST_P(BroadcastRadioHidlTest, TuneAndGetProgramInformationAndCancel) {
     EXPECT_TRUE(hidlReturn.isOk());
     EXPECT_EQ(Result::OK, halResult);
     if (mResultCallbackData == Result::OK) {
-        EXPECT_EQ(true, halInfo.tuned);
         EXPECT_LE(halInfo.channel, upperLimit);
         EXPECT_GE(halInfo.channel, lowerLimit);
-    } else {
-        EXPECT_EQ(false, halInfo.tuned);
     }
 
     // test cancel
@@ -591,8 +644,12 @@ TEST_P(BroadcastRadioHidlTest, TuneAndGetProgramInformationAndCancel) {
  * Verifies that:
  *  - the method returns INVALID_ARGUMENTS when applicable
  *  - the method recovers and succeeds after passing correct arguments
+ *
+ * Skipped for other radio classes than AM/FM, because tune to frequency
+ * is not possible on DAB nor satellite.
  */
 TEST_P(BroadcastRadioHidlTest, TuneFailsOutOfBounds) {
+    if (radioClass != Class::AM_FM) skipped = true;
     RETURN_IF_SKIPPED;
     ASSERT_TRUE(openTuner());
     ASSERT_TRUE(checkAntenna());
@@ -622,6 +679,52 @@ TEST_P(BroadcastRadioHidlTest, TuneFailsOutOfBounds) {
     EXPECT_TRUE(waitForCallback(kTuneCallbacktimeoutNs));
 }
 
+/**
+ * Test proper image format in metadata.
+ *
+ * Verifies that:
+ * - all images in metadata are provided in-band (as a binary blob, not by id)
+ *
+ * This is a counter-test for OobImagesOnly from 1.1 VTS.
+ */
+TEST_P(BroadcastRadioHidlTest, IbImagesOnly) {
+    RETURN_IF_SKIPPED;
+    ASSERT_TRUE(openTuner());
+    ASSERT_TRUE(checkAntenna());
+
+    bool firstScan = true;
+    uint32_t firstChannel, prevChannel;
+    while (true) {
+        mCallbackCalled = false;
+        auto hidlResult = mTuner->scan(Direction::UP, true);
+        ASSERT_TRUE(hidlResult.isOk());
+        if (hidlResult == Result::TIMEOUT) {
+            ALOGI("Got timeout on scan operation");
+            break;
+        }
+        ASSERT_EQ(Result::OK, hidlResult);
+        ASSERT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs));
+
+        if (firstScan) {
+            firstScan = false;
+            firstChannel = mProgramInfoCallbackData.channel;
+        } else {
+            // scanned the whole band
+            if (mProgramInfoCallbackData.channel >= firstChannel && prevChannel <= firstChannel) {
+                break;
+            }
+        }
+        prevChannel = mProgramInfoCallbackData.channel;
+
+        for (auto&& entry : mProgramInfoCallbackData.metadata) {
+            if (entry.key != MetadataKey::ICON && entry.key != MetadataKey::ART) continue;
+            EXPECT_EQ(MetadataType::RAW, entry.type);
+            EXPECT_EQ(0, entry.intValue);
+            EXPECT_GT(entry.rawValue.size(), 0u);
+        }
+    }
+}
+
 INSTANTIATE_TEST_CASE_P(
     BroadcastRadioHidlTestCases,
     BroadcastRadioHidlTest,
diff --git a/broadcastradio/1.1/Android.mk b/broadcastradio/1.1/Android.mk
deleted file mode 100644 (file)
index 0c4c55d..0000000
+++ /dev/null
@@ -1,19 +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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-include $(call all-subdir-makefiles)
index 82d45c6b5e974cb19642463b6d3c759c4f7111c0..751162966f2afa8457e13e7693e25d34260a3323 100644 (file)
@@ -47,8 +47,8 @@ interface ITuner extends @1.0::ITuner {
      *
      * @return result OK if the scan was properly scheduled (this does not mean
      *                it successfully finished).
-     *                TEMPORARILY_UNAVAILABLE if the background scan is
-     *                temporarily unavailable, ie. due to ongoing foreground
+     *                UNAVAILABLE if the background scan is unavailable,
+     *                ie. temporarily due to ongoing foreground
      *                playback in single-tuner device.
      *                NOT_INITIALIZED other error, ie. HW failure.
      */
@@ -65,6 +65,7 @@ interface ITuner extends @1.0::ITuner {
      *               Client application MUST verify vendor/product name
      *               before setting this parameter to anything else.
      * @return result OK if the list was successfully retrieved.
+     *                INVALID_ARGUMENTS if invalid arguments are passed
      *                NOT_READY if the scan is in progress.
      *                NOT_STARTED if the scan has not been started, client may
      *                call startBackgroundScan to fix this.
@@ -74,4 +75,33 @@ interface ITuner extends @1.0::ITuner {
     getProgramList(string filter)
         generates (ProgramListResult result, vec<ProgramInfo> programList);
 
+    /**
+     * Checks, if the analog playback is forced, see setAnalogForced.
+     *
+     * The isForced value is only valid if result was OK.
+     *
+     * @return result OK if the call succeeded and isForced is valid.
+     *                INVALID_STATE if the switch is not supported at current
+     *                configuration.
+     *                NOT_INITIALIZED if any other error occurs.
+     * @return isForced true if analog is forced, false otherwise.
+     */
+    isAnalogForced() generates (Result result, bool isForced);
+
+    /**
+     * Forces the analog playback for the supporting radio technology.
+     *
+     * User may disable digital playback for FM HD Radio or hybrid FM/DAB with
+     * this option. This is purely user choice, ie. does not reflect digital-
+     * analog handover managed from the HAL implementation side.
+     *
+     * Some radio technologies may not support this, ie. DAB.
+     *
+     * @param isForced true to force analog, false for a default behaviour.
+     * @return result OK if the setting was successfully done.
+     *                INVALID_STATE if the switch is not supported at current
+     *                configuration.
+     *                NOT_INITIALIZED if any other error occurs.
+     */
+    setAnalogForced(bool isForced) generates (Result result);
 };
index 07ce984e95294647891f718eaf773b153fe2b650..158e2170b1f626f6f5e47034a9fb12839dac3172 100644 (file)
@@ -39,12 +39,20 @@ interface ITunerCallback extends @1.0::ITunerCallback {
      */
     oneway afSwitch_1_1(ProgramInfo info);
 
+    /**
+     * Called by the HAL when background scan feature becomes available or not.
+     *
+     * @param isAvailable true, if the tuner turned temporarily background-
+     *                    capable, false in the other case.
+     */
+    oneway backgroundScanAvailable(bool isAvailable);
+
     /**
      * Called by the HAL when background scan initiated by startBackgroundScan
      * finishes. If the list was changed, programListChanged must be called too.
      * @param result OK if the scan succeeded, client may retrieve the actual
      *               list with ITuner::getProgramList.
-     *               TEMPORARILY_UNAVAILABLE if the scan was interrupted due to
+     *               UNAVAILABLE if the scan was interrupted due to
      *               hardware becoming temporarily unavailable.
      *               NOT_INITIALIZED other error, ie. HW failure.
      */
diff --git a/broadcastradio/1.1/default/Android.bp b/broadcastradio/1.1/default/Android.bp
new file mode 100644 (file)
index 0000000..759eb09
--- /dev/null
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+cc_library_shared {
+    name: "android.hardware.broadcastradio@1.1-impl",
+    vendor: true,
+    relative_install_path: "hw",
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+    srcs: [
+        "BroadcastRadio.cpp",
+        "BroadcastRadioFactory.cpp",
+        "Tuner.cpp",
+        "Utils.cpp",
+    ],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libutils",
+        "liblog",
+        "libhardware",
+        "android.hardware.broadcastradio@1.0",
+        "android.hardware.broadcastradio@1.1",
+        "libradio_metadata",
+    ],
+}
diff --git a/broadcastradio/1.1/default/Android.mk b/broadcastradio/1.1/default/Android.mk
deleted file mode 100644 (file)
index bb32d50..0000000
+++ /dev/null
@@ -1,46 +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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.broadcastradio@1.1-impl
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_CFLAGS += -Werror -Wall -Wextra
-LOCAL_SRC_FILES := \
-    BroadcastRadio.cpp \
-    BroadcastRadioFactory.cpp \
-    Tuner.cpp \
-    Utils.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libhidlbase \
-    libhidltransport \
-    libutils \
-    liblog \
-    libhardware \
-    android.hardware.broadcastradio@1.0 \
-    android.hardware.broadcastradio@1.1 \
-    libradio_metadata
-
-ifeq ($(strip $(AUDIOSERVER_MULTILIB)),)
-LOCAL_MULTILIB := 32
-else
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-endif
-
-include $(BUILD_SHARED_LIBRARY)
index f280754c86a5e9fd77b93474f32827c7aa77a7da..ae5848cec71ed5e00bd2bece79d72fdb9f670fdf 100644 (file)
@@ -201,16 +201,27 @@ exit:
 }
 
 Return<ProgramListResult> Tuner::startBackgroundScan() {
-    return ProgramListResult::NOT_INITIALIZED;
+    return ProgramListResult::UNAVAILABLE;
 }
 
 Return<void> Tuner::getProgramList(const hidl_string& filter __unused, getProgramList_cb _hidl_cb) {
     hidl_vec<ProgramInfo> pList;
     // TODO(b/34054813): do the actual implementation.
-    _hidl_cb(ProgramListResult::NOT_INITIALIZED, pList);
+    _hidl_cb(ProgramListResult::NOT_STARTED, pList);
     return Void();
 }
 
+Return<void> Tuner::isAnalogForced(isAnalogForced_cb _hidl_cb) {
+    // TODO(b/34348946): do the actual implementation.
+    _hidl_cb(Result::INVALID_STATE, false);
+    return Void();
+}
+
+Return<Result> Tuner::setAnalogForced(bool isForced __unused) {
+    // TODO(b/34348946): do the actual implementation.
+    return Result::INVALID_STATE;
+}
+
 } // namespace implementation
 }  // namespace V1_1
 }  // namespace broadcastradio
index d7b4545cc7640b9564e49dfa7237380d887da4bf..57eafd3d7cdb8a2e688fc0b8a0e8afa43794206e 100644 (file)
@@ -44,6 +44,8 @@ struct Tuner : public ITuner {
     Return<void> getProgramInformation_1_1(getProgramInformation_1_1_cb _hidl_cb) override;
     Return<ProgramListResult> startBackgroundScan() override;
     Return<void> getProgramList(const hidl_string& filter, getProgramList_cb _hidl_cb) override;
+    Return<void> isAnalogForced(isAnalogForced_cb _hidl_cb) override;
+    Return<Result> setAnalogForced(bool isForced) override;
 
     static void callback(radio_hal_event_t *halEvent, void *cookie);
     void onCallback(radio_hal_event_t *halEvent);
index 3021f2eb19cb6ebdeb7816f15cd14a0b0a9f07e2..5577ea02dabeaa741518d146f384afe093cfb0da 100644 (file)
@@ -23,7 +23,7 @@ typedef @1.0::Result Result;
 enum ProgramListResult : Result {
     NOT_READY,
     NOT_STARTED,
-    TEMPORARILY_UNAVAILABLE,
+    UNAVAILABLE,
 };
 
 /**
@@ -53,6 +53,18 @@ struct Properties {
      * it may not be available though, see startBackgroundScan.
      */
     bool supportsBackgroundScanning;
+
+    /**
+     * Opaque vendor-specific string, to be passed to front-end without changes.
+     * Format of this string can vary across vendors.
+     *
+     * It may be used for extra features, that's not supported by a platform,
+     * for example: "preset-slots=6;ultra-hd-capable=false".
+     *
+     * Front-end application MUST verify vendor/product name from the
+     * @1.0::Properties struct before doing any interpretation of this value.
+     */
+    string vendorExension;
 };
 
 /**
@@ -64,10 +76,14 @@ struct ProgramInfo {
     bitfield<ProgramInfoFlags> flags;
 
     /**
-     * Vendors are allowed to define their own set of flags and store it in this
-     * field. They MUST verify vendor/product name from Properties struct
-     * (IBroadcastRadio::getProperties) before doing any interpretation
-     * of such values.
+     * Opaque vendor-specific string, to be passed to front-end without changes.
+     * Format of this string can vary across vendors.
+     *
+     * It may be used for extra features, that's not supported by a platform,
+     * for example: "paid-service=true;bitrate=320kbps".
+     *
+     * Front-end application MUST verify vendor/product name from the
+     * @1.0::Properties struct before doing any interpretation of this value.
      */
-    uint32_t vendorFlags;
+    string vendorExension;
 };
index d3c05c47fbc6a3c11208def41599e9c0e3d64d1a..aa5ab548f69a22645bd9940ef36aa35cee05daf6 100644 (file)
@@ -129,6 +129,10 @@ class BroadcastRadioHidlTest : public ::testing::VtsHalHidlTargetTestBase {
             return Void();
         }
 
+        virtual Return<void> backgroundScanAvailable(bool isAvailable __unused) {
+            return Void();
+        }
+
         virtual Return<void> backgroundScanComplete(ProgramListResult result __unused) {
             return Void();
         }
index 5cacbf3417848c246b7d5816f64e8873b1895e19..7a315faab3c010d0ede54eed835289ffa98e553c 100644 (file)
@@ -1,7 +1,9 @@
 // This is an autogenerated file, do not edit.
 subdirs = [
     "1.0",
+    "1.0/default",
     "1.0/vts/functional",
     "1.1",
+    "1.1/default",
     "1.1/vts/functional",
 ]
index 5461d826c250728e5bcf424c2d4cd87dcd12d66a..6209cb83a7148f6b22cb312bd0750ee627d18947 100644 (file)
@@ -5,6 +5,7 @@ cc_library_static {
     srcs: [
         "CameraModule.cpp",
         "CameraMetadata.cpp",
+        "CameraParameters.cpp",
         "VendorTagDescriptor.cpp",
         "HandleImporter.cpp"],
     cflags: [
similarity index 99%
rename from camera/provider/2.4/vts/functional/CameraParameters.cpp
rename to camera/common/1.0/default/CameraParameters.cpp
index 97b263b64e95531c6fd47a0690088cc31dcd3b14..d224483c75b978b9b179c55d6ec5993cb1d55489 100644 (file)
 #include <system/graphics.h>
 
 namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace V1_0 {
+namespace helper {
+
 // Parameter keys to communicate between camera application and driver.
 const char CameraParameters::KEY_PREVIEW_SIZE[] = "preview-size";
 const char CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES[] = "preview-size-values";
@@ -534,4 +540,9 @@ bool CameraParameters::isEmpty() const {
     return mMap.isEmpty();
 }
 
+};
+};
+};
+};
+};
 }; // namespace android
similarity index 99%
rename from camera/provider/2.4/vts/functional/CameraParameters.h
rename to camera/common/1.0/default/include/CameraParameters.h
index ba33ffe63b940bcd57d8a35f7edc77ed60e97c34..e4ff6f21c319a0c369bbd8a01d3da2befc0e15d9 100644 (file)
 #include <utils/String8.h>
 
 namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace V1_0 {
+namespace helper {
 
 struct Size {
     int width;
@@ -694,6 +699,11 @@ private:
     DefaultKeyedVector<String8,String8>    mMap;
 };
 
-}; // namespace android
+};
+};
+};
+};
+};
+}; // namespace
 
 #endif
index c68cfc068961f8bb1aea01f7d549c280f85df45d..e47397c6a659bbf3450b9948a0a957025196b64f 100644 (file)
@@ -17,9 +17,9 @@
 #ifndef CAMERA_COMMON_1_0_HANDLEIMPORTED_H
 #define CAMERA_COMMON_1_0_HANDLEIMPORTED_H
 
-#include <system/window.h>
 #include <utils/Mutex.h>
 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <cutils/native_handle.h>
 
 using android::hardware::graphics::mapper::V2_0::IMapper;
 
index f33adf8d1a5296d985a5215be5760b76da362a5e..fcd134f45e1b8cedb10700505b7e07d176ecc8a5 100644 (file)
@@ -923,6 +923,7 @@ Return<void> CameraDeviceSession::configureStreams(
         status = Status::INTERNAL_ERROR;
     } else {
         convertToHidl(stream_list, &outStreams);
+        mFirstRequest = true;
     }
 
     _hidl_cb(status, outStreams);
@@ -1022,7 +1023,13 @@ Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& reque
 
     if (!converted) {
         ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__);
-        return Status::INTERNAL_ERROR;
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
+    if (mFirstRequest && halRequest.settings == nullptr) {
+        ALOGE("%s: capture request settings must not be null for first request!",
+                __FUNCTION__);
+        return Status::ILLEGAL_ARGUMENT;
     }
 
     hidl_vec<buffer_handle_t*> allBufPtrs;
@@ -1031,6 +1038,12 @@ Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& reque
             request.inputBuffer.bufferId != 0);
     size_t numOutputBufs = request.outputBuffers.size();
     size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
+
+    if (numOutputBufs == 0) {
+        ALOGE("%s: capture request must have at least one output buffer!", __FUNCTION__);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
     status = importRequest(request, allBufPtrs, allFences);
     if (status != Status::OK) {
         return status;
@@ -1102,6 +1115,7 @@ Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& reque
         return Status::INTERNAL_ERROR;
     }
 
+    mFirstRequest = false;
     return Status::OK;
 }
 
index fb3fc02a0f997e6aadd78a59495a94cf76e38557..2fe189fde1109b74e4abab543c565d8abac3f45b 100644 (file)
@@ -148,6 +148,7 @@ private:
     static HandleImporter sHandleImporter;
 
     bool mInitFail;
+    bool mFirstRequest = false;
 
     common::V1_0::helper::CameraMetadata mDeviceInfo;
 
index d897fc7110bc2475593faaf3295ad20523babfae..f2a2d2e71e9d4a70334d47fe84059c6e2e1e6dbb 100644 (file)
@@ -38,7 +38,7 @@ cc_binary {
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
-       "libbinder",
+        "libbinder",
         "liblog",
         "libutils",
         "android.hardware.camera.device@1.0",
index 85312c1a5dbcb3561890b133af264cd5f2226317..439fe3dd67fd0819fd98e7e8fb77a25b06c82d6b 100644 (file)
@@ -17,8 +17,7 @@
 cc_test {
     name: "VtsHalCameraProviderV2_4TargetTest",
     defaults: ["hidl_defaults"],
-    srcs: ["VtsHalCameraProviderV2_4TargetTest.cpp",
-           "CameraParameters.cpp" ],
+    srcs: ["VtsHalCameraProviderV2_4TargetTest.cpp"],
     shared_libs: [
         "liblog",
         "libhidlbase",
@@ -31,9 +30,14 @@ cc_test {
         "libcamera_metadata",
         "libbinder",
         "libgui",
-        "libui"
+        "libui",
+        "libfmq",
+    ],
+    static_libs: [
+        "VtsHalHidlTargetTestBase",
+        "libgrallocusage",
+        "android.hardware.camera.common@1.0-helper",
     ],
-    static_libs: ["VtsHalHidlTargetTestBase", "libgrallocusage"],
     cflags: [
         "-O0",
         "-g",
index efec7cba87b5c3d142ce87f60297782d88010c27..6f04efc598fcc25d1c0b663bdbaea3164ec8fb9b 100644 (file)
  */
 
 #define LOG_TAG "camera_hidl_hal_test"
-#include <VtsHalHidlTargetTestBase.h>
+
+#include <chrono>
+#include <mutex>
+#include <regex>
+#include <unordered_map>
+#include <condition_variable>
+
+#include <inttypes.h>
+
 #include <android/hardware/camera/device/1.0/ICameraDevice.h>
 #include <android/hardware/camera/device/3.2/ICameraDevice.h>
 #include <android/hardware/camera/provider/2.4/ICameraProvider.h>
-#include <android/log.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
 #include <binder/MemoryHeapBase.h>
+#include <CameraMetadata.h>
+#include <CameraParameters.h>
+#include <fmq/MessageQueue.h>
 #include <grallocusage/GrallocUsageConversion.h>
 #include <gui/BufferItemConsumer.h>
 #include <gui/BufferQueue.h>
 #include <gui/Surface.h>
 #include <hardware/gralloc.h>
 #include <hardware/gralloc1.h>
-#include <inttypes.h>
 #include <system/camera.h>
+#include <system/camera_metadata.h>
 #include <ui/GraphicBuffer.h>
-#include <utils/Errors.h>
-#include <chrono>
-#include <condition_variable>
-#include <mutex>
-#include <regex>
-#include <unordered_map>
-#include "CameraParameters.h"
-#include "system/camera_metadata.h"
+
+#include <VtsHalHidlTargetTestBase.h>
 
 using ::android::hardware::Return;
 using ::android::hardware::Void;
@@ -52,13 +57,14 @@ using ::android::IGraphicBufferConsumer;
 using ::android::BufferQueue;
 using ::android::BufferItemConsumer;
 using ::android::Surface;
-using ::android::CameraParameters;
 using ::android::hardware::graphics::common::V1_0::BufferUsage;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
 using ::android::hardware::camera::common::V1_0::Status;
 using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
 using ::android::hardware::camera::common::V1_0::TorchMode;
 using ::android::hardware::camera::common::V1_0::TorchModeStatus;
+using ::android::hardware::camera::common::V1_0::helper::CameraParameters;
+using ::android::hardware::camera::common::V1_0::helper::Size;
 using ::android::hardware::camera::provider::V2_4::ICameraProvider;
 using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
 using ::android::hardware::camera::device::V3_2::ICameraDevice;
@@ -89,8 +95,13 @@ using ::android::hardware::camera::device::V1_0::CameraFrameMetadata;
 using ::android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback;
 using ::android::hardware::camera::device::V1_0::FrameCallbackFlag;
 using ::android::hardware::camera::device::V1_0::HandleTimestampMessage;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::kSynchronizedReadWrite;
+using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+using ::android::hidl::manager::V1_0::IServiceManager;
 
 const char kCameraPassthroughServiceName[] = "legacy/0";
+const char *kProviderFQName = "android.hardware.camera.provider@2.4::ICameraProvider";
 const uint32_t kMaxPreviewWidth = 1920;
 const uint32_t kMaxPreviewHeight = 1080;
 const uint32_t kMaxVideoWidth = 4096;
@@ -114,25 +125,41 @@ struct AvailableZSLInputOutput {
 
 namespace {
     // "device@<version>/legacy/<id>"
-    const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/legacy/(.+)";
+    const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
     const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
     const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
     const char *kHAL3_2 = "3.2";
     const char *kHAL1_0 = "1.0";
 
-    bool matchDeviceName(const hidl_string& deviceName, std::smatch& sm) {
-        std::regex e(kDeviceNameRE);
+    bool matchDeviceName(const hidl_string& deviceName,
+            const hidl_string &providerType,
+            std::string* deviceVersion,
+            std::string* cameraId) {
+        ::android::String8 pattern;
+        pattern.appendFormat(kDeviceNameRE, providerType.c_str());
+        std::regex e(pattern.string());
         std::string deviceNameStd(deviceName.c_str());
-        return std::regex_match(deviceNameStd, sm, e);
+        std::smatch sm;
+        if (std::regex_match(deviceNameStd, sm, e)) {
+            if (deviceVersion != nullptr) {
+                *deviceVersion = sm[1];
+            }
+            if (cameraId != nullptr) {
+                *cameraId = sm[2];
+            }
+            return true;
+        }
+        return false;
     }
 
-    int getCameraDeviceVersion(const hidl_string& deviceName) {
-        std::smatch sm;
-        bool match = matchDeviceName(deviceName, sm);
+    int getCameraDeviceVersion(const hidl_string& deviceName,
+            const hidl_string &providerType) {
+        std::string version;
+        bool match = matchDeviceName(deviceName, providerType, &version, nullptr);
         if (!match) {
             return -1;
         }
-        std::string version = sm[1].str();
+
         if (version.compare(kHAL3_2) == 0) {
             // maybe switched to 3.4 or define the hidl version enumlater
             return CAMERA_DEVICE_API_VERSION_3_2;
@@ -142,6 +169,45 @@ namespace {
         return 0;
     }
 
+    bool parseProviderName(const std::string& name, std::string *type /*out*/,
+            uint32_t *id /*out*/) {
+        if (!type || !id) {
+            ADD_FAILURE();
+            return false;
+        }
+
+        std::string::size_type slashIdx = name.find('/');
+        if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
+            ADD_FAILURE() << "Provider name does not have / separator between type"
+                    "and id";
+            return false;
+        }
+
+        std::string typeVal = name.substr(0, slashIdx);
+
+        char *endPtr;
+        errno = 0;
+        long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
+        if (errno != 0) {
+            ADD_FAILURE() << "cannot parse provider id as an integer:" <<
+                    name.c_str() << strerror(errno) << errno;
+            return false;
+        }
+        if (endPtr != name.c_str() + name.size()) {
+            ADD_FAILURE() << "provider id has unexpected length " << name.c_str();
+            return false;
+        }
+        if (idVal < 0) {
+            ADD_FAILURE() << "id is negative: " << name.c_str() << idVal;
+            return false;
+        }
+
+        *type = typeVal;
+        *id = static_cast<uint32_t>(idVal);
+
+        return true;
+    }
+
     Status mapToStatus(::android::status_t s)  {
         switch(s) {
             case ::android::OK:
@@ -176,7 +242,7 @@ public:
     virtual void SetUp() override;
     virtual void TearDown() override;
 
-    sp<ICameraProvider> mProvider;
+    std::unordered_map<std::string, sp<ICameraProvider> > mProviders;
 
 private:
     CameraHidlEnvironment() {}
@@ -185,11 +251,40 @@ private:
 };
 
 void CameraHidlEnvironment::SetUp() {
-    // TODO: test the binderized mode
-    mProvider = ::testing::VtsHalHidlTargetTestBase::getService<ICameraProvider>(kCameraPassthroughServiceName);
-    // TODO: handle the device doesn't have any camera case
-    ALOGI_IF(mProvider, "provider is not nullptr, %p", mProvider.get());
-    ASSERT_NE(mProvider, nullptr);
+    sp<IServiceManager> manager = IServiceManager::getService();
+    ASSERT_NE(manager, nullptr);
+
+    manager->listByInterface(kProviderFQName,
+                             [this](const hidl_vec<hidl_string> &registered) {
+        std::string name;
+        uint32_t id;
+        sp<ICameraProvider> provider = nullptr;
+        for (size_t i = 0; i < registered.size(); i++) {
+            ASSERT_TRUE(parseProviderName(registered[i],
+                    &name /*out*/, &id /*out*/));
+            provider = ICameraProvider::tryGetService(registered[i]);
+            ALOGI_IF(provider, "provider is not nullptr, %p", provider.get());
+            if (nullptr != provider.get()) {
+                mProviders.emplace(name, provider);
+            }
+        }
+    });
+
+    std::string legacyName;
+    uint32_t legacyId;
+    ASSERT_TRUE(parseProviderName(kCameraPassthroughServiceName,
+            &legacyName /*out*/, &legacyId /*out*/));
+    auto legacyIt = mProviders.find(legacyName);
+    //Add any legacy passthrough implementations
+    if (legacyIt == mProviders.end()) {
+        sp<ICameraProvider> provider = ICameraProvider::tryGetService(
+                kCameraPassthroughServiceName);
+        if (nullptr != provider.get()) {
+            mProviders.emplace(legacyName, provider);
+        }
+    }
+
+    ASSERT_FALSE(mProviders.empty());
 }
 
 void CameraHidlEnvironment::TearDown() {
@@ -253,9 +348,7 @@ struct PreviewWindowCb : public ICameraDevicePreviewCallback {
 
             size_t result = 1;
             result = 31 * result + buf->numFds;
-            result = 31 * result + buf->numInts;
-            int length = buf->numFds + buf->numInts;
-            for (int i = 0; i < length; i++) {
+            for (int i = 0; i < buf->numFds; i++) {
                 result = 31 * result + buf->data[i];
             }
             return result;
@@ -265,10 +358,8 @@ struct PreviewWindowCb : public ICameraDevicePreviewCallback {
     struct BufferComparator {
         bool operator()(const buffer_handle_t& buf1,
                 const buffer_handle_t& buf2) const {
-            if ((buf1->numFds == buf2->numFds) &&
-                    (buf1->numInts == buf2->numInts)) {
-                int length = buf1->numFds + buf1->numInts;
-                for (int i = 0; i < length; i++) {
+            if (buf1->numFds == buf2->numFds) {
+                for (int i = 0; i < buf1->numFds; i++) {
                     if (buf1->data[i] != buf2->data[i]) {
                         return false;
                     }
@@ -445,7 +536,7 @@ public:
     virtual void SetUp() override {}
     virtual void TearDown() override {}
 
-    hidl_vec<hidl_string> getCameraDeviceNames();
+    hidl_vec<hidl_string> getCameraDeviceNames(sp<ICameraProvider> provider);
 
     struct EmptyDeviceCb : public ICameraDeviceCallback {
         virtual Return<void> processCaptureResult(const hidl_vec<CaptureResult>& /*results*/) override {
@@ -521,7 +612,7 @@ public:
         CameraHidlTest *mParent;               // Parent object
     };
 
-    void openCameraDevice(const std::string &name,const CameraHidlEnvironment* env,
+    void openCameraDevice(const std::string &name, sp<ICameraProvider> provider,
             sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device /*out*/);
     void setupPreviewWindow(
             const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
@@ -544,15 +635,17 @@ public:
     void waitForFrameLocked(DataCallbackMsg msgFrame,
             std::unique_lock<std::mutex> &l);
     void openEmptyDeviceSession(const std::string &name,
-            const CameraHidlEnvironment* env,
+            sp<ICameraProvider> provider,
             sp<ICameraDeviceSession> *session /*out*/,
             camera_metadata_t **staticMeta /*out*/);
     void configurePreviewStream(const std::string &name,
-            const CameraHidlEnvironment* env,
+            sp<ICameraProvider> provider,
             const AvailableStream *previewThreshold,
             sp<ICameraDeviceSession> *session /*out*/,
             Stream *previewStream /*out*/,
-            HalStreamConfiguration *halStreamConfig /*out*/);
+            HalStreamConfiguration *halStreamConfig /*out*/,
+            bool *supportsPartialResults /*out*/,
+            uint32_t *partialResultCount /*out*/);
     static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
             std::vector<AvailableStream> &outputStreams,
             const AvailableStream *threshold = nullptr);
@@ -566,14 +659,78 @@ public:
             const std::vector<AvailableStream> &streamSizes,
             int32_t format, AvailableStream &result);
     static Status isAutoFocusModeAvailable(
-            ::android::CameraParameters &cameraParams, const char *mode) ;
+            CameraParameters &cameraParams, const char *mode) ;
 
 protected:
+
+    // In-flight queue for tracking completion of capture requests.
+    struct InFlightRequest {
+        // Set by notify() SHUTTER call.
+        nsecs_t shutterTimestamp;
+
+        bool errorCodeValid;
+        ErrorCode errorCode;
+
+        //Is partial result supported
+        bool usePartialResult;
+
+        //Partial result count expected
+        uint32_t numPartialResults;
+
+        // Message queue
+        std::shared_ptr<ResultMetadataQueue> resultQueue;
+
+        // Set by process_capture_result call with valid metadata
+        bool haveResultMetadata;
+
+        // Decremented by calls to process_capture_result with valid output
+        // and input buffers
+        ssize_t numBuffersLeft;
+
+         // A 64bit integer to index the frame number associated with this result.
+        int64_t frameNumber;
+
+         // The partial result count (index) for this capture result.
+        int32_t partialResultCount;
+
+        // For buffer drop errors, the stream ID for the stream that lost a buffer.
+        // Otherwise -1.
+        int32_t errorStreamId;
+
+        // If this request has any input buffer
+        bool hasInputBuffer;
+
+        // Result metadata
+        ::android::hardware::camera::common::V1_0::helper::CameraMetadata collectedResult;
+
+        // Buffers are added by process_capture_result when output buffers
+        // return from HAL but framework.
+        ::android::Vector<StreamBuffer> resultOutputBuffers;
+
+        InFlightRequest(ssize_t numBuffers, bool hasInput,
+                bool partialResults, uint32_t partialCount,
+                std::shared_ptr<ResultMetadataQueue> queue = nullptr) :
+                shutterTimestamp(0),
+                errorCodeValid(false),
+                errorCode(ErrorCode::ERROR_BUFFER),
+                usePartialResult(partialResults),
+                numPartialResults(partialCount),
+                resultQueue(queue),
+                haveResultMetadata(false),
+                numBuffersLeft(numBuffers),
+                frameNumber(0),
+                partialResultCount(0),
+                errorStreamId(-1),
+                hasInputBuffer(hasInput) {}
+    };
+
+    // Map from frame number to the in-flight request state
+    typedef ::android::KeyedVector<uint32_t, InFlightRequest*> InFlightMap;
+
     std::mutex mLock;                          // Synchronize access to member variables
     std::condition_variable mResultCondition;  // Condition variable for incoming results
-    uint32_t mResultFrameNumber;               // Expected result frame number
-    std::vector<StreamBuffer> mResultBuffers;  // Holds stream buffers from capture result
-    std::vector<ErrorMsg> mErrors;             // Holds incoming error notifications
+    InFlightMap mInflightMap;                  // Map of all inflight requests
+
     DataCallbackMsg mDataMessageTypeReceived;  // Most recent message type received through data callbacks
     uint32_t mVideoBufferIndex;                // Buffer index of the most recent video buffer
     uint32_t mVideoData;                       // Buffer data of the most recent video buffer
@@ -696,53 +853,180 @@ Return<void> CameraHidlTest::DeviceCb::processCaptureResult(
         return Void();
     }
 
+    bool notify = false;
     std::unique_lock<std::mutex> l(mParent->mLock);
-    const CaptureResult& result = results[0];
+    for (size_t i = 0 ; i < results.size(); i++) {
+        uint32_t frameNumber = results[i].frameNumber;
+
+        if ((results[i].result.size() == 0) &&
+                (results[i].outputBuffers.size() == 0) &&
+                (results[i].inputBuffer.buffer == nullptr) &&
+                (results[i].fmqResultSize == 0)) {
+            ALOGE("%s: No result data provided by HAL for frame %d result count: %d",
+                  __func__, frameNumber, (int) results[i].fmqResultSize);
+            ADD_FAILURE();
+            break;
+        }
 
-    if(mParent->mResultFrameNumber != result.frameNumber) {
-        ALOGE("%s: Unexpected frame number! Expected: %u received: %u",
-              __func__, mParent->mResultFrameNumber, result.frameNumber);
-        ADD_FAILURE();
-    }
+        ssize_t idx = mParent->mInflightMap.indexOfKey(frameNumber);
+        if (::android::NAME_NOT_FOUND == idx) {
+            ALOGE("%s: Unexpected frame number! received: %u",
+                  __func__, frameNumber);
+            ADD_FAILURE();
+            break;
+        }
 
-    size_t resultLength = result.outputBuffers.size();
-    for (size_t i = 0; i < resultLength; i++) {
-        mParent->mResultBuffers.push_back(result.outputBuffers[i]);
-    }
+        bool isPartialResult = false;
+        bool hasInputBufferInRequest = false;
+        InFlightRequest *request = mParent->mInflightMap.editValueAt(idx);
+        ::android::hardware::camera::device::V3_2::CameraMetadata resultMetadata;
+        size_t resultSize = 0;
+        if (results[i].fmqResultSize > 0) {
+            resultMetadata.resize(results[i].fmqResultSize);
+            if (request->resultQueue == nullptr) {
+                ADD_FAILURE();
+                break;
+            }
+            if (!request->resultQueue->read(resultMetadata.data(),
+                    results[i].fmqResultSize)) {
+                ALOGE("%s: Frame %d: Cannot read camera metadata from fmq,"
+                        "size = %" PRIu64, __func__, frameNumber,
+                        results[i].fmqResultSize);
+                ADD_FAILURE();
+                break;
+            }
+            resultSize = resultMetadata.size();
+        } else if (results[i].result.size() > 0) {
+            resultMetadata.setToExternal(const_cast<uint8_t *>(
+                    results[i].result.data()), results[i].result.size());
+            resultSize = resultMetadata.size();
+        }
+
+        if (!request->usePartialResult && (resultSize > 0) &&
+                (results[i].partialResult != 1)) {
+            ALOGE("%s: Result is malformed for frame %d: partial_result %u "
+                    "must be 1  if partial result is not supported", __func__,
+                    frameNumber, results[i].partialResult);
+            ADD_FAILURE();
+            break;
+        }
+
+        if (results[i].partialResult != 0) {
+            request->partialResultCount = results[i].partialResult;
+        }
+
+        // Check if this result carries only partial metadata
+        if (request->usePartialResult && (resultSize > 0)) {
+            if ((results[i].partialResult > request->numPartialResults) ||
+                    (results[i].partialResult < 1)) {
+                ALOGE("%s: Result is malformed for frame %d: partial_result %u"
+                        " must be  in the range of [1, %d] when metadata is "
+                        "included in the result", __func__, frameNumber,
+                        results[i].partialResult, request->numPartialResults);
+                ADD_FAILURE();
+                break;
+            }
+            request->collectedResult.append(
+                    reinterpret_cast<const camera_metadata_t*>(
+                            resultMetadata.data()));
+
+            isPartialResult =
+                    (results[i].partialResult < request->numPartialResults);
+        }
+
+        hasInputBufferInRequest = request->hasInputBuffer;
+
+        // Did we get the (final) result metadata for this capture?
+        if ((resultSize > 0) && !isPartialResult) {
+            if (request->haveResultMetadata) {
+                ALOGE("%s: Called multiple times with metadata for frame %d",
+                      __func__, frameNumber);
+                ADD_FAILURE();
+                break;
+            }
+            request->haveResultMetadata = true;
+            request->collectedResult.sort();
+        }
+
+        uint32_t numBuffersReturned = results[i].outputBuffers.size();
+        if (results[i].inputBuffer.buffer != nullptr) {
+            if (hasInputBufferInRequest) {
+                numBuffersReturned += 1;
+            } else {
+                ALOGW("%s: Input buffer should be NULL if there is no input"
+                        " buffer sent in the request", __func__);
+            }
+        }
+        request->numBuffersLeft -= numBuffersReturned;
+        if (request->numBuffersLeft < 0) {
+            ALOGE("%s: Too many buffers returned for frame %d", __func__,
+                    frameNumber);
+            ADD_FAILURE();
+            break;
+        }
 
-    // TODO(epeev): Handle partial results in case client supports them and
-    //              verify the result against request settings.
+        request->resultOutputBuffers.appendArray(results[i].outputBuffers.data(),
+                results[i].outputBuffers.size());
+        // If shutter event is received notify the pending threads.
+        if (request->shutterTimestamp != 0) {
+            notify = true;
+        }
+    }
 
     l.unlock();
-    mParent->mResultCondition.notify_one();
+    if (notify) {
+        mParent->mResultCondition.notify_one();
+    }
 
     return Void();
 }
 
 Return<void> CameraHidlTest::DeviceCb::notify(
         const hidl_vec<NotifyMsg>& messages) {
-    const NotifyMsg& message = messages[0];
-
-    if (MsgType::ERROR == message.type) {
-        {
-            std::lock_guard<std::mutex> l(mParent->mLock);
-            mParent->mErrors.push_back(message.msg.error);
+    std::lock_guard<std::mutex> l(mParent->mLock);
+
+    for (size_t i = 0; i < messages.size(); i++) {
+        ssize_t idx = mParent->mInflightMap.indexOfKey(
+                messages[i].msg.shutter.frameNumber);
+        if (::android::NAME_NOT_FOUND == idx) {
+            ALOGE("%s: Unexpected frame number! received: %u",
+                  __func__, messages[i].msg.shutter.frameNumber);
+            ADD_FAILURE();
+            break;
         }
-
-        if ((ErrorCode::ERROR_REQUEST == message.msg.error.errorCode)
-                || (ErrorCode::ERROR_BUFFER == message.msg.error.errorCode)) {
-            mParent->mResultCondition.notify_one();
+        InFlightRequest *r = mParent->mInflightMap.editValueAt(idx);
+
+        switch(messages[i].type) {
+            case MsgType::ERROR:
+                if (ErrorCode::ERROR_DEVICE == messages[i].msg.error.errorCode) {
+                    ALOGE("%s: Camera reported serious device error",
+                          __func__);
+                    ADD_FAILURE();
+                } else {
+                    r->errorCodeValid = true;
+                    r->errorCode = messages[i].msg.error.errorCode;
+                    r->errorStreamId = messages[i].msg.error.errorStreamId;
+                }
+                break;
+            case MsgType::SHUTTER:
+                r->shutterTimestamp = messages[i].msg.shutter.timestamp;
+                break;
+            default:
+                ALOGE("%s: Unsupported notify message %d", __func__,
+                      messages[i].type);
+                ADD_FAILURE();
+                break;
         }
     }
 
+    mParent->mResultCondition.notify_one();
     return Void();
 }
 
-hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames() {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames(sp<ICameraProvider> provider) {
     hidl_vec<hidl_string> cameraDeviceNames;
     Return<void> ret;
-    ret = env->mProvider->getCameraIdList(
+    ret = provider->getCameraIdList(
         [&](auto status, const auto& idList) {
             ALOGI("getCameraIdList returns status:%d", (int)status);
             for (size_t i = 0; i < idList.size(); i++) {
@@ -760,58 +1044,63 @@ hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames() {
 // Test if ICameraProvider::isTorchModeSupported returns Status::OK
 TEST_F(CameraHidlTest, isTorchModeSupported) {
     Return<void> ret;
-    ret = CameraHidlEnvironment::Instance()->mProvider->isSetTorchModeSupported(
-        [&](auto status, bool support) {
-            ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
-                    (int)status, support);
-            ASSERT_EQ(Status::OK, status);
-        });
-    ASSERT_TRUE(ret.isOk());
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        ret = provider.second->isSetTorchModeSupported(
+            [&](auto status, bool support) {
+                ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
+                        (int)status, support);
+                ASSERT_EQ(Status::OK, status);
+            });
+        ASSERT_TRUE(ret.isOk());
+    }
 }
 
 // TODO: consider removing this test if getCameraDeviceNames() has the same coverage
 TEST_F(CameraHidlTest, getCameraIdList) {
     Return<void> ret;
-    ret = CameraHidlEnvironment::Instance()->mProvider->getCameraIdList(
-        [&](auto status, const auto& idList) {
-            ALOGI("getCameraIdList returns status:%d", (int)status);
-            for (size_t i = 0; i < idList.size(); i++) {
-                ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
-            }
-            ASSERT_EQ(Status::OK, status);
-            // This is true for internal camera provider.
-            // Not necessary hold for external cameras providers
-            ASSERT_GT(idList.size(), 0u);
-        });
-    ASSERT_TRUE(ret.isOk());
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        ret = provider.second->getCameraIdList(
+            [&](auto status, const auto& idList) {
+                ALOGI("getCameraIdList returns status:%d", (int)status);
+                for (size_t i = 0; i < idList.size(); i++) {
+                    ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
+                }
+                ASSERT_EQ(Status::OK, status);
+                // This is true for internal camera provider.
+                // Not necessary hold for external cameras providers
+                ASSERT_GT(idList.size(), 0u);
+            });
+        ASSERT_TRUE(ret.isOk());
+    }
 }
 
 // Test if ICameraProvider::getVendorTags returns Status::OK
 TEST_F(CameraHidlTest, getVendorTags) {
     Return<void> ret;
-    ret = CameraHidlEnvironment::Instance()->mProvider->getVendorTags(
-        [&](auto status, const auto& vendorTagSecs) {
-            ALOGI("getVendorTags returns status:%d numSections %zu",
-                    (int)status, vendorTagSecs.size());
-            for (size_t i = 0; i < vendorTagSecs.size(); i++) {
-                ALOGI("Vendor tag section %zu name %s",
-                        i, vendorTagSecs[i].sectionName.c_str());
-                for (size_t j = 0; j < vendorTagSecs[i].tags.size(); j++) {
-                    const auto& tag = vendorTagSecs[i].tags[j];
-                    ALOGI("Vendor tag id %u name %s type %d",
-                            tag.tagId,
-                            tag.tagName.c_str(),
-                            (int) tag.tagType);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        ret = provider.second->getVendorTags(
+            [&](auto status, const auto& vendorTagSecs) {
+                ALOGI("getVendorTags returns status:%d numSections %zu",
+                        (int)status, vendorTagSecs.size());
+                for (size_t i = 0; i < vendorTagSecs.size(); i++) {
+                    ALOGI("Vendor tag section %zu name %s",
+                            i, vendorTagSecs[i].sectionName.c_str());
+                    for (size_t j = 0; j < vendorTagSecs[i].tags.size(); j++) {
+                        const auto& tag = vendorTagSecs[i].tags[j];
+                        ALOGI("Vendor tag id %u name %s type %d",
+                                tag.tagId,
+                                tag.tagName.c_str(),
+                                (int) tag.tagType);
+                    }
                 }
-            }
-            ASSERT_EQ(Status::OK, status);
-        });
-    ASSERT_TRUE(ret.isOk());
+                ASSERT_EQ(Status::OK, status);
+            });
+        ASSERT_TRUE(ret.isOk());
+    }
 }
 
 // Test if ICameraProvider::setCallback returns Status::OK
 TEST_F(CameraHidlTest, setCallback) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
     struct ProviderCb : public ICameraProviderCallback {
         virtual Return<void> cameraDeviceStatusChange(
                 const hidl_string& cameraDeviceName,
@@ -830,37 +1119,49 @@ TEST_F(CameraHidlTest, setCallback) {
         }
     };
     sp<ProviderCb> cb = new ProviderCb;
-    auto status = env->mProvider->setCallback(cb);
-    ASSERT_TRUE(status.isOk());
-    ASSERT_EQ(Status::OK, status);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        auto status = provider.second->setCallback(cb);
+        ASSERT_TRUE(status.isOk());
+        ASSERT_EQ(Status::OK, status);
+        // Reset callback since cb will go out of scope
+        status = provider.second->setCallback(nullptr);
+        ASSERT_TRUE(status.isOk());
+        ASSERT_EQ(Status::OK, status);
+    }
 }
 
 // Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device
 TEST_F(CameraHidlTest, getCameraDeviceInterface) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device3_2) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device3_2, nullptr);
-                });
-            ASSERT_TRUE(ret.isOk());
-        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device1) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device1, nullptr);
-                });
-            ASSERT_TRUE(ret.isOk());
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device3_2) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device3_2, nullptr);
+                    });
+                ASSERT_TRUE(ret.isOk());
+            } else if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device1) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device1, nullptr);
+                    });
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -868,60 +1169,66 @@ TEST_F(CameraHidlTest, getCameraDeviceInterface) {
 // Verify that the device resource cost can be retrieved and the values are
 // sane.
 TEST_F(CameraHidlTest, getResourceCost) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("getResourceCost: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
-
-            ret = device3_2->getResourceCost(
-                [&](auto status, const auto& resourceCost) {
-                    ALOGI("getResourceCost returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ALOGI("    Resource cost is %d", resourceCost.resourceCost);
-                    ASSERT_LE(resourceCost.resourceCost, 100u);
-                    for (const auto& name : resourceCost.conflictingDevices) {
-                        ALOGI("    Conflicting device: %s", name.c_str());
-                    }
-                });
-            ASSERT_TRUE(ret.isOk());
-        } else {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("getResourceCost: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
-
-            ret = device1->getResourceCost(
-                [&](auto status, const auto& resourceCost) {
-                    ALOGI("getResourceCost returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ALOGI("    Resource cost is %d", resourceCost.resourceCost);
-                    ASSERT_LE(resourceCost.resourceCost, 100u);
-                    for (const auto& name : resourceCost.conflictingDevices) {
-                        ALOGI("    Conflicting device: %s", name.c_str());
-                    }
-                });
-            ASSERT_TRUE(ret.isOk());
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                ALOGI("getResourceCost: Testing camera device %s", name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
+
+                ret = device3_2->getResourceCost(
+                    [&](auto status, const auto& resourceCost) {
+                        ALOGI("getResourceCost returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ALOGI("    Resource cost is %d", resourceCost.resourceCost);
+                        ASSERT_LE(resourceCost.resourceCost, 100u);
+                        for (const auto& name : resourceCost.conflictingDevices) {
+                            ALOGI("    Conflicting device: %s", name.c_str());
+                        }
+                    });
+                ASSERT_TRUE(ret.isOk());
+            } else {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("getResourceCost: Testing camera device %s", name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
+
+                ret = device1->getResourceCost(
+                    [&](auto status, const auto& resourceCost) {
+                        ALOGI("getResourceCost returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ALOGI("    Resource cost is %d",
+                              resourceCost.resourceCost);
+                        ASSERT_LE(resourceCost.resourceCost, 100u);
+                        for (const auto& name : resourceCost.conflictingDevices) {
+                            ALOGI("    Conflicting device: %s", name.c_str());
+                        }
+                    });
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -929,126 +1236,143 @@ TEST_F(CameraHidlTest, getResourceCost) {
 // Verify that the static camera info can be retrieved
 // successfully.
 TEST_F(CameraHidlTest, getCameraInfo) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
-
-            ret = device1->getCameraInfo(
-                [&](auto status, const auto& info) {
-                    ALOGI("getCameraInfo returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    switch(info.orientation) {
-                        case 0:
-                        case 90:
-                        case 180:
-                        case 270:
-                            //Expected cases
-                            ALOGI("camera orientation: %d", info.orientation);
-                            break;
-                        default:
-                            FAIL() << "Unexpected camera orientation:" << info.orientation;
-                    }
-                    switch(info.facing) {
-                        case CameraFacing::BACK:
-                        case CameraFacing::FRONT:
-                        case CameraFacing::EXTERNAL:
-                            //Expected cases
-                            ALOGI("camera facing: %d", info.facing);
-                            break;
-                        default:
-                            FAIL() << "Unexpected camera facing:" << static_cast<uint32_t> (info.facing);
-                    }
-                });
-            ASSERT_TRUE(ret.isOk());
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("getCameraCharacteristics: Testing camera device %s",
+                      name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
+
+                ret = device1->getCameraInfo(
+                    [&](auto status, const auto& info) {
+                        ALOGI("getCameraInfo returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        switch(info.orientation) {
+                            case 0:
+                            case 90:
+                            case 180:
+                            case 270:
+                                //Expected cases
+                                ALOGI("camera orientation: %d", info.orientation);
+                                break;
+                            default:
+                                FAIL() << "Unexpected camera orientation:" << info.orientation;
+                        }
+                        switch(info.facing) {
+                            case CameraFacing::BACK:
+                            case CameraFacing::FRONT:
+                            case CameraFacing::EXTERNAL:
+                                //Expected cases
+                                ALOGI("camera facing: %d", info.facing);
+                                break;
+                            default:
+                                FAIL() << "Unexpected camera facing:" << static_cast<uint32_t> (
+                                        info.facing);
+                        }
+                    });
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Check whether preview window can be configured
 TEST_F(CameraHidlTest, setPreviewWindow) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-                    openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1,
-                    &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
-
-            Return<void> ret;
-            ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1,
+                        &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
+
+                Return<void> ret;
+                ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Verify that setting preview window fails in case device is not open
 TEST_F(CameraHidlTest, setPreviewWindowInvalid) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("getCameraCharacteristics: Testing camera device %s",
+                      name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OPERATION_NOT_SUPPORTED, returnStatus);
+                Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OPERATION_NOT_SUPPORTED, returnStatus);
+            }
         }
     }
 }
 
 // Start and stop preview checking whether it gets enabled in between.
 TEST_F(CameraHidlTest, startStopPreview) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-                    openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1,
-                    &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
-
-            startPreview(device1);
-
-            Return<bool> returnBoolStatus = device1->previewEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_TRUE(returnBoolStatus);
-
-            stopPreviewAndClose(device1);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1,
+                        &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
+
+                startPreview(device1);
+
+                Return<bool> returnBoolStatus = device1->previewEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_TRUE(returnBoolStatus);
+
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
@@ -1056,599 +1380,646 @@ TEST_F(CameraHidlTest, startStopPreview) {
 // Start preview without active preview window. Preview should start as soon
 // as a valid active window gets configured.
 TEST_F(CameraHidlTest, startStopPreviewDelayed) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-
-            Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+
+                Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            startPreview(device1);
+                startPreview(device1);
 
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
 
-            //Preview should get enabled now
-            Return<bool> returnBoolStatus = device1->previewEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_TRUE(returnBoolStatus);
+                //Preview should get enabled now
+                Return<bool> returnBoolStatus = device1->previewEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_TRUE(returnBoolStatus);
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // Verify that image capture behaves as expected along with preview callbacks.
 TEST_F(CameraHidlTest, takePicture) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
-            }
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
 
-            enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
-            startPreview(device1);
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                }
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
-            }
+                enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
+                              device1);
+                startPreview(device1);
 
-            disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
-                            device1);
-            enableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
-                    device1);
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
+                }
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
-            }
+                disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
+                                device1);
+                enableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
+                        device1);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                }
 
-            Return<Status> returnStatus = device1->takePicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                Return<Status> returnStatus = device1->takePicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                waitForFrameLocked(DataCallbackMsg::COMPRESSED_IMAGE, l);
-            }
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    waitForFrameLocked(DataCallbackMsg::COMPRESSED_IMAGE, l);
+                }
 
-            disableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
-                    device1);
-            stopPreviewAndClose(device1);
+                disableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
+                        device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // Image capture should fail in case preview didn't get enabled first.
 TEST_F(CameraHidlTest, takePictureFail) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-
-            Return<Status> returnStatus = device1->takePicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_NE(Status::OK, returnStatus);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+
+                Return<Status> returnStatus = device1->takePicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_NE(Status::OK, returnStatus);
 
-            Return<void> ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
+                Return<void> ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Verify that image capture can be cancelled.
 TEST_F(CameraHidlTest, cancelPicture) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
-
-            Return<Status> returnStatus = device1->takePicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
+
+                Return<Status> returnStatus = device1->takePicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            returnStatus = device1->cancelPicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                returnStatus = device1->cancelPicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
-// Image capture cancel should fail when image capture is not running.
-TEST_F(CameraHidlTest, cancelPictureFail) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+// Image capture cancel is a no-op when image capture is not running.
+TEST_F(CameraHidlTest, cancelPictureNOP) {
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
 
-            Return<Status> returnStatus = device1->cancelPicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_NE(Status::OK, returnStatus);
+                Return<Status> returnStatus = device1->cancelPicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // Test basic video recording.
 TEST_F(CameraHidlTest, startStopRecording) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
-            }
-
-            enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
-            startPreview(device1);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
-                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
-                mVideoBufferIndex = UINT32_MAX;
-            }
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                }
 
-            disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
+                enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
+                        device1);
+                startPreview(device1);
 
-            bool videoMetaEnabled = false;
-            Return<Status> returnStatus = device1->storeMetaDataInBuffers(true);
-            ASSERT_TRUE(returnStatus.isOk());
-            // It is allowed for devices to not support this feature
-            ASSERT_TRUE((Status::OK == returnStatus) ||
-                    (Status::OPERATION_NOT_SUPPORTED == returnStatus));
-            if (Status::OK == returnStatus) {
-                videoMetaEnabled = true;
-            }
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
+                    mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                    mVideoBufferIndex = UINT32_MAX;
+                }
 
-            enableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, device1);
-            Return<bool> returnBoolStatus = device1->recordingEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_FALSE(returnBoolStatus);
+                disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
+                        device1);
 
-            returnStatus = device1->startRecording();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                bool videoMetaEnabled = false;
+                Return<Status> returnStatus = device1->storeMetaDataInBuffers(
+                        true);
+                ASSERT_TRUE(returnStatus.isOk());
+                // It is allowed for devices to not support this feature
+                ASSERT_TRUE((Status::OK == returnStatus) ||
+                        (Status::OPERATION_NOT_SUPPORTED == returnStatus));
+                if (Status::OK == returnStatus) {
+                    videoMetaEnabled = true;
+                }
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                waitForFrameLocked(DataCallbackMsg::VIDEO_FRAME, l);
-                ASSERT_NE(UINT32_MAX, mVideoBufferIndex);
-                disableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME,
+                enableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME,
                         device1);
-            }
+                Return<bool> returnBoolStatus = device1->recordingEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_FALSE(returnBoolStatus);
 
-            returnBoolStatus = device1->recordingEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_TRUE(returnBoolStatus);
+                returnStatus = device1->startRecording();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            Return<void> ret;
-            if (videoMetaEnabled) {
-                ret = device1->releaseRecordingFrameHandle(mVideoData,
-                        mVideoBufferIndex, mVideoNativeHandle);
-                ASSERT_TRUE(ret.isOk());
-            } else {
-                ret = device1->releaseRecordingFrame(mVideoData, mVideoBufferIndex);
-                ASSERT_TRUE(ret.isOk());
-            }
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    waitForFrameLocked(DataCallbackMsg::VIDEO_FRAME, l);
+                    ASSERT_NE(UINT32_MAX, mVideoBufferIndex);
+                    disableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME,
+                            device1);
+                }
+
+                returnBoolStatus = device1->recordingEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_TRUE(returnBoolStatus);
+
+                Return<void> ret;
+                if (videoMetaEnabled) {
+                    ret = device1->releaseRecordingFrameHandle(mVideoData,
+                            mVideoBufferIndex, mVideoNativeHandle);
+                    ASSERT_TRUE(ret.isOk());
+                } else {
+                    ret = device1->releaseRecordingFrame(mVideoData,
+                            mVideoBufferIndex);
+                    ASSERT_TRUE(ret.isOk());
+                }
 
-            ret = device1->stopRecording();
-            ASSERT_TRUE(ret.isOk());
+                ret = device1->stopRecording();
+                ASSERT_TRUE(ret.isOk());
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // It shouldn't be possible to start recording without enabling preview first.
 TEST_F(CameraHidlTest, startRecordingFail) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-
-            Return<bool> returnBoolStatus = device1->recordingEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_FALSE(returnBoolStatus);
-
-            Return<Status> returnStatus = device1->startRecording();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_NE(Status::OK, returnStatus);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+
+                Return<bool> returnBoolStatus = device1->recordingEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_FALSE(returnBoolStatus);
+
+                Return<Status> returnStatus = device1->startRecording();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_NE(Status::OK, returnStatus);
 
-            Return<void> ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
-        }
+                Return<void> ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+            }
+        }
     }
 }
 
 // Check autofocus support if available.
 TEST_F(CameraHidlTest, autoFocus) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<const char *> focusModes = {CameraParameters::FOCUS_MODE_AUTO,
-            CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
-            CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO};
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-
-            ::android::CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
-
-            if (Status::OK != isAutoFocusModeAvailable(cameraParams,
-                    CameraParameters::FOCUS_MODE_AUTO)) {
-                Return<void> ret = device1->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
-            }
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<const char *> focusModes = {CameraParameters::FOCUS_MODE_AUTO,
+                CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
+                CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO};
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
 
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
-            enableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
-
-            for (auto &iter : focusModes) {
                 if (Status::OK != isAutoFocusModeAvailable(cameraParams,
-                        iter)) {
+                        CameraParameters::FOCUS_MODE_AUTO)) {
+                    Return<void> ret = device1->close();
+                    ASSERT_TRUE(ret.isOk());
                     continue;
                 }
 
-                cameraParams.set(CameraParameters::KEY_FOCUS_MODE, iter);
-                setParameters(device1, cameraParams);
-                {
-                    std::unique_lock<std::mutex> l(mLock);
-                    mNotifyMessage = NotifyCallbackMsg::ERROR;
-                }
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
+                enableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
+
+                for (auto &iter : focusModes) {
+                    if (Status::OK != isAutoFocusModeAvailable(cameraParams,
+                            iter)) {
+                        continue;
+                    }
 
-                Return<Status> returnStatus = device1->autoFocus();
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
+                    cameraParams.set(CameraParameters::KEY_FOCUS_MODE, iter);
+                    setParameters(device1, cameraParams);
+                    {
+                        std::unique_lock<std::mutex> l(mLock);
+                        mNotifyMessage = NotifyCallbackMsg::ERROR;
+                    }
 
-                {
-                    std::unique_lock<std::mutex> l(mLock);
-                    while (NotifyCallbackMsg::FOCUS != mNotifyMessage) {
-                        auto timeout = std::chrono::system_clock::now() +
-                                std::chrono::seconds(kAutoFocusTimeoutSec);
-                        ASSERT_NE(std::cv_status::timeout,
-                                mResultCondition.wait_until(l, timeout));
+                    Return<Status> returnStatus = device1->autoFocus();
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+
+                    {
+                        std::unique_lock<std::mutex> l(mLock);
+                        while (NotifyCallbackMsg::FOCUS != mNotifyMessage) {
+                            auto timeout = std::chrono::system_clock::now() +
+                                    std::chrono::seconds(kAutoFocusTimeoutSec);
+                            ASSERT_NE(std::cv_status::timeout,
+                                    mResultCondition.wait_until(l, timeout));
+                        }
                     }
                 }
-            }
 
-            disableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
-            stopPreviewAndClose(device1);
+                disableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // In case autofocus is supported verify that it can be cancelled.
 TEST_F(CameraHidlTest, cancelAutoFocus) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            ::android::CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
 
-            if (Status::OK != isAutoFocusModeAvailable(cameraParams,
-                    CameraParameters::FOCUS_MODE_AUTO)) {
-                Return<void> ret = device1->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
-            }
+                if (Status::OK != isAutoFocusModeAvailable(cameraParams,
+                        CameraParameters::FOCUS_MODE_AUTO)) {
+                    Return<void> ret = device1->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
 
-            // It should be fine to call before preview starts.
-            ASSERT_EQ(Status::OK, device1->cancelAutoFocus());
+                // It should be fine to call before preview starts.
+                ASSERT_EQ(Status::OK, device1->cancelAutoFocus());
 
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
 
-            // It should be fine to call after preview starts too.
-            Return<Status> returnStatus = device1->cancelAutoFocus();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                // It should be fine to call after preview starts too.
+                Return<Status> returnStatus = device1->cancelAutoFocus();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            returnStatus = device1->autoFocus();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                returnStatus = device1->autoFocus();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            returnStatus = device1->cancelAutoFocus();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                returnStatus = device1->cancelAutoFocus();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // Check whether face detection is available and try to enable&disable.
 TEST_F(CameraHidlTest, sendCommandFaceDetection) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-
-            ::android::CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
-
-            int32_t hwFaces = cameraParams.getInt(
-                    CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW);
-            int32_t swFaces = cameraParams.getInt(
-                    CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW);
-            if ((0 >= hwFaces) && (0 >= swFaces)) {
-                Return<void> ret = device1->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
-            }
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
+
+                int32_t hwFaces = cameraParams.getInt(
+                        CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW);
+                int32_t swFaces = cameraParams.getInt(
+                        CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW);
+                if ((0 >= hwFaces) && (0 >= swFaces)) {
+                    Return<void> ret = device1->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
 
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
 
-            if (0 < hwFaces) {
-                Return<Status> returnStatus = device1->sendCommand(
-                        CommandType::START_FACE_DETECTION,
-                        CAMERA_FACE_DETECTION_HW, 0);
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
-                // TODO(epeev) : Enable and check for face notifications
-                returnStatus = device1->sendCommand(
-                        CommandType::STOP_FACE_DETECTION,
-                        CAMERA_FACE_DETECTION_HW, 0);
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
-            }
+                if (0 < hwFaces) {
+                    Return<Status> returnStatus = device1->sendCommand(
+                            CommandType::START_FACE_DETECTION,
+                            CAMERA_FACE_DETECTION_HW, 0);
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+                    // TODO(epeev) : Enable and check for face notifications
+                    returnStatus = device1->sendCommand(
+                            CommandType::STOP_FACE_DETECTION,
+                            CAMERA_FACE_DETECTION_HW, 0);
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+                }
 
-            if (0 < swFaces) {
-                Return<Status> returnStatus = device1->sendCommand(
-                        CommandType::START_FACE_DETECTION,
-                        CAMERA_FACE_DETECTION_SW, 0);
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
-                // TODO(epeev) : Enable and check for face notifications
-                returnStatus = device1->sendCommand(
-                        CommandType::STOP_FACE_DETECTION,
-                        CAMERA_FACE_DETECTION_SW, 0);
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
-            }
+                if (0 < swFaces) {
+                    Return<Status> returnStatus = device1->sendCommand(
+                            CommandType::START_FACE_DETECTION,
+                            CAMERA_FACE_DETECTION_SW, 0);
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+                    // TODO(epeev) : Enable and check for face notifications
+                    returnStatus = device1->sendCommand(
+                            CommandType::STOP_FACE_DETECTION,
+                            CAMERA_FACE_DETECTION_SW, 0);
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+                }
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // Check whether smooth zoom is available and try to enable&disable.
 TEST_F(CameraHidlTest, sendCommandSmoothZoom) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-
-            ::android::CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
-
-            const char *smoothZoomStr = cameraParams.get(
-                    CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED);
-            bool smoothZoomSupported = ((nullptr != smoothZoomStr) &&
-                    (strcmp(smoothZoomStr, CameraParameters::TRUE) == 0)) ?
-                            true : false;
-            if (!smoothZoomSupported) {
-                Return<void> ret = device1->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
-            }
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
+
+                const char *smoothZoomStr = cameraParams.get(
+                        CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED);
+                bool smoothZoomSupported = ((nullptr != smoothZoomStr) &&
+                        (strcmp(smoothZoomStr, CameraParameters::TRUE) == 0)) ?
+                                true : false;
+                if (!smoothZoomSupported) {
+                    Return<void> ret = device1->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
 
-            int32_t maxZoom = cameraParams.getInt(
-                    CameraParameters::KEY_MAX_ZOOM);
-            ASSERT_TRUE(0 < maxZoom);
+                int32_t maxZoom = cameraParams.getInt(
+                        CameraParameters::KEY_MAX_ZOOM);
+                ASSERT_TRUE(0 < maxZoom);
 
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
-            setParameters(device1, cameraParams);
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
+                setParameters(device1, cameraParams);
 
-            Return<Status> returnStatus = device1->sendCommand(
-                    CommandType::START_SMOOTH_ZOOM, maxZoom, 0);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-            // TODO(epeev) : Enable and check for face notifications
-            returnStatus = device1->sendCommand(CommandType::STOP_SMOOTH_ZOOM,
-                    0, 0);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                Return<Status> returnStatus = device1->sendCommand(
+                        CommandType::START_SMOOTH_ZOOM, maxZoom, 0);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+                // TODO(epeev) : Enable and check for face notifications
+                returnStatus = device1->sendCommand(
+                        CommandType::STOP_SMOOTH_ZOOM, 0, 0);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // Basic sanity tests related to camera parameters.
 TEST_F(CameraHidlTest, getSetParameters) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-
-            ::android::CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
-
-            int32_t width, height;
-            cameraParams.getPictureSize(&width, &height);
-            ASSERT_TRUE((0 < width) && (0 < height));
-            cameraParams.getPreviewSize(&width, &height);
-            ASSERT_TRUE((0 < width) && (0 < height));
-            int32_t minFps, maxFps;
-            cameraParams.getPreviewFpsRange(&minFps, &maxFps);
-            ASSERT_TRUE((0 < minFps) && (0 < maxFps));
-            ASSERT_NE(nullptr, cameraParams.getPreviewFormat());
-            ASSERT_NE(nullptr, cameraParams.getPictureFormat());
-            ASSERT_TRUE(strcmp(CameraParameters::PIXEL_FORMAT_JPEG,
-                    cameraParams.getPictureFormat()) == 0);
-
-            const char *flashMode = cameraParams.get(
-                    CameraParameters::KEY_FLASH_MODE);
-            ASSERT_TRUE((nullptr == flashMode) || (strcmp(
-                    CameraParameters::FLASH_MODE_OFF, flashMode) == 0));
-
-            const char *wbMode = cameraParams.get(
-                    CameraParameters::KEY_WHITE_BALANCE);
-            ASSERT_TRUE((nullptr == wbMode) || (strcmp(
-                    CameraParameters::WHITE_BALANCE_AUTO, wbMode) == 0));
-
-            const char *effect = cameraParams.get(CameraParameters::KEY_EFFECT);
-            ASSERT_TRUE((nullptr == effect) || (strcmp(
-                    CameraParameters::EFFECT_NONE, effect) == 0));
-
-            ::android::Vector<::android::Size> previewSizes;
-            cameraParams.getSupportedPreviewSizes(previewSizes);
-            ASSERT_FALSE(previewSizes.empty());
-            ::android::Vector<::android::Size> pictureSizes;
-            cameraParams.getSupportedPictureSizes(pictureSizes);
-            ASSERT_FALSE(pictureSizes.empty());
-            const char *previewFormats = cameraParams.get(
-                    CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
-            ASSERT_NE(nullptr, previewFormats);
-            ::android::String8 previewFormatsString(previewFormats);
-            ASSERT_TRUE(previewFormatsString.contains(
-                    CameraParameters::PIXEL_FORMAT_YUV420SP));
-            ASSERT_NE(nullptr, cameraParams.get(
-                    CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
-            ASSERT_NE(nullptr, cameraParams.get(
-                    CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
-            const char *focusModes = cameraParams.get(
-                    CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
-            ASSERT_NE(nullptr, focusModes);
-            ::android::String8 focusModesString(focusModes);
-            const char *focusMode = cameraParams.get(
-                    CameraParameters::KEY_FOCUS_MODE);
-            ASSERT_NE(nullptr, focusMode);
-            // Auto focus mode should be default
-            if (focusModesString.contains(CameraParameters::FOCUS_MODE_AUTO)) {
-                ASSERT_TRUE(strcmp(
-                        CameraParameters::FOCUS_MODE_AUTO, focusMode) == 0);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
+
+                int32_t width, height;
+                cameraParams.getPictureSize(&width, &height);
+                ASSERT_TRUE((0 < width) && (0 < height));
+                cameraParams.getPreviewSize(&width, &height);
+                ASSERT_TRUE((0 < width) && (0 < height));
+                int32_t minFps, maxFps;
+                cameraParams.getPreviewFpsRange(&minFps, &maxFps);
+                ASSERT_TRUE((0 < minFps) && (0 < maxFps));
+                ASSERT_NE(nullptr, cameraParams.getPreviewFormat());
+                ASSERT_NE(nullptr, cameraParams.getPictureFormat());
+                ASSERT_TRUE(strcmp(CameraParameters::PIXEL_FORMAT_JPEG,
+                        cameraParams.getPictureFormat()) == 0);
+
+                const char *flashMode = cameraParams.get(
+                        CameraParameters::KEY_FLASH_MODE);
+                ASSERT_TRUE((nullptr == flashMode) || (strcmp(
+                        CameraParameters::FLASH_MODE_OFF, flashMode) == 0));
+
+                const char *wbMode = cameraParams.get(
+                        CameraParameters::KEY_WHITE_BALANCE);
+                ASSERT_TRUE((nullptr == wbMode) || (strcmp(
+                        CameraParameters::WHITE_BALANCE_AUTO, wbMode) == 0));
+
+                const char *effect = cameraParams.get(
+                        CameraParameters::KEY_EFFECT);
+                ASSERT_TRUE((nullptr == effect) || (strcmp(
+                        CameraParameters::EFFECT_NONE, effect) == 0));
+
+                ::android::Vector<Size> previewSizes;
+                cameraParams.getSupportedPreviewSizes(previewSizes);
+                ASSERT_FALSE(previewSizes.empty());
+                ::android::Vector<Size> pictureSizes;
+                cameraParams.getSupportedPictureSizes(pictureSizes);
+                ASSERT_FALSE(pictureSizes.empty());
+                const char *previewFormats = cameraParams.get(
+                        CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
+                ASSERT_NE(nullptr, previewFormats);
+                ::android::String8 previewFormatsString(previewFormats);
+                ASSERT_TRUE(previewFormatsString.contains(
+                        CameraParameters::PIXEL_FORMAT_YUV420SP));
+                ASSERT_NE(nullptr, cameraParams.get(
+                        CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
+                ASSERT_NE(nullptr, cameraParams.get(
+                        CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
+                const char *focusModes = cameraParams.get(
+                        CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
+                ASSERT_NE(nullptr, focusModes);
+                ::android::String8 focusModesString(focusModes);
+                const char *focusMode = cameraParams.get(
+                        CameraParameters::KEY_FOCUS_MODE);
+                ASSERT_NE(nullptr, focusMode);
+                // Auto focus mode should be default
+                if (focusModesString.contains(
+                        CameraParameters::FOCUS_MODE_AUTO)) {
+                    ASSERT_TRUE(strcmp(
+                            CameraParameters::FOCUS_MODE_AUTO, focusMode) == 0);
+                }
+                ASSERT_TRUE(0 < cameraParams.getInt(
+                        CameraParameters::KEY_FOCAL_LENGTH));
+                int32_t horizontalViewAngle = cameraParams.getInt(
+                        CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE);
+                ASSERT_TRUE((0 < horizontalViewAngle) &&
+                            (360 >= horizontalViewAngle));
+                int32_t verticalViewAngle = cameraParams.getInt(
+                        CameraParameters::KEY_VERTICAL_VIEW_ANGLE);
+                ASSERT_TRUE((0 < verticalViewAngle) &&
+                            (360 >= verticalViewAngle));
+                int32_t jpegQuality = cameraParams.getInt(
+                        CameraParameters::KEY_JPEG_QUALITY);
+                ASSERT_TRUE((1 <= jpegQuality) && (100 >= jpegQuality));
+                int32_t jpegThumbQuality = cameraParams.getInt(
+                        CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
+                ASSERT_TRUE((1 <= jpegThumbQuality) &&
+                            (100 >= jpegThumbQuality));
+
+                cameraParams.setPictureSize(pictureSizes[0].width,
+                        pictureSizes[0].height);
+                cameraParams.setPreviewSize(previewSizes[0].width,
+                        previewSizes[0].height);
+
+                setParameters(device1, cameraParams);
+                getParameters(device1, &cameraParams /*out*/);
+
+                cameraParams.getPictureSize(&width, &height);
+                ASSERT_TRUE((pictureSizes[0].width == width) &&
+                        (pictureSizes[0].height == height));
+                cameraParams.getPreviewSize(&width, &height);
+                ASSERT_TRUE((previewSizes[0].width == width) &&
+                        (previewSizes[0].height == height));
+
+                Return<void> ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
             }
-            ASSERT_TRUE(0 < cameraParams.getInt(
-                    CameraParameters::KEY_FOCAL_LENGTH));
-            int32_t horizontalViewAngle = cameraParams.getInt(
-                    CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE);
-            ASSERT_TRUE((0 < horizontalViewAngle) && (360 >= horizontalViewAngle));
-            int32_t verticalViewAngle = cameraParams.getInt(
-                    CameraParameters::KEY_VERTICAL_VIEW_ANGLE);
-            ASSERT_TRUE((0 < verticalViewAngle) && (360 >= verticalViewAngle));
-            int32_t jpegQuality = cameraParams.getInt(
-                    CameraParameters::KEY_JPEG_QUALITY);
-            ASSERT_TRUE((1 <= jpegQuality) && (100 >= jpegQuality));
-            int32_t jpegThumbQuality = cameraParams.getInt(
-                    CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
-            ASSERT_TRUE((1 <= jpegThumbQuality) && (100 >= jpegThumbQuality));
-
-            cameraParams.setPictureSize(pictureSizes[0].width,
-                    pictureSizes[0].height);
-            cameraParams.setPreviewSize(previewSizes[0].width,
-                    previewSizes[0].height);
-
-            setParameters(device1, cameraParams);
-            getParameters(device1, &cameraParams /*out*/);
-
-            cameraParams.getPictureSize(&width, &height);
-            ASSERT_TRUE((pictureSizes[0].width == width) &&
-                    (pictureSizes[0].height == height));
-            cameraParams.getPreviewSize(&width, &height);
-            ASSERT_TRUE((previewSizes[0].width == width) &&
-                    (previewSizes[0].height == height));
-
-            Return<void> ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -1656,39 +2027,50 @@ TEST_F(CameraHidlTest, getSetParameters) {
 // Verify that the static camera characteristics can be retrieved
 // successfully.
 TEST_F(CameraHidlTest, getCameraCharacteristics) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
-
-            ret = device3_2->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);
-                });
-            ASSERT_TRUE(ret.isOk());
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                ALOGI("getCameraCharacteristics: Testing camera device %s",
+                      name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
+
+                ret = device3_2->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);
+                    });
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -1696,252 +2078,273 @@ TEST_F(CameraHidlTest, getCameraCharacteristics) {
 //In case it is supported verify that torch can be enabled.
 //Check for corresponding toch callbacks as well.
 TEST_F(CameraHidlTest, setTorchMode) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    bool torchControlSupported = false;
-    Return<void> ret;
-
-    ret = CameraHidlEnvironment::Instance()->mProvider->isSetTorchModeSupported(
-        [&](auto status, bool support) {
-            ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
-                    (int)status, support);
-            ASSERT_EQ(Status::OK, status);
-            torchControlSupported = support;
-        });
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        bool torchControlSupported = false;
+        Return<void> ret;
+
+        ret = provider.second->isSetTorchModeSupported(
+            [&](auto status, bool support) {
+                ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
+                        (int)status, support);
+                ASSERT_EQ(Status::OK, status);
+                torchControlSupported = support;
+            });
 
 
-    sp<TorchProviderCb> cb = new TorchProviderCb(this);
-    Return<Status> returnStatus = env->mProvider->setCallback(cb);
-    ASSERT_TRUE(returnStatus.isOk());
-    ASSERT_EQ(Status::OK, returnStatus);
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("setTorchMode: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        sp<TorchProviderCb> cb = new TorchProviderCb(this);
+        Return<Status> returnStatus = provider.second->setCallback(cb);
+        ASSERT_TRUE(returnStatus.isOk());
+        ASSERT_EQ(Status::OK, returnStatus);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                ALOGI("setTorchMode: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
-            returnStatus = device3_2->setTorchMode(TorchMode::ON);
-            ASSERT_TRUE(returnStatus.isOk());
-            if (!torchControlSupported) {
-                ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
-            } else {
-                ASSERT_TRUE(returnStatus == Status::OK ||
-                            returnStatus == Status::OPERATION_NOT_SUPPORTED);
-                if (returnStatus == Status::OK) {
-                    {
-                        std::unique_lock<std::mutex> l(mTorchLock);
-                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
-                            auto timeout = std::chrono::system_clock::now() +
-                                    std::chrono::seconds(kTorchTimeoutSec);
-                            ASSERT_NE(std::cv_status::timeout,
-                                    mTorchCond.wait_until(l, timeout));
+                mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
+                returnStatus = device3_2->setTorchMode(TorchMode::ON);
+                ASSERT_TRUE(returnStatus.isOk());
+                if (!torchControlSupported) {
+                    ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
+                } else {
+                    ASSERT_TRUE(returnStatus == Status::OK ||
+                                returnStatus == Status::OPERATION_NOT_SUPPORTED);
+                    if (returnStatus == Status::OK) {
+                        {
+                            std::unique_lock<std::mutex> l(mTorchLock);
+                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                                auto timeout = std::chrono::system_clock::now() +
+                                        std::chrono::seconds(kTorchTimeoutSec);
+                                ASSERT_NE(std::cv_status::timeout,
+                                        mTorchCond.wait_until(l, timeout));
+                            }
+                            ASSERT_EQ(TorchModeStatus::AVAILABLE_ON,
+                                    mTorchStatus);
+                            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
                         }
-                        ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
-                        mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
-                    }
 
-                    returnStatus = device3_2->setTorchMode(TorchMode::OFF);
-                    ASSERT_TRUE(returnStatus.isOk());
-                    ASSERT_EQ(Status::OK, returnStatus);
-
-                    {
-                        std::unique_lock<std::mutex> l(mTorchLock);
-                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
-                            auto timeout = std::chrono::system_clock::now() +
-                                    std::chrono::seconds(kTorchTimeoutSec);
-                            ASSERT_NE(std::cv_status::timeout,
-                                    mTorchCond.wait_until(l, timeout));
+                        returnStatus = device3_2->setTorchMode(TorchMode::OFF);
+                        ASSERT_TRUE(returnStatus.isOk());
+                        ASSERT_EQ(Status::OK, returnStatus);
+
+                        {
+                            std::unique_lock<std::mutex> l(mTorchLock);
+                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                                auto timeout = std::chrono::system_clock::now() +
+                                        std::chrono::seconds(kTorchTimeoutSec);
+                                ASSERT_NE(std::cv_status::timeout,
+                                        mTorchCond.wait_until(l, timeout));
+                            }
+                            ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF,
+                                    mTorchStatus);
                         }
-                        ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
                     }
                 }
-            }
-        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("dumpState: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+            } else if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("dumpState: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
-            returnStatus = device1->setTorchMode(TorchMode::ON);
-            ASSERT_TRUE(returnStatus.isOk());
-            if (!torchControlSupported) {
-                ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
-            } else {
-                ASSERT_TRUE(returnStatus == Status::OK ||
-                            returnStatus == Status::OPERATION_NOT_SUPPORTED);
-                if (returnStatus == Status::OK) {
-                    {
-                        std::unique_lock<std::mutex> l(mTorchLock);
-                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
-                            auto timeout = std::chrono::system_clock::now() +
-                                    std::chrono::seconds(kTorchTimeoutSec);
-                            ASSERT_NE(std::cv_status::timeout,
-                                    mTorchCond.wait_until(l, timeout));
+                mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
+                returnStatus = device1->setTorchMode(TorchMode::ON);
+                ASSERT_TRUE(returnStatus.isOk());
+                if (!torchControlSupported) {
+                    ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
+                } else {
+                    ASSERT_TRUE(returnStatus == Status::OK ||
+                                returnStatus == Status::OPERATION_NOT_SUPPORTED);
+                    if (returnStatus == Status::OK) {
+                        {
+                            std::unique_lock<std::mutex> l(mTorchLock);
+                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                                auto timeout = std::chrono::system_clock::now() +
+                                        std::chrono::seconds(kTorchTimeoutSec);
+                                ASSERT_NE(std::cv_status::timeout,
+                                        mTorchCond.wait_until(l, timeout));
+                            }
+                            ASSERT_EQ(TorchModeStatus::AVAILABLE_ON,
+                                    mTorchStatus);
+                            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
                         }
-                        ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
-                        mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
-                    }
-
-                    returnStatus = device1->setTorchMode(TorchMode::OFF);
-                    ASSERT_TRUE(returnStatus.isOk());
-                    ASSERT_EQ(Status::OK, returnStatus);
 
-                    {
-                        std::unique_lock<std::mutex> l(mTorchLock);
-                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
-                            auto timeout = std::chrono::system_clock::now() +
-                                    std::chrono::seconds(kTorchTimeoutSec);
-                            ASSERT_NE(std::cv_status::timeout,
-                                    mTorchCond.wait_until(l, timeout));
+                        returnStatus = device1->setTorchMode(TorchMode::OFF);
+                        ASSERT_TRUE(returnStatus.isOk());
+                        ASSERT_EQ(Status::OK, returnStatus);
+
+                        {
+                            std::unique_lock<std::mutex> l(mTorchLock);
+                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                                auto timeout = std::chrono::system_clock::now() +
+                                        std::chrono::seconds(kTorchTimeoutSec);
+                                ASSERT_NE(std::cv_status::timeout,
+                                        mTorchCond.wait_until(l, timeout));
+                            }
+                            ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF,
+                                    mTorchStatus);
                         }
-                        ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
                     }
                 }
+                ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
             }
-            ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
         }
-    }
 
-    returnStatus = env->mProvider->setCallback(nullptr);
-    ASSERT_TRUE(returnStatus.isOk());
-    ASSERT_EQ(Status::OK, returnStatus);
+        returnStatus = provider.second->setCallback(nullptr);
+        ASSERT_TRUE(returnStatus.isOk());
+        ASSERT_EQ(Status::OK, returnStatus);
+    }
 }
 
 // Check dump functionality.
 TEST_F(CameraHidlTest, dumpState) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    Return<void> ret;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        Return<void> ret;
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<ICameraDevice> device3_2;
+                ALOGI("dumpState: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("dumpState: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
-
-            native_handle_t* raw_handle = native_handle_create(1, 0);
-            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
-            ASSERT_GE(raw_handle->data[0], 0);
-            hidl_handle handle = raw_handle;
-            ret= device3_2->dumpState(handle);
-            ASSERT_TRUE(ret.isOk());
-            close(raw_handle->data[0]);
-            native_handle_delete(raw_handle);
-        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("dumpState: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+                native_handle_t* raw_handle = native_handle_create(1, 0);
+                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+                ASSERT_GE(raw_handle->data[0], 0);
+                hidl_handle handle = raw_handle;
+                ret= device3_2->dumpState(handle);
+                ASSERT_TRUE(ret.isOk());
+                close(raw_handle->data[0]);
+                native_handle_delete(raw_handle);
+            } else if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("dumpState: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            native_handle_t* raw_handle = native_handle_create(1, 0);
-            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
-            ASSERT_GE(raw_handle->data[0], 0);
-            hidl_handle handle = raw_handle;
-            Return<Status> returnStatus = device1->dumpState(handle);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-            close(raw_handle->data[0]);
-            native_handle_delete(raw_handle);
+                native_handle_t* raw_handle = native_handle_create(1, 0);
+                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+                ASSERT_GE(raw_handle->data[0], 0);
+                hidl_handle handle = raw_handle;
+                Return<Status> returnStatus = device1->dumpState(handle);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+                close(raw_handle->data[0]);
+                native_handle_delete(raw_handle);
+            }
         }
     }
 }
 
 // Open, dumpStates, then close
 TEST_F(CameraHidlTest, openClose) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    Return<void> ret;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        Return<void> ret;
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                ALOGI("openClose: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("openClose: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
-
-            sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
-            sp<ICameraDeviceSession> session;
-            ret = device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-            ASSERT_TRUE(ret.isOk());
-
-            native_handle_t* raw_handle = native_handle_create(1, 0);
-            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
-            ASSERT_GE(raw_handle->data[0], 0);
-            hidl_handle handle = raw_handle;
-            ret = device3_2->dumpState(handle);
-            ASSERT_TRUE(ret.isOk());
-            close(raw_handle->data[0]);
-            native_handle_delete(raw_handle);
-
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
-            // TODO: test all session API calls return INTERNAL_ERROR after close
-            // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
-        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-
-            native_handle_t* raw_handle = native_handle_create(1, 0);
-            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
-            ASSERT_GE(raw_handle->data[0], 0);
-            hidl_handle handle = raw_handle;
-            Return<Status> returnStatus = device1->dumpState(handle);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-            close(raw_handle->data[0]);
-            native_handle_delete(raw_handle);
-
-            ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
+                sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
+                sp<ICameraDeviceSession> session;
+                ret = device3_2->open(
+                    cb,
+                    [&](auto status, const auto& newSession) {
+                        ALOGI("device::open returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(newSession, nullptr);
+                        session = newSession;
+                    });
+                ASSERT_TRUE(ret.isOk());
+
+                native_handle_t* raw_handle = native_handle_create(1, 0);
+                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+                ASSERT_GE(raw_handle->data[0], 0);
+                hidl_handle handle = raw_handle;
+                ret = device3_2->dumpState(handle);
+                ASSERT_TRUE(ret.isOk());
+                close(raw_handle->data[0]);
+                native_handle_delete(raw_handle);
+
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+                // TODO: test all session API calls return INTERNAL_ERROR after close
+                // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
+            } else if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+
+                native_handle_t* raw_handle = native_handle_create(1, 0);
+                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+                ASSERT_GE(raw_handle->data[0], 0);
+                hidl_handle handle = raw_handle;
+                Return<Status> returnStatus = device1->dumpState(handle);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+                close(raw_handle->data[0]);
+                native_handle_delete(raw_handle);
+
+                ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -1949,71 +2352,81 @@ TEST_F(CameraHidlTest, openClose) {
 // Check whether all common default request settings can be sucessfully
 // constructed.
 TEST_F(CameraHidlTest, constructDefaultRequestSettings) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            Return<void> ret;
-            ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
-
-            sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
-            sp<ICameraDeviceSession> session;
-            ret = device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-            ASSERT_TRUE(ret.isOk());
-
-            for (uint32_t t = (uint32_t) RequestTemplate::PREVIEW;
-                    t <= (uint32_t) RequestTemplate::MANUAL; t++) {
-                RequestTemplate reqTemplate = (RequestTemplate) t;
-                ret = session->constructDefaultRequestSettings(
-                    reqTemplate,
-                    [&](auto status, const auto& req) {
-                        ALOGI("constructDefaultRequestSettings returns status:%d", (int)status);
-                        if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
-                                reqTemplate == RequestTemplate::MANUAL) {
-                            // optional templates
-                            ASSERT_TRUE(status == Status::OK || status == Status::ILLEGAL_ARGUMENT);
-                        } else {
-                            ASSERT_EQ(Status::OK, status);
-                        }
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                Return<void> ret;
+                ALOGI("constructDefaultRequestSettings: Testing camera device %s",
+                      name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-                        if (status == Status::OK) {
-                            const camera_metadata_t* metadata =
-                                (camera_metadata_t*) req.data();
-                            size_t expectedSize = req.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
-                            // request keys we've defined for each template
-                            ASSERT_GT(entryCount, 0u);
-                            ALOGI("template %u metadata entry count is %zu", t, entryCount);
-                        } else {
-                            ASSERT_EQ(0u, req.size());
-                        }
+                sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
+                sp<ICameraDeviceSession> session;
+                ret = device3_2->open(
+                    cb,
+                    [&](auto status, const auto& newSession) {
+                        ALOGI("device::open returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(newSession, nullptr);
+                        session = newSession;
                     });
                 ASSERT_TRUE(ret.isOk());
+
+                for (uint32_t t = (uint32_t) RequestTemplate::PREVIEW;
+                        t <= (uint32_t) RequestTemplate::MANUAL; t++) {
+                    RequestTemplate reqTemplate = (RequestTemplate) t;
+                    ret = session->constructDefaultRequestSettings(
+                        reqTemplate,
+                        [&](auto status, const auto& req) {
+                            ALOGI("constructDefaultRequestSettings returns status:%d",
+                                  (int)status);
+                            if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
+                                    reqTemplate == RequestTemplate::MANUAL) {
+                                // optional templates
+                                ASSERT_TRUE((status == Status::OK) ||
+                                        (status == Status::ILLEGAL_ARGUMENT));
+                            } else {
+                                ASSERT_EQ(Status::OK, status);
+                            }
+
+                            if (status == Status::OK) {
+                                const camera_metadata_t* metadata =
+                                    (camera_metadata_t*) req.data();
+                                size_t expectedSize = req.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
+                                // request keys we've defined for each template
+                                ASSERT_GT(entryCount, 0u);
+                                ALOGI("template %u metadata entry count is %zu",
+                                      t, entryCount);
+                            } else {
+                                ASSERT_EQ(0u, req.size());
+                            }
+                        });
+                    ASSERT_TRUE(ret.isOk());
+                }
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
             }
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -2021,119 +2434,98 @@ TEST_F(CameraHidlTest, constructDefaultRequestSettings) {
 // Verify that all supported stream formats and sizes can be configured
 // successfully.
 TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputStreams;
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
-
-            outputStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputStreams));
-            ASSERT_NE(0u, outputStreams.size());
-
-            int32_t streamId = 0;
-            for (auto &it : outputStreams) {
-                Stream stream = {streamId, StreamType::OUTPUT,
-                        static_cast<uint32_t> (it.width),
-                        static_cast<uint32_t> (it.height),
-                        static_cast<PixelFormat> (it.format), 0, 0,
-                        StreamRotation::ROTATION_0};
-                ::android::hardware::hidl_vec<Stream> streams = {stream};
-                StreamConfiguration config = {streams,
-                        StreamConfigurationMode::NORMAL_MODE};
-                ret = session->configureStreams(config, [streamId] (Status s,
-                        HalStreamConfiguration halConfig) {
-                    ASSERT_EQ(Status::OK, s);
-                    ASSERT_EQ(1u, halConfig.streams.size());
-                    ASSERT_EQ(halConfig.streams[0].id, streamId);
-                });
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputStreams;
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
+
+                outputStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputStreams));
+                ASSERT_NE(0u, outputStreams.size());
+
+                int32_t streamId = 0;
+                for (auto &it : outputStreams) {
+                    Stream stream = {streamId, StreamType::OUTPUT,
+                            static_cast<uint32_t> (it.width),
+                            static_cast<uint32_t> (it.height),
+                            static_cast<PixelFormat> (it.format),
+                            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+                            StreamRotation::ROTATION_0};
+                    ::android::hardware::hidl_vec<Stream> streams = {stream};
+                    StreamConfiguration config = {streams,
+                            StreamConfigurationMode::NORMAL_MODE};
+                    ret = session->configureStreams(config, [streamId] (Status s,
+                            HalStreamConfiguration halConfig) {
+                        ASSERT_EQ(Status::OK, s);
+                        ASSERT_EQ(1u, halConfig.streams.size());
+                        ASSERT_EQ(halConfig.streams[0].id, streamId);
+                    });
+                    ASSERT_TRUE(ret.isOk());
+                    streamId++;
+                }
+
+                free_camera_metadata(staticMeta);
+                ret = session->close();
                 ASSERT_TRUE(ret.isOk());
-                streamId++;
             }
-
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
 
 // Check for correct handling of invalid/incorrect configuration parameters.
 TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputStreams;
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
-
-            outputStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputStreams));
-            ASSERT_NE(0u, outputStreams.size());
-
-            int32_t streamId = 0;
-            Stream stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (0),
-                    static_cast<uint32_t> (0),
-                    static_cast<PixelFormat> (outputStreams[0].format),
-                    0, 0, StreamRotation::ROTATION_0};
-            ::android::hardware::hidl_vec<Stream> streams = {stream};
-            StreamConfiguration config = {streams,
-                    StreamConfigurationMode::NORMAL_MODE};
-            ret = session->configureStreams(config, [] (Status s,
-                    HalStreamConfiguration) {
-                ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
-                            (Status::INTERNAL_ERROR == s));
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (UINT32_MAX),
-                    static_cast<uint32_t> (UINT32_MAX),
-                    static_cast<PixelFormat> (outputStreams[0].format),
-                    0, 0, StreamRotation::ROTATION_0};
-            streams[0] = stream;
-            config = {streams,
-                    StreamConfigurationMode::NORMAL_MODE};
-            ret = session->configureStreams(config, [] (Status s,
-                    HalStreamConfiguration) {
-                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            for (auto &it : outputStreams) {
-                stream = {streamId++, StreamType::OUTPUT,
-                        static_cast<uint32_t> (it.width),
-                        static_cast<uint32_t> (it.height),
-                        static_cast<PixelFormat> (UINT32_MAX),
-                        0, 0, StreamRotation::ROTATION_0};
-                streams[0] = stream;
-                config = {streams,
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputStreams;
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
+
+                outputStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputStreams));
+                ASSERT_NE(0u, outputStreams.size());
+
+                int32_t streamId = 0;
+                Stream stream = {streamId++, StreamType::OUTPUT,
+                        static_cast<uint32_t> (0),
+                        static_cast<uint32_t> (0),
+                        static_cast<PixelFormat> (outputStreams[0].format),
+                        GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+                        StreamRotation::ROTATION_0};
+                ::android::hardware::hidl_vec<Stream> streams = {stream};
+                StreamConfiguration config = {streams,
                         StreamConfigurationMode::NORMAL_MODE};
                 ret = session->configureStreams(config, [] (Status s,
                         HalStreamConfiguration) {
-                    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                    ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
+                                (Status::INTERNAL_ERROR == s));
                 });
                 ASSERT_TRUE(ret.isOk());
 
                 stream = {streamId++, StreamType::OUTPUT,
-                        static_cast<uint32_t> (it.width),
-                        static_cast<uint32_t> (it.height),
-                        static_cast<PixelFormat> (it.format),
-                        0, 0, static_cast<StreamRotation> (UINT32_MAX)};
+                        static_cast<uint32_t> (UINT32_MAX),
+                        static_cast<uint32_t> (UINT32_MAX),
+                        static_cast<PixelFormat> (outputStreams[0].format),
+                        GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+                        StreamRotation::ROTATION_0};
                 streams[0] = stream;
                 config = {streams,
                         StreamConfigurationMode::NORMAL_MODE};
@@ -2142,11 +2534,43 @@ TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) {
                     ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
                 });
                 ASSERT_TRUE(ret.isOk());
-            }
 
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                for (auto &it : outputStreams) {
+                    stream = {streamId++, StreamType::OUTPUT,
+                            static_cast<uint32_t> (it.width),
+                            static_cast<uint32_t> (it.height),
+                            static_cast<PixelFormat> (UINT32_MAX),
+                            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+                            StreamRotation::ROTATION_0};
+                    streams[0] = stream;
+                    config = {streams,
+                            StreamConfigurationMode::NORMAL_MODE};
+                    ret = session->configureStreams(config, [] (Status s,
+                            HalStreamConfiguration) {
+                        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                    });
+                    ASSERT_TRUE(ret.isOk());
+
+                    stream = {streamId++, StreamType::OUTPUT,
+                            static_cast<uint32_t> (it.width),
+                            static_cast<uint32_t> (it.height),
+                            static_cast<PixelFormat> (it.format),
+                            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+                            static_cast<StreamRotation> (UINT32_MAX)};
+                    streams[0] = stream;
+                    config = {streams,
+                            StreamConfigurationMode::NORMAL_MODE};
+                    ret = session->configureStreams(config, [] (Status s,
+                            HalStreamConfiguration) {
+                        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                    });
+                    ASSERT_TRUE(ret.isOk());
+                }
+
+                free_camera_metadata(staticMeta);
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -2154,83 +2578,87 @@ TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) {
 // Check whether all supported ZSL output stream combinations can be
 // configured successfully.
 TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> inputStreams;
-    std::vector<AvailableZSLInputOutput> inputOutputMap;
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
-
-            Status rc = isZSLModeAvailable(staticMeta);
-            if (Status::METHOD_NOT_SUPPORTED == rc) {
-                ret = session->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
-            }
-            ASSERT_EQ(Status::OK, rc);
-
-            inputStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    inputStreams));
-            ASSERT_NE(0u, inputStreams.size());
-
-            inputOutputMap.clear();
-            ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta,
-                    inputOutputMap));
-            ASSERT_NE(0u, inputOutputMap.size());
-
-            int32_t streamId = 0;
-            for (auto &inputIter : inputOutputMap) {
-                AvailableStream input;
-                ASSERT_EQ(Status::OK,
-                        findLargestSize(inputStreams, inputIter.inputFormat, input));
-                ASSERT_NE(0u, inputStreams.size());
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> inputStreams;
+        std::vector<AvailableZSLInputOutput> inputOutputMap;
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
+
+                Status rc = isZSLModeAvailable(staticMeta);
+                if (Status::METHOD_NOT_SUPPORTED == rc) {
+                    ret = session->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
+                ASSERT_EQ(Status::OK, rc);
 
-                AvailableStream outputThreshold = {INT32_MAX, INT32_MAX,
-                        inputIter.outputFormat};
-                std::vector<AvailableStream> outputStreams;
+                inputStreams.clear();
                 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                        outputStreams, &outputThreshold));
-                for (auto &outputIter : outputStreams) {
-                    Stream zslStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (input.width),
-                            static_cast<uint32_t> (input.height),
-                            static_cast<PixelFormat> (input.format),
-                            GRALLOC_USAGE_HW_CAMERA_ZSL, 0,
-                            StreamRotation::ROTATION_0};
-                    Stream inputStream = {streamId++, StreamType::INPUT,
-                            static_cast<uint32_t> (input.width),
-                            static_cast<uint32_t> (input.height),
-                            static_cast<PixelFormat> (input.format), 0, 0,
-                            StreamRotation::ROTATION_0};
-                    Stream outputStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (outputIter.width),
-                            static_cast<uint32_t> (outputIter.height),
-                            static_cast<PixelFormat> (outputIter.format), 0, 0,
-                            StreamRotation::ROTATION_0};
+                        inputStreams));
+                ASSERT_NE(0u, inputStreams.size());
 
-                    ::android::hardware::hidl_vec<Stream> streams = {
-                            inputStream, zslStream, outputStream};
-                    StreamConfiguration config = {streams,
-                            StreamConfigurationMode::NORMAL_MODE};
-                    ret = session->configureStreams(config,
+                inputOutputMap.clear();
+                ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta,
+                        inputOutputMap));
+                ASSERT_NE(0u, inputOutputMap.size());
+
+                int32_t streamId = 0;
+                for (auto &inputIter : inputOutputMap) {
+                    AvailableStream input;
+                    ASSERT_EQ(Status::OK,
+                            findLargestSize(inputStreams, inputIter.inputFormat, input));
+                    ASSERT_NE(0u, inputStreams.size());
+
+                    AvailableStream outputThreshold = {INT32_MAX, INT32_MAX,
+                            inputIter.outputFormat};
+                    std::vector<AvailableStream> outputStreams;
+                    ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                            outputStreams, &outputThreshold));
+                    for (auto &outputIter : outputStreams) {
+                        Stream zslStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (input.width),
+                                static_cast<uint32_t> (input.height),
+                                static_cast<PixelFormat> (input.format),
+                                GRALLOC_USAGE_HW_CAMERA_ZSL, 0,
+                                StreamRotation::ROTATION_0};
+                        Stream inputStream = {streamId++, StreamType::INPUT,
+                                static_cast<uint32_t> (input.width),
+                                static_cast<uint32_t> (input.height),
+                                static_cast<PixelFormat> (input.format), 0, 0,
+                                StreamRotation::ROTATION_0};
+                        Stream outputStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (outputIter.width),
+                                static_cast<uint32_t> (outputIter.height),
+                                static_cast<PixelFormat> (outputIter.format),
+                                GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+                                StreamRotation::ROTATION_0};
+
+                        ::android::hardware::hidl_vec<Stream> streams = {
+                                inputStream, zslStream, outputStream};
+                        StreamConfiguration config = {streams,
+                                StreamConfigurationMode::NORMAL_MODE};
+                        ret = session->configureStreams(config,
                                                     [](Status s, HalStreamConfiguration halConfig) {
                                                         ASSERT_EQ(Status::OK, s);
                                                         ASSERT_EQ(3u, halConfig.streams.size());
                                                     });
-                    ASSERT_TRUE(ret.isOk());
+                        ASSERT_TRUE(ret.isOk());
+                    }
                 }
-            }
 
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                free_camera_metadata(staticMeta);
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -2238,62 +2666,67 @@ TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) {
 // Verify that all supported preview + still capture stream combinations
 // can be configured successfully.
 TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputBlobStreams;
-    std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
-            static_cast<int32_t>(PixelFormat::BLOB)};
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
-
-            outputBlobStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputBlobStreams, &blobThreshold));
-            ASSERT_NE(0u, outputBlobStreams.size());
-
-            outputPreviewStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputPreviewStreams, &previewThreshold));
-            ASSERT_NE(0u, outputPreviewStreams.size());
-
-            int32_t streamId = 0;
-            for (auto &blobIter : outputBlobStreams) {
-                for (auto &previewIter : outputPreviewStreams) {
-                    Stream previewStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (previewIter.width),
-                            static_cast<uint32_t> (previewIter.height),
-                            static_cast<PixelFormat> (previewIter.format), 0, 0,
-                            StreamRotation::ROTATION_0};
-                    Stream blobStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (blobIter.width),
-                            static_cast<uint32_t> (blobIter.height),
-                            static_cast<PixelFormat> (blobIter.format), 0, 0,
-                            StreamRotation::ROTATION_0};
-                    ::android::hardware::hidl_vec<Stream> streams = {
-                            previewStream, blobStream};
-                    StreamConfiguration config = {streams,
-                            StreamConfigurationMode::NORMAL_MODE};
-                    ret = session->configureStreams(config,
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputBlobStreams;
+        std::vector<AvailableStream> outputPreviewStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
+                static_cast<int32_t>(PixelFormat::BLOB)};
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
+
+                outputBlobStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputBlobStreams, &blobThreshold));
+                ASSERT_NE(0u, outputBlobStreams.size());
+
+                outputPreviewStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputPreviewStreams, &previewThreshold));
+                ASSERT_NE(0u, outputPreviewStreams.size());
+
+                int32_t streamId = 0;
+                for (auto &blobIter : outputBlobStreams) {
+                    for (auto &previewIter : outputPreviewStreams) {
+                        Stream previewStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (previewIter.width),
+                                static_cast<uint32_t> (previewIter.height),
+                                static_cast<PixelFormat> (previewIter.format),
+                                GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+                                StreamRotation::ROTATION_0};
+                        Stream blobStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (blobIter.width),
+                                static_cast<uint32_t> (blobIter.height),
+                                static_cast<PixelFormat> (blobIter.format),
+                                GRALLOC1_CONSUMER_USAGE_CPU_READ, 0,
+                                StreamRotation::ROTATION_0};
+                        ::android::hardware::hidl_vec<Stream> streams = {
+                                previewStream, blobStream};
+                        StreamConfiguration config = {streams,
+                                StreamConfigurationMode::NORMAL_MODE};
+                        ret = session->configureStreams(config,
                                                     [](Status s, HalStreamConfiguration halConfig) {
                                                         ASSERT_EQ(Status::OK, s);
                                                         ASSERT_EQ(2u, halConfig.streams.size());
                                                     });
-                    ASSERT_TRUE(ret.isOk());
+                        ASSERT_TRUE(ret.isOk());
+                    }
                 }
-            }
 
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                free_camera_metadata(staticMeta);
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -2302,89 +2735,99 @@ TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) {
 // configured. Additionally check for common invalid inputs when
 // using this mode.
 TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
-
-            Status rc = isConstrainedModeAvailable(staticMeta);
-            if (Status::METHOD_NOT_SUPPORTED == rc) {
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
+
+                Status rc = isConstrainedModeAvailable(staticMeta);
+                if (Status::METHOD_NOT_SUPPORTED == rc) {
+                    ret = session->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
+                ASSERT_EQ(Status::OK, rc);
+
+                AvailableStream hfrStream;
+                rc = pickConstrainedModeSize(staticMeta, hfrStream);
+                ASSERT_EQ(Status::OK, rc);
+
+                int32_t streamId = 0;
+                Stream stream = {streamId, StreamType::OUTPUT,
+                        static_cast<uint32_t> (hfrStream.width),
+                        static_cast<uint32_t> (hfrStream.height),
+                        static_cast<PixelFormat> (hfrStream.format),
+                        GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
+                        StreamRotation::ROTATION_0};
+                ::android::hardware::hidl_vec<Stream> streams = {stream};
+                StreamConfiguration config = {streams,
+                        StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+                ret = session->configureStreams(config, [streamId] (Status s,
+                        HalStreamConfiguration halConfig) {
+                    ASSERT_EQ(Status::OK, s);
+                    ASSERT_EQ(1u, halConfig.streams.size());
+                    ASSERT_EQ(halConfig.streams[0].id, streamId);
+                });
+                ASSERT_TRUE(ret.isOk());
+
+                stream = {streamId++, StreamType::OUTPUT,
+                        static_cast<uint32_t> (0),
+                        static_cast<uint32_t> (0),
+                        static_cast<PixelFormat> (hfrStream.format),
+                        GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
+                        StreamRotation::ROTATION_0};
+                streams[0] = stream;
+                config = {streams,
+                        StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+                ret = session->configureStreams(config, [] (Status s,
+                        HalStreamConfiguration) {
+                    ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
+                                (Status::INTERNAL_ERROR == s));
+                });
+                ASSERT_TRUE(ret.isOk());
+
+                stream = {streamId++, StreamType::OUTPUT,
+                        static_cast<uint32_t> (UINT32_MAX),
+                        static_cast<uint32_t> (UINT32_MAX),
+                        static_cast<PixelFormat> (hfrStream.format),
+                        GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
+                        StreamRotation::ROTATION_0};
+                streams[0] = stream;
+                config = {streams,
+                        StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+                ret = session->configureStreams(config, [] (Status s,
+                        HalStreamConfiguration) {
+                    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                });
+                ASSERT_TRUE(ret.isOk());
+
+                stream = {streamId++, StreamType::OUTPUT,
+                        static_cast<uint32_t> (hfrStream.width),
+                        static_cast<uint32_t> (hfrStream.height),
+                        static_cast<PixelFormat> (UINT32_MAX),
+                        GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
+                        StreamRotation::ROTATION_0};
+                streams[0] = stream;
+                config = {streams,
+                        StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+                ret = session->configureStreams(config, [] (Status s,
+                        HalStreamConfiguration) {
+                    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                });
+                ASSERT_TRUE(ret.isOk());
+
+                free_camera_metadata(staticMeta);
                 ret = session->close();
                 ASSERT_TRUE(ret.isOk());
-                continue;
             }
-            ASSERT_EQ(Status::OK, rc);
-
-            AvailableStream hfrStream;
-            rc = pickConstrainedModeSize(staticMeta, hfrStream);
-            ASSERT_EQ(Status::OK, rc);
-
-            int32_t streamId = 0;
-            Stream stream = {streamId, StreamType::OUTPUT,
-                    static_cast<uint32_t> (hfrStream.width),
-                    static_cast<uint32_t> (hfrStream.height),
-                    static_cast<PixelFormat> (hfrStream.format), 0, 0,
-                    StreamRotation::ROTATION_0};
-            ::android::hardware::hidl_vec<Stream> streams = {stream};
-            StreamConfiguration config = {streams,
-                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            ret = session->configureStreams(config, [streamId] (Status s,
-                    HalStreamConfiguration halConfig) {
-                ASSERT_EQ(Status::OK, s);
-                ASSERT_EQ(1u, halConfig.streams.size());
-                ASSERT_EQ(halConfig.streams[0].id, streamId);
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (0),
-                    static_cast<uint32_t> (0),
-                    static_cast<PixelFormat> (hfrStream.format), 0, 0,
-                    StreamRotation::ROTATION_0};
-            streams[0] = stream;
-            config = {streams,
-                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
-                ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
-                            (Status::INTERNAL_ERROR == s));
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (UINT32_MAX),
-                    static_cast<uint32_t> (UINT32_MAX),
-                    static_cast<PixelFormat> (hfrStream.format), 0, 0,
-                    StreamRotation::ROTATION_0};
-            streams[0] = stream;
-            config = {streams,
-                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
-                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (hfrStream.width),
-                    static_cast<uint32_t> (hfrStream.height),
-                    static_cast<PixelFormat> (UINT32_MAX), 0, 0,
-                    StreamRotation::ROTATION_0};
-            streams[0] = stream;
-            config = {streams,
-                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
-                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -2392,176 +2835,218 @@ TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) {
 // Verify that all supported video + snapshot stream combinations can
 // be configured successfully.
 TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputBlobStreams;
-    std::vector<AvailableStream> outputVideoStreams;
-    AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight,
-            static_cast<int32_t>(PixelFormat::BLOB)};
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
-
-            outputBlobStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputBlobStreams, &blobThreshold));
-            ASSERT_NE(0u, outputBlobStreams.size());
-
-            outputVideoStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputVideoStreams, &videoThreshold));
-            ASSERT_NE(0u, outputVideoStreams.size());
-
-            int32_t streamId = 0;
-            for (auto &blobIter : outputBlobStreams) {
-                for (auto &videoIter : outputVideoStreams) {
-                    Stream videoStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (videoIter.width),
-                            static_cast<uint32_t> (videoIter.height),
-                            static_cast<PixelFormat> (videoIter.format), 0, 0,
-                            StreamRotation::ROTATION_0};
-                    Stream blobStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (blobIter.width),
-                            static_cast<uint32_t> (blobIter.height),
-                            static_cast<PixelFormat> (blobIter.format),
-                            GRALLOC_USAGE_HW_VIDEO_ENCODER, 0,
-                            StreamRotation::ROTATION_0};
-                    ::android::hardware::hidl_vec<Stream> streams = {
-                            videoStream, blobStream};
-                    StreamConfiguration config = {streams,
-                            StreamConfigurationMode::NORMAL_MODE};
-                    ret = session->configureStreams(config,
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputBlobStreams;
+        std::vector<AvailableStream> outputVideoStreams;
+        AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight,
+                static_cast<int32_t>(PixelFormat::BLOB)};
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
+
+                outputBlobStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputBlobStreams, &blobThreshold));
+                ASSERT_NE(0u, outputBlobStreams.size());
+
+                outputVideoStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputVideoStreams, &videoThreshold));
+                ASSERT_NE(0u, outputVideoStreams.size());
+
+                int32_t streamId = 0;
+                for (auto &blobIter : outputBlobStreams) {
+                    for (auto &videoIter : outputVideoStreams) {
+                        Stream videoStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (videoIter.width),
+                                static_cast<uint32_t> (videoIter.height),
+                                static_cast<PixelFormat> (videoIter.format),
+                                GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
+                                StreamRotation::ROTATION_0};
+                        Stream blobStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (blobIter.width),
+                                static_cast<uint32_t> (blobIter.height),
+                                static_cast<PixelFormat> (blobIter.format),
+                                GRALLOC1_CONSUMER_USAGE_CPU_READ, 0,
+                                StreamRotation::ROTATION_0};
+                        ::android::hardware::hidl_vec<Stream> streams = {
+                                videoStream, blobStream};
+                        StreamConfiguration config = {streams,
+                                StreamConfigurationMode::NORMAL_MODE};
+                        ret = session->configureStreams(config,
                                                     [](Status s, HalStreamConfiguration halConfig) {
                                                         ASSERT_EQ(Status::OK, s);
                                                         ASSERT_EQ(2u, halConfig.streams.size());
                                                     });
-                    ASSERT_TRUE(ret.isOk());
+                        ASSERT_TRUE(ret.isOk());
+                    }
                 }
-            }
 
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                free_camera_metadata(staticMeta);
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Generate and verify a camera capture request
 TEST_F(CameraHidlTest, processCaptureRequestPreview) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    uint64_t bufferId = 1;
-    uint32_t frameNumber = 1;
-    ::android::hardware::hidl_vec<uint8_t> settings;
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/);
-
-            RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
-            Return<void> ret;
-            ret = session->constructDefaultRequestSettings(reqTemplate,
-                [&](auto status, const auto& req) {
-                    ASSERT_EQ(Status::OK, status);
-                    settings = req; });
-            ASSERT_TRUE(ret.isOk());
-
-            sp<GraphicBuffer> gb = new GraphicBuffer(
-                previewStream.width, previewStream.height,
-                static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
-                1, android_convertGralloc1To0Usage(
-                       halStreamConfig.streams[0].producerUsage,
-                       halStreamConfig.streams[0].consumerUsage));
-            ASSERT_NE(nullptr, gb.get());
-            StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
-                    bufferId, hidl_handle(gb->getNativeBuffer()->handle),
-                    BufferStatus::OK, nullptr, nullptr};
-            ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
-                    outputBuffer};
-            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
-                    BufferStatus::ERROR, nullptr, nullptr};
-            CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
-                    emptyInputBuffer, outputBuffers};
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mResultBuffers.clear();
-                mResultFrameNumber = frameNumber;
-            }
-
-            Status status = Status::INTERNAL_ERROR;
-            uint32_t numRequestProcessed = 0;
-            hidl_vec<BufferCache> cachesToRemove;
-            Return<void> returnStatus = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                        status = s;
-                        numRequestProcessed = n;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        uint64_t bufferId = 1;
+        uint32_t frameNumber = 1;
+        ::android::hardware::hidl_vec<uint8_t> settings;
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
+                        &partialResultCount/*out*/);
+
+                std::shared_ptr<ResultMetadataQueue> resultQueue;
+                auto resultQueueRet = session->getCaptureResultMetadataQueue(
+                    [&resultQueue](const auto& descriptor) {
+                        resultQueue = std::make_shared<ResultMetadataQueue>(
+                                descriptor);
+                        if (!resultQueue->isValid() ||
+                                resultQueue->availableToWrite() <= 0) {
+                            ALOGE("%s: HAL returns empty result metadata fmq,"
+                                    " not use it", __func__);
+                            resultQueue = nullptr;
+                            // Don't use the queue onwards.
+                        }
                     });
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, status);
-            ASSERT_EQ(numRequestProcessed, 1u);
+                ASSERT_TRUE(resultQueueRet.isOk());
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                while (0 == mResultBuffers.size()) {
-                    auto timeout = std::chrono::system_clock::now() +
-                            std::chrono::seconds(kStreamBufferTimeoutSec);
-                    ASSERT_NE(std::cv_status::timeout,
-                            mResultCondition.wait_until(l, timeout));
+                InFlightRequest inflightReq = {1, false, supportsPartialResults,
+                        partialResultCount, resultQueue};
+
+                RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
+                Return<void> ret;
+                ret = session->constructDefaultRequestSettings(reqTemplate,
+                    [&](auto status, const auto& req) {
+                        ASSERT_EQ(Status::OK, status);
+                        settings = req; });
+                ASSERT_TRUE(ret.isOk());
+
+                sp<GraphicBuffer> gb = new GraphicBuffer(
+                    previewStream.width, previewStream.height,
+                    static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
+                    1, android_convertGralloc1To0Usage(
+                           halStreamConfig.streams[0].producerUsage,
+                           halStreamConfig.streams[0].consumerUsage));
+                ASSERT_NE(nullptr, gb.get());
+                StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
+                        bufferId, hidl_handle(gb->getNativeBuffer()->handle),
+                        BufferStatus::OK, nullptr, nullptr};
+                ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
+                        outputBuffer};
+                StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                        BufferStatus::ERROR, nullptr, nullptr};
+                CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */,
+                        settings, emptyInputBuffer, outputBuffers};
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mInflightMap.clear();
+                    mInflightMap.add(frameNumber, &inflightReq);
                 }
 
-                ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
-                ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
+                Status status = Status::INTERNAL_ERROR;
+                uint32_t numRequestProcessed = 0;
+                hidl_vec<BufferCache> cachesToRemove;
+                Return<void> returnStatus = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                            status = s;
+                            numRequestProcessed = n;
+                        });
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, status);
+                ASSERT_EQ(numRequestProcessed, 1u);
 
-                request.frameNumber++;
-                //Empty settings should be supported after the first call
-                //for repeating requests.
-                request.settings.setToExternal(nullptr, 0, true);
-                mResultBuffers.clear();
-                mResultFrameNumber++;
-            }
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    while (!inflightReq.errorCodeValid &&
+                            ((0 < inflightReq.numBuffersLeft) ||
+                                    (!inflightReq.haveResultMetadata))) {
+                        auto timeout = std::chrono::system_clock::now() +
+                                std::chrono::seconds(kStreamBufferTimeoutSec);
+                        ASSERT_NE(std::cv_status::timeout,
+                                mResultCondition.wait_until(l, timeout));
+                    }
 
-            returnStatus = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                        status = s;
-                        numRequestProcessed = n;
-                    });
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, status);
-            ASSERT_EQ(numRequestProcessed, 1u);
+                    ASSERT_FALSE(inflightReq.errorCodeValid);
+                    ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+                    ASSERT_EQ(previewStream.id,
+                              inflightReq.resultOutputBuffers[0].streamId);
+
+                    request.frameNumber++;
+                    //Empty settings should be supported after the first call
+                    //for repeating requests.
+                    request.settings.setToExternal(nullptr, 0, true);
+                    // The buffer has been registered to HAL by bufferId, so per
+                    // API contract we should send a null handle for this buffer
+                    request.outputBuffers[0].buffer = nullptr;
+                    mInflightMap.clear();
+                    inflightReq = {1, false, supportsPartialResults,
+                                        partialResultCount, resultQueue};
+                    mInflightMap.add(request.frameNumber, &inflightReq);
+                }
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                while (0 == mResultBuffers.size()) {
-                    auto timeout = std::chrono::system_clock::now() +
-                            std::chrono::seconds(kStreamBufferTimeoutSec);
-                    ASSERT_NE(std::cv_status::timeout,
-                            mResultCondition.wait_until(l, timeout));
+                returnStatus = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                            status = s;
+                            numRequestProcessed = n;
+                        });
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, status);
+                ASSERT_EQ(numRequestProcessed, 1u);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    while (!inflightReq.errorCodeValid &&
+                            ((0 < inflightReq.numBuffersLeft) ||
+                                    (!inflightReq.haveResultMetadata))) {
+                        auto timeout = std::chrono::system_clock::now() +
+                                std::chrono::seconds(kStreamBufferTimeoutSec);
+                        ASSERT_NE(std::cv_status::timeout,
+                                mResultCondition.wait_until(l, timeout));
+                    }
+
+                    ASSERT_FALSE(inflightReq.errorCodeValid);
+                    ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+                    ASSERT_EQ(previewStream.id,
+                              inflightReq.resultOutputBuffers[0].streamId);
                 }
-                ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
-                ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
-            }
 
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -2569,58 +3054,64 @@ TEST_F(CameraHidlTest, processCaptureRequestPreview) {
 // Test whether an incorrect capture request with missing settings will
 // be reported correctly.
 TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    uint64_t bufferId = 1;
-    uint32_t frameNumber = 1;
-    ::android::hardware::hidl_vec<uint8_t> settings;
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/);
-
-            sp<GraphicBuffer> gb = new GraphicBuffer(
-                previewStream.width, previewStream.height,
-                static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
-                1, android_convertGralloc1To0Usage(
-                       halStreamConfig.streams[0].producerUsage,
-                       halStreamConfig.streams[0].consumerUsage));
-
-            StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
-                    bufferId, hidl_handle(gb->getNativeBuffer()->handle),
-                    BufferStatus::OK, nullptr, nullptr};
-            ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
-                    outputBuffer};
-            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
-                    BufferStatus::ERROR, nullptr, nullptr};
-            CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
-                    emptyInputBuffer, outputBuffers};
-
-            //Settings were not correctly initialized, we should fail here
-            Status status = Status::OK;
-            uint32_t numRequestProcessed = 0;
-            hidl_vec<BufferCache> cachesToRemove;
-            Return<void> ret = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                        status = s;
-                        numRequestProcessed = n;
-                    });
-            ASSERT_TRUE(ret.isOk());
-            ASSERT_EQ(Status::INTERNAL_ERROR, status);
-            ASSERT_EQ(numRequestProcessed, 0u);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputPreviewStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        uint64_t bufferId = 1;
+        uint32_t frameNumber = 1;
+        ::android::hardware::hidl_vec<uint8_t> settings;
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
+                        &partialResultCount /*out*/);
+
+                sp<GraphicBuffer> gb = new GraphicBuffer(
+                    previewStream.width, previewStream.height,
+                    static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
+                    1, android_convertGralloc1To0Usage(
+                           halStreamConfig.streams[0].producerUsage,
+                           halStreamConfig.streams[0].consumerUsage));
+
+                StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
+                        bufferId, hidl_handle(gb->getNativeBuffer()->handle),
+                        BufferStatus::OK, nullptr, nullptr};
+                ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
+                        outputBuffer};
+                StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                        BufferStatus::ERROR, nullptr, nullptr};
+                CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
+                        emptyInputBuffer, outputBuffers};
+
+                //Settings were not correctly initialized, we should fail here
+                Status status = Status::OK;
+                uint32_t numRequestProcessed = 0;
+                hidl_vec<BufferCache> cachesToRemove;
+                Return<void> ret = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                            status = s;
+                            numRequestProcessed = n;
+                        });
+                ASSERT_TRUE(ret.isOk());
+                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
+                ASSERT_EQ(numRequestProcessed, 0u);
 
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -2628,207 +3119,230 @@ TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
 // Check whether an invalid capture request with missing output buffers
 // will be reported correctly.
 TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputBlobStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    uint32_t frameNumber = 1;
-    ::android::hardware::hidl_vec<uint8_t> settings;
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/);
-
-            RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
-            Return<void> ret;
-            ret = session->constructDefaultRequestSettings(reqTemplate,
-                [&](auto status, const auto& req) {
-                    ASSERT_EQ(Status::OK, status);
-                    settings = req; });
-            ASSERT_TRUE(ret.isOk());
-
-            ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
-            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
-                    BufferStatus::ERROR, nullptr, nullptr};
-            CaptureRequest request = {frameNumber, 0/* fmqSettingsSize */, settings,
-                    emptyInputBuffer, emptyOutputBuffers};
-
-            //Output buffers are missing, we should fail here
-            Status status = Status::OK;
-            uint32_t numRequestProcessed = 0;
-            hidl_vec<BufferCache> cachesToRemove;
-            ret = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                        status = s;
-                        numRequestProcessed = n;
-                    });
-            ASSERT_TRUE(ret.isOk());
-            ASSERT_EQ(Status::INTERNAL_ERROR, status);
-            ASSERT_EQ(numRequestProcessed, 0u);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputBlobStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        uint32_t frameNumber = 1;
+        ::android::hardware::hidl_vec<uint8_t> settings;
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults/*out*/,
+                        &partialResultCount /*out*/);
+
+                RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
+                Return<void> ret;
+                ret = session->constructDefaultRequestSettings(reqTemplate,
+                    [&](auto status, const auto& req) {
+                        ASSERT_EQ(Status::OK, status);
+                        settings = req; });
+                ASSERT_TRUE(ret.isOk());
 
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
+                StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                        BufferStatus::ERROR, nullptr, nullptr};
+                CaptureRequest request = {frameNumber, 0/* fmqSettingsSize */,
+                        settings, emptyInputBuffer, emptyOutputBuffers};
+
+                //Output buffers are missing, we should fail here
+                Status status = Status::OK;
+                uint32_t numRequestProcessed = 0;
+                hidl_vec<BufferCache> cachesToRemove;
+                ret = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                            status = s;
+                            numRequestProcessed = n;
+                        });
+                ASSERT_TRUE(ret.isOk());
+                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
+                ASSERT_EQ(numRequestProcessed, 0u);
+
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Generate, trigger and flush a preview request
 TEST_F(CameraHidlTest, flushPreviewRequest) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    uint64_t bufferId = 1;
-    uint32_t frameNumber = 1;
-    ::android::hardware::hidl_vec<uint8_t> settings;
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/);
-
-            RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
-            Return<void> ret;
-            ret = session->constructDefaultRequestSettings(reqTemplate,
-                [&](auto status, const auto& req) {
-                    ASSERT_EQ(Status::OK, status);
-                    settings = req; });
-            ASSERT_TRUE(ret.isOk());
-
-            sp<GraphicBuffer> gb = new GraphicBuffer(
-                previewStream.width, previewStream.height,
-                static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
-                1, android_convertGralloc1To0Usage(
-                       halStreamConfig.streams[0].producerUsage,
-                       halStreamConfig.streams[0].consumerUsage));
-            ASSERT_NE(nullptr, gb.get());
-            StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
-                    bufferId, hidl_handle(gb->getNativeBuffer()->handle),
-                    BufferStatus::OK, nullptr, nullptr};
-            ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
-                    outputBuffer};
-            const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
-                    BufferStatus::ERROR, nullptr, nullptr};
-            CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
-                    emptyInputBuffer, outputBuffers};
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mResultBuffers.clear();
-                mErrors.clear();
-                mResultFrameNumber = frameNumber;
-            }
-
-            Status status = Status::INTERNAL_ERROR;
-            uint32_t numRequestProcessed = 0;
-            hidl_vec<BufferCache> cachesToRemove;
-            ret = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                        status = s;
-                        numRequestProcessed = n;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputPreviewStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        uint64_t bufferId = 1;
+        uint32_t frameNumber = 1;
+        ::android::hardware::hidl_vec<uint8_t> settings;
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
+                        &partialResultCount /*out*/);
+
+                std::shared_ptr<ResultMetadataQueue> resultQueue;
+                auto resultQueueRet = session->getCaptureResultMetadataQueue(
+                    [&resultQueue](const auto& descriptor) {
+                        resultQueue = std::make_shared<ResultMetadataQueue>(
+                                descriptor);
+                        if (!resultQueue->isValid() ||
+                                resultQueue->availableToWrite() <= 0) {
+                            ALOGE("%s: HAL returns empty result metadata fmq,"
+                                    " not use it", __func__);
+                            resultQueue = nullptr;
+                            // Don't use the queue onwards.
+                        }
                     });
+                ASSERT_TRUE(resultQueueRet.isOk());
 
-            ASSERT_TRUE(ret.isOk());
-            ASSERT_EQ(Status::OK, status);
-            ASSERT_EQ(numRequestProcessed, 1u);
-            //Flush before waiting for request to complete.
-            Return<Status> returnStatus = session->flush();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                while ((0 == mResultBuffers.size()) && (0 == mErrors.size())) {
-                    auto timeout = std::chrono::system_clock::now() +
-                            std::chrono::seconds(kStreamBufferTimeoutSec);
-                    ASSERT_NE(std::cv_status::timeout,
-                            mResultCondition.wait_until(l, timeout));
+                InFlightRequest inflightReq = {1, false, supportsPartialResults,
+                        partialResultCount, resultQueue};
+                RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
+                Return<void> ret;
+                ret = session->constructDefaultRequestSettings(reqTemplate,
+                    [&](auto status, const auto& req) {
+                        ASSERT_EQ(Status::OK, status);
+                        settings = req; });
+                ASSERT_TRUE(ret.isOk());
+
+                sp<GraphicBuffer> gb = new GraphicBuffer(
+                    previewStream.width, previewStream.height,
+                    static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
+                    1, android_convertGralloc1To0Usage(
+                           halStreamConfig.streams[0].producerUsage,
+                           halStreamConfig.streams[0].consumerUsage));
+                ASSERT_NE(nullptr, gb.get());
+                StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
+                        bufferId, hidl_handle(gb->getNativeBuffer()->handle),
+                        BufferStatus::OK, nullptr, nullptr};
+                ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
+                        outputBuffer};
+                const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                        BufferStatus::ERROR, nullptr, nullptr};
+                CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */,
+                        settings, emptyInputBuffer, outputBuffers};
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mInflightMap.clear();
+                    mInflightMap.add(frameNumber, &inflightReq);
                 }
 
-                if (mErrors.empty()) {
-                    ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
-                    ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
-                } else {
-                    for (auto &error : mErrors) {
-                        switch (error.errorCode) {
+                Status status = Status::INTERNAL_ERROR;
+                uint32_t numRequestProcessed = 0;
+                hidl_vec<BufferCache> cachesToRemove;
+                ret = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                            status = s;
+                            numRequestProcessed = n;
+                        });
+
+                ASSERT_TRUE(ret.isOk());
+                ASSERT_EQ(Status::OK, status);
+                ASSERT_EQ(numRequestProcessed, 1u);
+                //Flush before waiting for request to complete.
+                Return<Status> returnStatus = session->flush();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    while (!inflightReq.errorCodeValid &&
+                            ((0 < inflightReq.numBuffersLeft) ||
+                                    (!inflightReq.haveResultMetadata))) {
+                        auto timeout = std::chrono::system_clock::now() +
+                                std::chrono::seconds(kStreamBufferTimeoutSec);
+                        ASSERT_NE(std::cv_status::timeout,
+                                mResultCondition.wait_until(l, timeout));
+                    }
+
+                    if (!inflightReq.errorCodeValid) {
+                        ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+                        ASSERT_EQ(previewStream.id,
+                                  inflightReq.resultOutputBuffers[0].streamId);
+                    } else {
+                        switch (inflightReq.errorCode) {
                             case ErrorCode::ERROR_REQUEST:
                             case ErrorCode::ERROR_RESULT:
-                                //Expected
-                                break;
                             case ErrorCode::ERROR_BUFFER:
-                                //Expected as well
-                                ASSERT_EQ(frameNumber, error.frameNumber);
-                                ASSERT_EQ(previewStream.id, error.errorStreamId);
+                                //Expected
                                 break;
                             case ErrorCode::ERROR_DEVICE:
                             default:
-                                FAIL() <<"Unexpected error:" << static_cast<uint32_t> (error.errorCode);
+                                FAIL() << "Unexpected error:" << static_cast<uint32_t> (
+                                        inflightReq.errorCode);
                         }
                     }
+
+                    ret = session->close();
+                    ASSERT_TRUE(ret.isOk());
                 }
             }
-
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
 
 // Verify that camera flushes correctly without any pending requests.
 TEST_F(CameraHidlTest, flushEmpty) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mResultBuffers.clear();
-                mErrors.clear();
-                mResultFrameNumber = 0;
-            }
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputPreviewStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
+                        &partialResultCount /*out*/);
+
+                Return<Status> returnStatus = session->flush();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            Return<Status> returnStatus = session->flush();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                auto timeout = std::chrono::system_clock::now() +
-                        std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
-                ASSERT_EQ(std::cv_status::timeout,
-                        mResultCondition.wait_until(l, timeout));
-                ASSERT_TRUE(mErrors.empty());
-                ASSERT_TRUE(mResultBuffers.empty());
-            }
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    auto timeout = std::chrono::system_clock::now() +
+                            std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
+                    ASSERT_EQ(std::cv_status::timeout,
+                            mResultCondition.wait_until(l, timeout));
+                }
 
-            Return<void> ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                Return<void> ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -3005,7 +3519,7 @@ Status CameraHidlTest::findLargestSize(
 
 // Check whether the camera device supports specific focus mode.
 Status CameraHidlTest::isAutoFocusModeAvailable(
-        ::android::CameraParameters &cameraParams,
+        CameraParameters &cameraParams,
         const char *mode) {
     ::android::String8 focusModes(cameraParams.get(
             CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
@@ -3018,21 +3532,24 @@ Status CameraHidlTest::isAutoFocusModeAvailable(
 
 // Open a device session and configure a preview stream.
 void CameraHidlTest::configurePreviewStream(const std::string &name,
-        const CameraHidlEnvironment* env,
+        sp<ICameraProvider> provider,
         const AvailableStream *previewThreshold,
         sp<ICameraDeviceSession> *session /*out*/,
         Stream *previewStream /*out*/,
-        HalStreamConfiguration *halStreamConfig /*out*/) {
-    ASSERT_NE(nullptr, env);
+        HalStreamConfiguration *halStreamConfig /*out*/,
+        bool *supportsPartialResults /*out*/,
+        uint32_t *partialResultCount /*out*/) {
     ASSERT_NE(nullptr, session);
     ASSERT_NE(nullptr, previewStream);
     ASSERT_NE(nullptr, halStreamConfig);
+    ASSERT_NE(nullptr, supportsPartialResults);
+    ASSERT_NE(nullptr, partialResultCount);
 
     std::vector<AvailableStream> outputPreviewStreams;
     ::android::sp<ICameraDevice> device3_2;
     ALOGI("configureStreams: Testing camera device %s", name.c_str());
     Return<void> ret;
-    ret = env->mProvider->getCameraDeviceInterface_V3_x(
+    ret = provider->getCameraDeviceInterface_V3_x(
         name,
         [&](auto status, const auto& device) {
             ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
@@ -3064,6 +3581,14 @@ void CameraHidlTest::configurePreviewStream(const std::string &name,
     });
     ASSERT_TRUE(ret.isOk());
 
+    camera_metadata_ro_entry entry;
+    auto status = find_camera_metadata_ro_entry(staticMeta,
+            ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry);
+    if ((0 == status) && (entry.count > 0)) {
+        *partialResultCount = entry.data.i32[0];
+        *supportsPartialResults = (*partialResultCount > 1);
+    }
+
     outputPreviewStreams.clear();
     auto rc = getAvailableOutputStreams(staticMeta,
             outputPreviewStreams, previewThreshold);
@@ -3075,7 +3600,7 @@ void CameraHidlTest::configurePreviewStream(const std::string &name,
             static_cast<uint32_t> (outputPreviewStreams[0].width),
             static_cast<uint32_t> (outputPreviewStreams[0].height),
             static_cast<PixelFormat> (outputPreviewStreams[0].format),
-            0, 0, StreamRotation::ROTATION_0};
+            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0};
     ::android::hardware::hidl_vec<Stream> streams = {*previewStream};
     StreamConfiguration config = {streams,
             StreamConfigurationMode::NORMAL_MODE};
@@ -3090,17 +3615,16 @@ void CameraHidlTest::configurePreviewStream(const std::string &name,
 
 // Open a device session with empty callbacks and return static metadata.
 void CameraHidlTest::openEmptyDeviceSession(const std::string &name,
-        const CameraHidlEnvironment* env,
+        sp<ICameraProvider> provider,
         sp<ICameraDeviceSession> *session /*out*/,
         camera_metadata_t **staticMeta /*out*/) {
-    ASSERT_NE(nullptr, env);
     ASSERT_NE(nullptr, session);
     ASSERT_NE(nullptr, staticMeta);
 
     ::android::sp<ICameraDevice> device3_2;
     ALOGI("configureStreams: Testing camera device %s", name.c_str());
     Return<void> ret;
-    ret = env->mProvider->getCameraDeviceInterface_V3_x(
+    ret = provider->getCameraDeviceInterface_V3_x(
         name,
         [&](auto status, const auto& device) {
             ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
@@ -3132,13 +3656,12 @@ void CameraHidlTest::openEmptyDeviceSession(const std::string &name,
 
 // Open a particular camera device.
 void CameraHidlTest::openCameraDevice(const std::string &name,
-        const CameraHidlEnvironment* env,
+        sp<ICameraProvider> provider,
         sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device1 /*out*/) {
-    ASSERT_TRUE(nullptr != env);
     ASSERT_TRUE(nullptr != device1);
 
     Return<void> ret;
-    ret = env->mProvider->getCameraDeviceInterface_V1_x(
+    ret = provider->getCameraDeviceInterface_V1_x(
             name,
             [&](auto status, const auto& device) {
             ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
diff --git a/compatibility_matrix.current.xml b/compatibility_matrix.current.xml
new file mode 100644 (file)
index 0000000..9603bd6
--- /dev/null
@@ -0,0 +1,333 @@
+<compatibility-matrix version="1.0" type="framework">
+    <hal format="hidl" optional="false">
+        <name>android.hardware.audio</name>
+        <version>2.0</version>
+        <interface>
+            <name>IDevicesFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.audio.effect</name>
+        <version>2.0</version>
+        <interface>
+            <name>IEffectsFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.evs</name>
+        <version>1.0</version>
+        <interface>
+            <name>IEvsEnumerator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.vehicle</name>
+        <version>2.0</version>
+        <interface>
+            <name>IVehicle</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.biometrics.fingerprint</name>
+        <version>2.1</version>
+        <interface>
+            <name>IBiometricsFingerprint</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.bluetooth</name>
+        <version>1.0</version>
+        <interface>
+            <name>IBluetoothHci</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.boot</name>
+        <version>1.0</version>
+        <interface>
+            <name>IBootControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.broadcastradio</name>
+        <version>1.0</version>
+        <interface>
+            <name>IBroadcastRadioFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.camera.provider</name>
+        <version>2.4</version>
+        <interface>
+            <name>ICameraProvider</name>
+            <instance>legacy/0</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.configstore</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>ISurfaceFlingerConfigs</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.contexthub</name>
+        <version>1.0</version>
+        <interface>
+            <name>IContexthub</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.drm</name>
+        <version>1.0</version>
+        <interface>
+            <name>ICryptoFactory</name>
+            <instance>default</instance>
+        </interface>
+        <interface>
+            <name>IDrmFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.dumpstate</name>
+        <version>1.0</version>
+        <interface>
+            <name>IDumpstateDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.gatekeeper</name>
+        <version>1.0</version>
+        <interface>
+            <name>IGatekeeper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.gnss</name>
+        <version>1.0</version>
+        <interface>
+            <name>IGnss</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.graphics.allocator</name>
+        <version>2.0</version>
+        <interface>
+            <name>IAllocator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.graphics.composer</name>
+        <version>2.1</version>
+        <interface>
+            <name>IComposer</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.graphics.mapper</name>
+        <version>2.0</version>
+        <interface>
+            <name>IMapper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.health</name>
+        <version>1.0</version>
+        <interface>
+            <name>IHealth</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.ir</name>
+        <version>1.0</version>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.keymaster</name>
+        <version>3.0</version>
+        <interface>
+            <name>IKeymasterDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.light</name>
+        <version>2.0</version>
+        <interface>
+            <name>ILight</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.media.omx</name>
+        <version>1.0</version>
+        <interface>
+            <name>IOmx</name>
+            <instance>default</instance>
+        </interface>
+        <interface>
+            <name>IOmxStore</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.memtrack</name>
+        <version>1.0</version>
+        <interface>
+            <name>IMemtrack</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.nfc</name>
+        <version>1.0</version>
+        <interface>
+            <name>INfc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.oemlock</name>
+        <version>1.0</version>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.power</name>
+        <version>1.0</version>
+        <interface>
+            <name>IPower</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.radio</name>
+        <version>1.0</version>
+        <interface>
+            <name>IRadio</name>
+            <instance>slot1</instance>
+        </interface>
+        <interface>
+            <name>ISap</name>
+            <instance>slot1</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.radio.deprecated</name>
+        <version>1.0</version>
+        <interface>
+            <name>IOemHook</name>
+            <instance>slot1</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.renderscript</name>
+        <version>1.0</version>
+        <interface>
+            <name>IDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.sensors</name>
+        <version>1.0</version>
+        <interface>
+            <name>ISensors</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.soundtrigger</name>
+        <version>2.0</version>
+        <interface>
+            <name>ISoundTriggerHw</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.thermal</name>
+        <version>1.0</version>
+        <interface>
+            <name>IThermal</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tv.cec</name>
+        <version>1.0</version>
+        <interface>
+            <name>IHdmiCec</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tv.input</name>
+        <version>1.0</version>
+        <interface>
+            <name>ITvInput</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.usb</name>
+        <version>1.0</version>
+        <interface>
+            <name>IUsb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.vibrator</name>
+        <version>1.0</version>
+        <interface>
+            <name>IVibrator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.vr</name>
+        <version>1.0</version>
+        <interface>
+            <name>IVr</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.weaver</name>
+        <version>1.0</version>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.wifi</name>
+        <version>1.0</version>
+        <interface>
+            <name>IWifi</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.wifi.supplicant</name>
+        <version>1.0</version>
+        <interface>
+            <name>ISupplicant</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <kernel version="4.9.0" />
+    <kernel version="4.4.0" />
+    <kernel version="3.18.0" />
+</compatibility-matrix>
diff --git a/compatibility_matrix.legacy.xml b/compatibility_matrix.legacy.xml
new file mode 100644 (file)
index 0000000..6167f25
--- /dev/null
@@ -0,0 +1,325 @@
+<compatibility-matrix version="1.0" type="framework">
+    <hal format="hidl" optional="false">
+        <name>android.hardware.audio</name>
+        <version>2.0</version>
+        <interface>
+            <name>IDevicesFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.audio.effect</name>
+        <version>2.0</version>
+        <interface>
+            <name>IEffectsFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.evs</name>
+        <version>1.0</version>
+        <interface>
+            <name>IEvsEnumerator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.vehicle</name>
+        <version>2.0</version>
+        <interface>
+            <name>IVehicle</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.biometrics.fingerprint</name>
+        <version>2.1</version>
+        <interface>
+            <name>IBiometricsFingerprint</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.bluetooth</name>
+        <version>1.0</version>
+        <interface>
+            <name>IBluetoothHci</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.boot</name>
+        <version>1.0</version>
+        <interface>
+            <name>IBootControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.broadcastradio</name>
+        <version>1.0</version>
+        <interface>
+            <name>IBroadcastRadioFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.camera.provider</name>
+        <version>2.4</version>
+        <interface>
+            <name>ICameraProvider</name>
+            <instance>legacy/0</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.configstore</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>ISurfaceFlingerConfigs</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.contexthub</name>
+        <version>1.0</version>
+        <interface>
+            <name>IContexthub</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.drm</name>
+        <version>1.0</version>
+        <interface>
+            <name>ICryptoFactory</name>
+            <instance>default</instance>
+        </interface>
+        <interface>
+            <name>IDrmFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.dumpstate</name>
+        <version>1.0</version>
+        <interface>
+            <name>IDumpstateDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.gatekeeper</name>
+        <version>1.0</version>
+        <interface>
+            <name>IGatekeeper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.gnss</name>
+        <version>1.0</version>
+        <interface>
+            <name>IGnss</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.graphics.allocator</name>
+        <version>2.0</version>
+        <interface>
+            <name>IAllocator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.graphics.composer</name>
+        <version>2.1</version>
+        <interface>
+            <name>IComposer</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.graphics.mapper</name>
+        <version>2.0</version>
+        <interface>
+            <name>IMapper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.health</name>
+        <version>1.0</version>
+        <interface>
+            <name>IHealth</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.ir</name>
+        <version>1.0</version>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.keymaster</name>
+        <version>3.0</version>
+        <interface>
+            <name>IKeymasterDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.light</name>
+        <version>2.0</version>
+        <interface>
+            <name>ILight</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.media.omx</name>
+        <version>1.0</version>
+        <interface>
+            <name>IOmx</name>
+            <instance>default</instance>
+        </interface>
+        <interface>
+            <name>IOmxStore</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.memtrack</name>
+        <version>1.0</version>
+        <interface>
+            <name>IMemtrack</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.nfc</name>
+        <version>1.0</version>
+        <interface>
+            <name>INfc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.power</name>
+        <version>1.0</version>
+        <interface>
+            <name>IPower</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.radio</name>
+        <version>1.0</version>
+        <interface>
+            <name>IRadio</name>
+            <instance>slot1</instance>
+        </interface>
+        <interface>
+            <name>ISap</name>
+            <instance>slot1</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.radio.deprecated</name>
+        <version>1.0</version>
+        <interface>
+            <name>IOemHook</name>
+            <instance>slot1</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.renderscript</name>
+        <version>1.0</version>
+        <interface>
+            <name>IDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.sensors</name>
+        <version>1.0</version>
+        <interface>
+            <name>ISensors</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.soundtrigger</name>
+        <version>2.0</version>
+        <interface>
+            <name>ISoundTriggerHw</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.thermal</name>
+        <version>1.0</version>
+        <interface>
+            <name>IThermal</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tv.cec</name>
+        <version>1.0</version>
+        <interface>
+            <name>IHdmiCec</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tv.input</name>
+        <version>1.0</version>
+        <interface>
+            <name>ITvInput</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.usb</name>
+        <version>1.0</version>
+        <interface>
+            <name>IUsb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.vibrator</name>
+        <version>1.0</version>
+        <interface>
+            <name>IVibrator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.vr</name>
+        <version>1.0</version>
+        <interface>
+            <name>IVr</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.wifi</name>
+        <version>1.0</version>
+        <interface>
+            <name>IWifi</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.wifi.supplicant</name>
+        <version>1.0</version>
+        <interface>
+            <name>ISupplicant</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <kernel version="4.9.0" />
+    <kernel version="4.4.0" />
+    <kernel version="3.18.0" />
+</compatibility-matrix>
diff --git a/configstore/1.0/default/android.hardware.configstore@1.0-service.rc b/configstore/1.0/default/android.hardware.configstore@1.0-service.rc
deleted file mode 100644 (file)
index 563d854..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-service configstore-hal-1-0 /vendor/bin/hw/android.hardware.configstore@1.0-service
-    class hal animation
-    user system
-    group system
index 95cd30b8109b5e832507bde322d0e4debfd8592f..e501580935fe02a09daf04c0cda94f5a4057838e 100644 (file)
@@ -41,6 +41,7 @@ class ConfigstoreHidlTest : public ::testing::VtsHalHidlTargetTestBase {
     virtual void SetUp() override {
         sfConfigs = ::testing::VtsHalHidlTargetTestBase::getService<
             ISurfaceFlingerConfigs>();
+        ASSERT_NE(sfConfigs, nullptr);
     }
 
     virtual void TearDown() override {}
diff --git a/configstore/1.1/Android.bp b/configstore/1.1/Android.bp
new file mode 100644 (file)
index 0000000..92fb7c1
--- /dev/null
@@ -0,0 +1,64 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+    name: "android.hardware.configstore@1.1_hal",
+    srcs: [
+        "ISurfaceFlingerConfigs.hal",
+    ],
+}
+
+genrule {
+    name: "android.hardware.configstore@1.1_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.configstore@1.1",
+    srcs: [
+        ":android.hardware.configstore@1.1_hal",
+    ],
+    out: [
+        "android/hardware/configstore/1.1/SurfaceFlingerConfigsAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.configstore@1.1_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.configstore@1.1",
+    srcs: [
+        ":android.hardware.configstore@1.1_hal",
+    ],
+    out: [
+        "android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h",
+        "android/hardware/configstore/1.1/IHwSurfaceFlingerConfigs.h",
+        "android/hardware/configstore/1.1/BnHwSurfaceFlingerConfigs.h",
+        "android/hardware/configstore/1.1/BpHwSurfaceFlingerConfigs.h",
+        "android/hardware/configstore/1.1/BsSurfaceFlingerConfigs.h",
+    ],
+}
+
+cc_library {
+    name: "android.hardware.configstore@1.1",
+    defaults: ["hidl-module-defaults"],
+    generated_sources: ["android.hardware.configstore@1.1_genc++"],
+    generated_headers: ["android.hardware.configstore@1.1_genc++_headers"],
+    export_generated_headers: ["android.hardware.configstore@1.1_genc++_headers"],
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hardware.configstore@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.configstore@1.0",
+    ],
+}
diff --git a/configstore/1.1/Android.mk b/configstore/1.1/Android.mk
new file mode 100644 (file)
index 0000000..b3f7053
--- /dev/null
@@ -0,0 +1,44 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.configstore-V1.1-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+    android.hardware.configstore-V1.0-java \
+    android.hidl.base-V1.0-java \
+
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES += core-oj hwbinder
+
+#
+# Build ISurfaceFlingerConfigs.hal
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_1/ISurfaceFlingerConfigs.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISurfaceFlingerConfigs.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.1::ISurfaceFlingerConfigs
+
+$(GEN): $(LOCAL_PATH)/ISurfaceFlingerConfigs.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/configstore/1.1/ISurfaceFlingerConfigs.hal b/configstore/1.1/ISurfaceFlingerConfigs.hal
new file mode 100644 (file)
index 0000000..5eacbe0
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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.configstore@1.1;
+
+import @1.0::ISurfaceFlingerConfigs;
+
+/**
+ * New revision of ISurfaceFlingerConfigs
+ */
+
+interface ISurfaceFlingerConfigs extends @1.0::ISurfaceFlingerConfigs {
+};
similarity index 75%
rename from configstore/1.0/default/Android.mk
rename to configstore/1.1/default/Android.mk
index e017cfd284cfab94ff24738e5082508cc9ce8191..ac3d8b039ddfda291d45ab10054892c001667608 100644 (file)
@@ -2,17 +2,18 @@ LOCAL_PATH := $(call my-dir)
 
 ################################################################################
 include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.configstore@1.0-service
+LOCAL_MODULE := android.hardware.configstore@1.1-service
 LOCAL_PROPRIETARY_MODULE := true
 LOCAL_MODULE_CLASS := EXECUTABLES
 LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_INIT_RC := android.hardware.configstore@1.0-service.rc
+LOCAL_INIT_RC := android.hardware.configstore@1.1-service.rc
 LOCAL_SRC_FILES:= service.cpp
 
 include $(LOCAL_PATH)/surfaceflinger.mk
 
 LOCAL_SHARED_LIBRARIES := \
     android.hardware.configstore@1.0 \
+    android.hardware.configstore@1.1 \
     libhidlbase \
     libhidltransport \
     libbase \
similarity index 70%
rename from configstore/1.0/default/SurfaceFlingerConfigs.cpp
rename to configstore/1.1/default/SurfaceFlingerConfigs.cpp
index 9c134ef70a6aa81216870830ccbca6e61cb1f220..5a040f2a89bfdcf143bacf76e46af6d780cbc603 100644 (file)
@@ -1,14 +1,29 @@
-#include "SurfaceFlingerConfigs.h"
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-#include <android-base/logging.h>
+#include "SurfaceFlingerConfigs.h"
 
 namespace android {
 namespace hardware {
 namespace configstore {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 
-// Methods from ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs follow.
+// Methods from ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs
+// follow.
 Return<void> SurfaceFlingerConfigs::vsyncEventPhaseOffsetNs(vsyncEventPhaseOffsetNs_cb _hidl_cb) {
 #ifdef VSYNC_EVENT_PHASE_OFFSET_NS
     _hidl_cb({true, VSYNC_EVENT_PHASE_OFFSET_NS});
@@ -36,7 +51,8 @@ Return<void> SurfaceFlingerConfigs::useContextPriority(useContextPriority_cb _hi
     return Void();
 }
 
-Return<void> SurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers(maxFrameBufferAcquiredBuffers_cb _hidl_cb) {
+Return<void> SurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers(
+    maxFrameBufferAcquiredBuffers_cb _hidl_cb) {
 #ifdef NUM_FRAMEBUFFER_SURFACE_BUFFERS
     _hidl_cb({true, NUM_FRAMEBUFFER_SURFACE_BUFFERS});
 #else
@@ -72,13 +88,14 @@ Return<void> SurfaceFlingerConfigs::hasHDRDisplay(hasHDRDisplay_cb _hidl_cb) {
     return Void();
 }
 
-Return<void> SurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs(presentTimeOffsetFromVSyncNs_cb _hidl_cb) {
+Return<void> SurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs(
+    presentTimeOffsetFromVSyncNs_cb _hidl_cb) {
 #ifdef PRESENT_TIME_OFFSET_FROM_VSYNC_NS
-      _hidl_cb({true, PRESENT_TIME_OFFSET_FROM_VSYNC_NS});
+    _hidl_cb({true, PRESENT_TIME_OFFSET_FROM_VSYNC_NS});
 #else
-      _hidl_cb({false, 0});
+    _hidl_cb({false, 0});
 #endif
-      return Void();
+    return Void();
 }
 
 Return<void> SurfaceFlingerConfigs::useHwcForRGBtoYUV(useHwcForRGBtoYUV_cb _hidl_cb) {
@@ -91,14 +108,14 @@ Return<void> SurfaceFlingerConfigs::useHwcForRGBtoYUV(useHwcForRGBtoYUV_cb _hidl
 }
 
 Return<void> SurfaceFlingerConfigs::maxVirtualDisplaySize(maxVirtualDisplaySize_cb _hidl_cb) {
-  uint64_t maxSize = 0;
+    uint64_t maxSize = 0;
 #ifdef MAX_VIRTUAL_DISPLAY_DIMENSION
-  maxSize = MAX_VIRTUAL_DISPLAY_DIMENSION;
-  _hidl_cb({true, maxSize});
+    maxSize = MAX_VIRTUAL_DISPLAY_DIMENSION;
+    _hidl_cb({true, maxSize});
 #else
-  _hidl_cb({false, maxSize});
+    _hidl_cb({false, maxSize});
 #endif
-  return Void();
+    return Void();
 }
 
 Return<void> SurfaceFlingerConfigs::useVrFlinger(useVrFlinger_cb _hidl_cb) {
@@ -122,8 +139,13 @@ Return<void> SurfaceFlingerConfigs::startGraphicsAllocatorService(
     return Void();
 }
 
+// Methods from ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs
+// follow.
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace configstore
 }  // namespace hardware
 }  // namespace android
similarity index 59%
rename from configstore/1.0/default/SurfaceFlingerConfigs.h
rename to configstore/1.1/default/SurfaceFlingerConfigs.h
index 17a424ec5c9c9d2557cd2bb3d2be2f5dac6021dc..53e8ae8714aa3dc6a328f3181343cb3fda7222c4 100644 (file)
@@ -1,31 +1,26 @@
-#ifndef ANDROID_HARDWARE_CONFIGSTORE_V1_0_SURFACEFLINGERCONFIGS_H
-#define ANDROID_HARDWARE_CONFIGSTORE_V1_0_SURFACEFLINGERCONFIGS_H
+#ifndef ANDROID_HARDWARE_CONFIGSTORE_V1_1_SURFACEFLINGERCONFIGS_H
+#define ANDROID_HARDWARE_CONFIGSTORE_V1_1_SURFACEFLINGERCONFIGS_H
 
-#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 
 namespace android {
 namespace hardware {
 namespace configstore {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 
-using ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs;
-using ::android::hardware::configstore::V1_0::OptionalBool;
-using ::android::hidl::base::V1_0::IBase;
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
+using ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 using ::android::sp;
 
 struct SurfaceFlingerConfigs : public ISurfaceFlingerConfigs {
-    // Methods from ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs follow.
+    // Methods from
+    // ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs follow.
     Return<void> vsyncEventPhaseOffsetNs(vsyncEventPhaseOffsetNs_cb _hidl_cb) override;
-    Return<void> vsyncSfEventPhaseOffsetNs(vsyncEventPhaseOffsetNs_cb _hidl_cb) override;
+    Return<void> vsyncSfEventPhaseOffsetNs(vsyncSfEventPhaseOffsetNs_cb _hidl_cb) override;
     Return<void> useContextPriority(useContextPriority_cb _hidl_cb) override;
     Return<void> hasWideColorDisplay(hasWideColorDisplay_cb _hidl_cb) override;
     Return<void> hasHDRDisplay(hasHDRDisplay_cb _hidl_cb) override;
@@ -35,17 +30,18 @@ struct SurfaceFlingerConfigs : public ISurfaceFlingerConfigs {
     Return<void> hasSyncFramework(hasSyncFramework_cb _hidl_cb) override;
     Return<void> useVrFlinger(useVrFlinger_cb _hidl_cb) override;
     Return<void> maxFrameBufferAcquiredBuffers(maxFrameBufferAcquiredBuffers_cb _hidl_cb) override;
-    Return<void> startGraphicsAllocatorService(
-        startGraphicsAllocatorService_cb _hidl_cb) override;
+    Return<void> startGraphicsAllocatorService(startGraphicsAllocatorService_cb _hidl_cb) override;
 
-    // Methods from ::android::hidl::base::V1_0::IBase follow.
+    // Methods from
+    // ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs follow.
 
+    // Methods from ::android::hidl::base::V1_0::IBase follow.
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace configstore
 }  // namespace hardware
 }  // namespace android
 
-#endif  // ANDROID_HARDWARE_CONFIGSTORE_V1_0_SURFACEFLINGERCONFIGS_H
+#endif  // ANDROID_HARDWARE_CONFIGSTORE_V1_1_SURFACEFLINGERCONFIGS_H
diff --git a/configstore/1.1/default/android.hardware.configstore@1.1-service.rc b/configstore/1.1/default/android.hardware.configstore@1.1-service.rc
new file mode 100644 (file)
index 0000000..018ef10
--- /dev/null
@@ -0,0 +1,4 @@
+service configstore-hal /vendor/bin/hw/android.hardware.configstore@1.1-service
+    class hal animation
+    user system
+    group system
similarity index 76%
rename from configstore/1.0/default/service.cpp
rename to configstore/1.1/default/service.cpp
index 60b69abe065642a5449caa89c3f12841f1ce574d..3a4cd3fd67888f5d07779f784ff445b3373c5f24 100644 (file)
@@ -1,11 +1,11 @@
 /*
  * Copyright (C) 2017 The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
+ * Licensed under the Apache License, Version 2.1 (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
+ *      http://www.apache.org/licenses/LICENSE-2.1
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * limitations under the License.
  */
 
-#define LOG_TAG "android.hardware.configstore@1.0-service"
+#define LOG_TAG "android.hardware.configstore@1.1-service"
 
-#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
 #include <hidl/HidlTransportSupport.h>
 
 #include "SurfaceFlingerConfigs.h"
 
 using android::hardware::configureRpcThreadpool;
 using android::hardware::joinRpcThreadpool;
-using android::hardware::configstore::V1_0::ISurfaceFlingerConfigs;
-using android::hardware::configstore::V1_0::implementation::SurfaceFlingerConfigs;
+using android::hardware::configstore::V1_1::ISurfaceFlingerConfigs;
+using android::hardware::configstore::V1_1::implementation::SurfaceFlingerConfigs;
 using android::sp;
 using android::status_t;
 using android::OK;
diff --git a/configstore/1.1/vts/functional/Android.bp b/configstore/1.1/vts/functional/Android.bp
new file mode 100644 (file)
index 0000000..5cfa483
--- /dev/null
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "VtsHalConfigstoreV1_1TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalConfigstoreV1_1TargetTest.cpp"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+        "android.hardware.configstore@1.1",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ]
+}
+
diff --git a/configstore/1.1/vts/functional/VtsHalConfigstoreV1_1TargetTest.cpp b/configstore/1.1/vts/functional/VtsHalConfigstoreV1_1TargetTest.cpp
new file mode 100644 (file)
index 0000000..bd3da4c
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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 "ConfigstoreHidlHalTest"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/logging.h>
+#include <android/hardware/configstore/1.0/types.h>
+#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
+#include <unistd.h>
+
+using ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs;
+using ::android::sp;
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+#define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk())
+
+class ConfigstoreHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    sp<ISurfaceFlingerConfigs> sfConfigs;
+
+    virtual void SetUp() override {
+        sfConfigs = ::testing::VtsHalHidlTargetTestBase::getService<ISurfaceFlingerConfigs>();
+        ASSERT_NE(sfConfigs, nullptr);
+    }
+
+    virtual void TearDown() override {}
+};
+
+/**
+ * Placeholder testcase.
+ */
+TEST_F(ConfigstoreHidlTest, Test) {
+    ASSERT_TRUE(true);
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    LOG(INFO) << "Test result = " << status;
+    return status;
+}
index ba3e62e29b93a6c1842d6c192a363c6cf76110ff..4a783c3d7efa4d64f37b6191a4f6188b78f7d1de 100644 (file)
@@ -2,5 +2,7 @@
 subdirs = [
     "1.0",
     "1.0/vts/functional",
+    "1.1",
+    "1.1/vts/functional",
     "utils",
 ]
index 78d27cc5a865930c68a7289b25bfc21b5569e591..9f5131d6e314e51530fbca00065e8d559eb1d78f 100644 (file)
@@ -32,3 +32,23 @@ cc_library_shared {
         "android.hardware.contexthub@1.0",
     ],
 }
+
+cc_binary {
+    name: "android.hardware.contexthub@1.0-service",
+    relative_install_path: "hw",
+    proprietary: true,
+    init_rc: ["android.hardware.contexthub@1.0-service.rc"],
+    srcs: ["service.cpp"],
+
+    shared_libs: [
+        "libbase",
+        "libcutils",
+        "libdl",
+        "libhardware",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+        "android.hardware.contexthub@1.0",
+    ],
+}
diff --git a/contexthub/1.0/default/Android.mk b/contexthub/1.0/default/Android.mk
deleted file mode 100644 (file)
index 917bfe0..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_MODULE := android.hardware.contexthub@1.0-service
-LOCAL_INIT_RC := android.hardware.contexthub@1.0-service.rc
-LOCAL_SRC_FILES := \
-        service.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
-        libbase \
-        libcutils \
-        libdl \
-        libhardware \
-        libhidlbase \
-        libhidltransport \
-        liblog \
-        libutils \
-        android.hardware.contexthub@1.0 \
-
-include $(BUILD_EXECUTABLE)
index 0828c6efa6e54eb9b4bbb497af3897f41f582a44..a3ff61e8f2f45d0e735bc0221ae7eb07c4a89191 100644 (file)
@@ -189,7 +189,37 @@ fe3c3c2f572b72f15f8594c538b0577bd5c28722c31879cfe6231330cddb6747 android.hardwar
 
 # ABI preserving changes to HALs released in Android O
 
+760485232f6cce07f8bb05e3475509956996b702f77415ee5bff05e2ec5a5bcc android.hardware.dumpstate@1.0::IDumpstateDevice
+e822cb7f4a1bdd45689c5e92ccd19a2201c20b771bd4b2ec1ae627e324591f9d android.hardware.radio@1.0::IRadioResponse
 28e929b453df3d9f5060af2764e6cdb123ddb893e3e86923c877f6ff7e5f02c9 android.hardware.wifi@1.0::types
 
+# HALs released in Android O MR1
+
+4b65763663a94a3920134011691f8fbb42ccb7b7795589efddc049a9106047d6 android.hardware.oemlock@1.0::IOemLock
+e02cd3722cb5e8fa51179f5defacb4f7866f903c9c7c51dc01a3148473a71525 android.hardware.oemlock@1.0::types
+224f9d22a367a0016f09b6dc676f53f1446697d9dc747163032329e5da552de5 android.hardware.power@1.1::IPower
+574fd9758b7cab4922c72cc5a9f36d1cd48ffd3425fdd776426653280d3d4138 android.hardware.power@1.1::types
+f79edf50a378a9c9bb737f93f205dab91b4c63ea49723afc6f856c138203ea81 android.hardware.radio@1.1::IRadio
+fcc5c8c88b85a9f63fba67d9e674da466c72a98ca287f343fb5721d098713f86 android.hardware.radio@1.1::IRadioIndication
+50f27e8c7ec009d5d4418b2ce8392b940bbf052ecc1d7251285f332485a5ba4e android.hardware.radio@1.1::IRadioResponse
+be981148c95c0089f3ae92854f0e7ae999d308e927db3e065f12a4fabe07852f android.hardware.radio@1.1::ISap
+d8d6bf7b4d36c04ce587df75953c3f723cfbe71c896c1aa8ab6478eae126723d android.hardware.radio@1.1::types
+d8aae01606bfd34bf2fb9a59cadc016f46f318e56cddb8f15a945c5b3c1222bc android.hardware.tetheroffload.config@1.0::IOffloadConfig
+447b00306bc95a7aafec1d660f6f3e9f76ac8bc0353193435e5579ab833da619 android.hardware.tetheroffload.control@1.0::IOffloadControl
+07658829339d75962016e00ed81b005ad29fca7ac12ad3bc3ccd86b08d94c2d3 android.hardware.tetheroffload.control@1.0::ITetheringOffloadCallback
+0df5b0178af15c53cdce8fcf8ca14035e8e08db4fa76fdc12009ddbe0b53626b android.hardware.tetheroffload.control@1.0::types
+b30ef02ef26ff804e2f6acf1201bc141b59e134e6a0338562284491102cb13e3 android.hardware.usb@1.1::IUsb
+13a580e35af01270a1e9774177c51db51d8672e6139ba00851e654e68a4d7dff android.hardware.usb@1.1::IUsbCallback
+f0ed667288908c08fced570bd1f3c4a0f236aa927938e805f0d9fece525da81e android.hardware.usb@1.1::types
+f95a1e85612f2d0d616eacd2eb63c52d10dfa889f165df57697c30e1f47b4785 android.hardware.vibrator@1.1::IVibrator
+246fb9d9e2b4800aeb0adc3cdbaa15d0321ebab54b7bd1ab87da5b67c7b0b064 android.hardware.vibrator@1.1::types
+9bc43413b80cd0c59a022e93da1448dcb82dd10c6dd31932df4659e4bdcb1368 android.hardware.weaver@1.0::IWeaver
+7728b0393a2ed9796537d4165c7d95407e9d8cb447a647b545fdfe06a28689e7 android.hardware.weaver@1.0::types
+bb7c96762d0aa3ddb874c8815bacdd3cbc8fb87ea2f82b928bc29e24a3593055 android.hardware.wifi.offload@1.0::IOffload
+c3354ab0d381a236c12dc486ad4b6bec28c979d26748b4661f12ede36f392808 android.hardware.wifi.offload@1.0::IOffloadCallback
+b18caefefcc765092412285d776234fcf213b73bdf07ae1b67a5f71b2d2464e3 android.hardware.wifi.offload@1.0::types
+c26473e2e4a00af43e28a0ddf9002e5062a7d0940429e5efb6e5513a8abcb75c android.hardware.wifi@1.1::IWifi
+b056e1defab4071584214584057d0bc73a613081bf1152590549649d4582c13c android.hardware.wifi@1.1::IWifiChip
+
 # HALs released in Android O MR1 (Final Set)
 0a159f81359cd4f71bbe00972ee8403ea79351fb7c0cd48be72ebb3e424dbaef android.hardware.radio@1.0::types
index 194b2a7bbac6f0fa1cd948936eba787976933c11..84ee5dfc497ac24a037e43f32408f14dc55c75d5 100644 (file)
@@ -16,7 +16,6 @@
 
 #define LOG_TAG "drm_hal_clearkey_test@1.0"
 
-#include <android-base/logging.h>
 #include <android/hardware/drm/1.0/ICryptoFactory.h>
 #include <android/hardware/drm/1.0/ICryptoPlugin.h>
 #include <android/hardware/drm/1.0/IDrmFactory.h>
@@ -27,8 +26,8 @@
 #include <hidl/HidlSupport.h>
 #include <hidlmemory/mapping.h>
 #include <log/log.h>
-#include <openssl/aes.h>
 #include <memory>
+#include <openssl/aes.h>
 #include <random>
 
 #include "VtsHalHidlTargetTestBase.h"
index 389ffec70616811980f9c51daa9677a9a013569f..2e080b30505bd615f16a16c45b5f0032cfecb002 100644 (file)
@@ -16,7 +16,6 @@
 
 #define LOG_TAG "drm_hal_vendor_test@1.0"
 
-#include <android-base/logging.h>
 #include <android/hardware/drm/1.0/ICryptoFactory.h>
 #include <android/hardware/drm/1.0/ICryptoPlugin.h>
 #include <android/hardware/drm/1.0/IDrmFactory.h>
@@ -27,8 +26,8 @@
 #include <gtest/gtest.h>
 #include <hidlmemory/mapping.h>
 #include <log/log.h>
-#include <openssl/aes.h>
 #include <memory>
+#include <openssl/aes.h>
 #include <random>
 
 #include "drm_hal_vendor_module_api.h"
@@ -129,7 +128,7 @@ class DrmHalVendorFactoryTest : public testing::TestWithParam<std::string> {
         // Do the same for the crypto factory
         cryptoFactory = VtsTestBase::getService<ICryptoFactory>(name);
         if (cryptoFactory == nullptr) {
-            VtsTestBase::getService<ICryptoFactory>();
+            cryptoFactory = VtsTestBase::getService<ICryptoFactory>();
         }
         ASSERT_NE(cryptoFactory, nullptr);
 
@@ -1596,9 +1595,8 @@ int main(int argc, char** argv) {
 #endif
     gVendorModules = new drm_vts::VendorModules(kModulePath);
     if (gVendorModules->getPathList().size() == 0) {
-        std::cerr << "No vendor modules found in " << kModulePath <<
-                ", exiting" << std::endl;
-        exit(-1);
+        std::cerr << "WARNING: No vendor modules found in " << kModulePath <<
+                ", all vendor tests will be skipped" << std::endl;
     }
     ::testing::InitGoogleTest(&argc, argv);
     return RUN_ALL_TESTS();
index 206c139b36c411b178cef41d2fee940b590912ff..12a0db40b6728bd73454ffbdceaff1b9022c8306 100644 (file)
@@ -18,7 +18,14 @@ package android.hardware.dumpstate@1.0;
 
 interface IDumpstateDevice {
     /**
-     * Dumps device-specific state into the given file descriptor.
+     * Dump device-specific state into the given file descriptors.
+     *
+     * One file descriptor must be passed to this method but two may be passed:
+     * the first descriptor must be used to dump device-specific state in text
+     * format, the second descriptor is optional and may be used to dump
+     * device-specific state in binary format.
+     *
+     * @param h A native handle with one or two valid file descriptors.
      */
     dumpstateBoard(handle h);
 };
index 213fc62252a831c0cc4018597b336be56e3846e0..818a53127cfb7580035bee409fc4d5fd7d1cff63 100644 (file)
@@ -37,7 +37,7 @@ Return<void> DumpstateDevice::dumpstateBoard(const hidl_handle& handle) {
     // this interface - since HIDL_FETCH_IDumpstateDevice() is not defined, this function will never
     // be called by dumpstate.
 
-    if (handle->numFds < 1) {
+    if (handle == nullptr || handle->numFds < 1) {
         ALOGE("no FDs\n");
         return Void();
     }
diff --git a/dumpstate/1.0/vts/functional/Android.bp b/dumpstate/1.0/vts/functional/Android.bp
new file mode 100644 (file)
index 0000000..a1c735b
--- /dev/null
@@ -0,0 +1,32 @@
+//
+// 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.
+
+cc_test {
+    name: "VtsHalDumpstateV1_0TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalDumpstateV1_0TargetTest.cpp"],
+    shared_libs: [
+        "android.hardware.dumpstate@1.0",
+        "libcutils",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ]
+}
diff --git a/dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp b/dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp
new file mode 100644 (file)
index 0000000..046bf56
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * 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 "dumpstate_hidl_hal_test"
+
+#include <android/hardware/dumpstate/1.0/IDumpstateDevice.h>
+#include <cutils/native_handle.h>
+#include <log/log.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+using ::android::hardware::dumpstate::V1_0::IDumpstateDevice;
+using ::android::hardware::Return;
+using ::android::sp;
+
+class DumpstateHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        dumpstate = ::testing::VtsHalHidlTargetTestBase::getService<IDumpstateDevice>();
+        ASSERT_NE(dumpstate, nullptr) << "Could not get HIDL instance";
+    }
+
+    sp<IDumpstateDevice> dumpstate;
+};
+
+// Negative test: make sure dumpstateBoard() doesn't crash when passed a null pointer.
+TEST_F(DumpstateHidlTest, TestNullHandle) {
+    Return<void> status = dumpstate->dumpstateBoard(nullptr);
+
+    ASSERT_TRUE(status.isOk()) << "Status should be ok: " << status.description();
+}
+
+// Negative test: make sure dumpstateBoard() ignores a handle with no FD.
+TEST_F(DumpstateHidlTest, TestHandleWithNoFd) {
+    native_handle_t* handle = native_handle_create(0, 0);
+    ASSERT_NE(handle, nullptr) << "Could not create native_handle";
+
+    Return<void> status = dumpstate->dumpstateBoard(handle);
+
+    ASSERT_TRUE(status.isOk()) << "Status should be ok: " << status.description();
+
+    native_handle_close(handle);
+    native_handle_delete(handle);
+}
+
+// Positive test: make sure dumpstateBoard() writes something to the FD.
+TEST_F(DumpstateHidlTest, TestOk) {
+    FILE* file = tmpfile();
+
+    ASSERT_NE(nullptr, file) << "Could not create temp file: " << strerror(errno);
+
+    native_handle_t* handle = native_handle_create(1, 0);
+    ASSERT_NE(handle, nullptr) << "Could not create native_handle";
+    handle->data[0] = fileno(file);
+
+    Return<void> status = dumpstate->dumpstateBoard(handle);
+    ASSERT_TRUE(status.isOk()) << "Status should be ok: " << status.description();
+
+    // Check that at least one byte was written
+    rewind(file);  // can not fail
+    char buff;
+    int read = fread(&buff, sizeof(buff), 1, file);
+    ASSERT_EQ(1, read) << "dumped nothing";
+
+    EXPECT_EQ(0, fclose(file)) << errno;
+
+    native_handle_close(handle);
+    native_handle_delete(handle);
+}
+
+// Positive test: make sure dumpstateBoard() doesn't crash with two FDs.
+TEST_F(DumpstateHidlTest, TestHandleWithTwoFds) {
+    FILE* file1 = tmpfile();
+    FILE* file2 = tmpfile();
+
+    ASSERT_NE(nullptr, file1) << "Could not create temp file #1: " << strerror(errno);
+    ASSERT_NE(nullptr, file2) << "Could not create temp file #2: " << strerror(errno);
+
+    native_handle_t* handle = native_handle_create(2, 0);
+    ASSERT_NE(handle, nullptr) << "Could not create native_handle";
+    handle->data[0] = fileno(file1);
+    handle->data[1] = fileno(file2);
+
+    Return<void> status = dumpstate->dumpstateBoard(handle);
+    ASSERT_TRUE(status.isOk()) << "Status should be ok: " << status.description();
+
+    EXPECT_EQ(0, fclose(file1)) << errno;
+    EXPECT_EQ(0, fclose(file2)) << errno;
+
+    native_handle_close(handle);
+    native_handle_delete(handle);
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGI("Test result = %d", status);
+    return status;
+}
index bbb3e4bac0013f69f1ea7483935a8c511a9c07b3..33f70ebae24c1ff58649714b3173644ce5677b78 100644 (file)
@@ -1,4 +1,5 @@
 // This is an autogenerated file, do not edit.
 subdirs = [
     "1.0",
+    "1.0/vts/functional",
 ]
index 13dc96a01d0e06401af644bd17504c33344d176d..e629955e995a1a602522e3ce94a195a836da04a0 100644 (file)
@@ -1,4 +1,4 @@
 service gnss_service /vendor/bin/hw/android.hardware.gnss@1.0-service
-    class main
-    user system
+    class hal
+    user gps
     group system gps radio
index 53181f15dc3f07b7ee1485ca4a9043db0bb0dd45..91e75fe1d7bda3a34fd9a8ffd285f8750ed7a93c 100644 (file)
@@ -39,7 +39,7 @@ using android::sp;
 
 // for command line argument on how strictly to run the test
 bool sAgpsIsPresent = false;  // if SUPL or XTRA assistance available
-bool sSignalIsWeak = false;  // if GNSS signals are weak (e.g. light indoor)
+bool sSignalIsWeak = false;   // if GNSS signals are weak (e.g. light indoor)
 
 // The main test class for GNSS HAL.
 class GnssHalTest : public ::testing::VtsHalHidlTargetTestBase {
@@ -120,6 +120,124 @@ class GnssHalTest : public ::testing::VtsHalHidlTargetTestBase {
     return status;
   }
 
+  /*
+   * StartAndGetSingleLocation:
+   * Helper function to get one Location and check fields
+   *
+   * returns  true if a location was successfully generated
+   */
+  bool StartAndGetSingleLocation(bool checkAccuracies) {
+      auto result = gnss_hal_->start();
+
+      EXPECT_TRUE(result.isOk());
+      EXPECT_TRUE(result);
+
+      /*
+       * GPS signals initially optional for this test, so don't expect fast fix,
+       * or no timeout, unless signal is present
+       */
+      int firstGnssLocationTimeoutSeconds = sAgpsIsPresent ? 15 : 45;
+      if (sSignalIsWeak) {
+          // allow more time for weak signals
+          firstGnssLocationTimeoutSeconds += 30;
+      }
+
+      wait(firstGnssLocationTimeoutSeconds);
+      if (sAgpsIsPresent) {
+          EXPECT_EQ(location_called_count_, 1);
+      }
+      if (location_called_count_ > 0) {
+          CheckLocation(last_location_, checkAccuracies);
+          return true;
+      }
+      return false;
+  }
+
+  /*
+   * StopAndClearLocations:
+   * Helper function to stop locations
+   *
+   * returns  true if a location was successfully generated
+   */
+  void StopAndClearLocations() {
+      auto result = gnss_hal_->stop();
+
+      EXPECT_TRUE(result.isOk());
+      EXPECT_TRUE(result);
+
+      /*
+       * Clear notify/waiting counter, allowing up till the timeout after
+       * the last reply for final startup messages to arrive (esp. system
+       * info.)
+       */
+      while (wait(TIMEOUT_SEC) == std::cv_status::no_timeout) {
+      }
+  }
+
+  /*
+   * CheckLocation:
+   * Helper function to vet Location fields
+   */
+  void CheckLocation(GnssLocation& location, bool checkAccuracies) {
+      EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
+      EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
+      EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED);
+      EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
+      // New uncertainties available in O must be provided,
+      // at least when paired with modern hardware (2017+)
+      if (checkAccuracies) {
+          EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY);
+          EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY);
+          if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
+              EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY);
+          }
+      }
+      EXPECT_GE(location.latitudeDegrees, -90.0);
+      EXPECT_LE(location.latitudeDegrees, 90.0);
+      EXPECT_GE(location.longitudeDegrees, -180.0);
+      EXPECT_LE(location.longitudeDegrees, 180.0);
+      EXPECT_GE(location.altitudeMeters, -1000.0);
+      EXPECT_LE(location.altitudeMeters, 30000.0);
+      EXPECT_GE(location.speedMetersPerSec, 0.0);
+      EXPECT_LE(location.speedMetersPerSec, 5.0);  // VTS tests are stationary.
+
+      // Non-zero speeds must be reported with an associated bearing
+      if (location.speedMetersPerSec > 0.0) {
+          EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING);
+      }
+
+      /*
+       * Tolerating some especially high values for accuracy estimate, in case of
+       * first fix with especially poor geometry (happens occasionally)
+       */
+      EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
+      EXPECT_LE(location.horizontalAccuracyMeters, 250.0);
+
+      /*
+       * Some devices may define bearing as -180 to +180, others as 0 to 360.
+       * Both are okay & understandable.
+       */
+      if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
+          EXPECT_GE(location.bearingDegrees, -180.0);
+          EXPECT_LE(location.bearingDegrees, 360.0);
+      }
+      if (location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
+          EXPECT_GT(location.verticalAccuracyMeters, 0.0);
+          EXPECT_LE(location.verticalAccuracyMeters, 500.0);
+      }
+      if (location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
+          EXPECT_GT(location.speedAccuracyMetersPerSecond, 0.0);
+          EXPECT_LE(location.speedAccuracyMetersPerSecond, 50.0);
+      }
+      if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
+          EXPECT_GT(location.bearingAccuracyDegrees, 0.0);
+          EXPECT_LE(location.bearingAccuracyDegrees, 360.0);
+      }
+
+      // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
+      EXPECT_GT(location.timestamp, 1.48e12);
+  }
+
   /* Callback class for data & Event. */
   class GnssCallback : public IGnssCallback {
    public:
@@ -204,107 +322,6 @@ class GnssHalTest : public ::testing::VtsHalHidlTargetTestBase {
  */
 TEST_F(GnssHalTest, SetCallbackCapabilitiesCleanup) {}
 
-/*
- * CheckLocation:
- * Helper function to vet Location fields
- */
-void CheckLocation(GnssLocation& location, bool checkAccuracies) {
-  EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
-  EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
-  EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED);
-  EXPECT_TRUE(location.gnssLocationFlags &
-              GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
-  // New uncertainties available in O must be provided,
-  // at least when paired with modern hardware (2017+)
-  if (checkAccuracies) {
-    EXPECT_TRUE(location.gnssLocationFlags &
-                GnssLocationFlags::HAS_VERTICAL_ACCURACY);
-    EXPECT_TRUE(location.gnssLocationFlags &
-                GnssLocationFlags::HAS_SPEED_ACCURACY);
-    if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
-      EXPECT_TRUE(location.gnssLocationFlags &
-                  GnssLocationFlags::HAS_BEARING_ACCURACY);
-    }
-  }
-  EXPECT_GE(location.latitudeDegrees, -90.0);
-  EXPECT_LE(location.latitudeDegrees, 90.0);
-  EXPECT_GE(location.longitudeDegrees, -180.0);
-  EXPECT_LE(location.longitudeDegrees, 180.0);
-  EXPECT_GE(location.altitudeMeters, -1000.0);
-  EXPECT_LE(location.altitudeMeters, 30000.0);
-  EXPECT_GE(location.speedMetersPerSec, 0.0);
-  EXPECT_LE(location.speedMetersPerSec, 5.0);  // VTS tests are stationary.
-
-  // Non-zero speeds must be reported with an associated bearing
-  if (location.speedMetersPerSec > 0.0) {
-    EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING);
-  }
-
-  /*
-   * Tolerating some especially high values for accuracy estimate, in case of
-   * first fix with especially poor geometry (happens occasionally)
-   */
-  EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
-  EXPECT_LE(location.horizontalAccuracyMeters, 250.0);
-
-  /*
-   * Some devices may define bearing as -180 to +180, others as 0 to 360.
-   * Both are okay & understandable.
-   */
-  if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
-    EXPECT_GE(location.bearingDegrees, -180.0);
-    EXPECT_LE(location.bearingDegrees, 360.0);
-  }
-  if (location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
-    EXPECT_GT(location.verticalAccuracyMeters, 0.0);
-    EXPECT_LE(location.verticalAccuracyMeters, 500.0);
-  }
-  if (location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
-    EXPECT_GT(location.speedAccuracyMetersPerSecond, 0.0);
-    EXPECT_LE(location.speedAccuracyMetersPerSecond, 50.0);
-  }
-  if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
-    EXPECT_GT(location.bearingAccuracyDegrees, 0.0);
-    EXPECT_LE(location.bearingAccuracyDegrees, 360.0);
-  }
-
-  // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
-  EXPECT_GT(location.timestamp, 1.48e12);
-}
-
-/*
- * StartAndGetSingleLocation:
- * Helper function to get one Location and check fields
- *
- * returns  true if a location was successfully generated
- */
-bool StartAndGetSingleLocation(GnssHalTest* test, bool checkAccuracies) {
-  auto result = test->gnss_hal_->start();
-
-  EXPECT_TRUE(result.isOk());
-  EXPECT_TRUE(result);
-
-  /*
-   * GPS signals initially optional for this test, so don't expect fast fix,
-   * or no timeout, unless signal is present
-   */
-  int firstGnssLocationTimeoutSeconds = sAgpsIsPresent ? 15 : 45;
-  if (sSignalIsWeak) {
-    // allow more time for weak signals
-    firstGnssLocationTimeoutSeconds += 30;
-  }
-
-  test->wait(firstGnssLocationTimeoutSeconds);
-  if (sAgpsIsPresent) {
-    EXPECT_EQ(test->location_called_count_, 1);
-  }
-  if (test->location_called_count_ > 0) {
-    CheckLocation(test->last_location_, checkAccuracies);
-    return true;
-  }
-  return false;
-}
-
 /*
  * GetLocation:
  * Turns on location, waits 45 second for at least 5 locations,
@@ -333,21 +350,17 @@ TEST_F(GnssHalTest, GetLocation) {
    * GPS signals initially optional for this test, so don't expect no timeout
    * yet
    */
-  bool gotLocation = StartAndGetSingleLocation(this, checkMoreAccuracies);
+  bool gotLocation = StartAndGetSingleLocation(checkMoreAccuracies);
 
   if (gotLocation) {
     for (int i = 1; i < LOCATIONS_TO_CHECK; i++) {
-      EXPECT_EQ(std::cv_status::no_timeout,
-          wait(LOCATION_TIMEOUT_SUBSEQUENT_SEC));
-      EXPECT_EQ(location_called_count_, i + 1);
-      CheckLocation(last_location_, checkMoreAccuracies);
+        EXPECT_EQ(std::cv_status::no_timeout, wait(LOCATION_TIMEOUT_SUBSEQUENT_SEC));
+        EXPECT_EQ(location_called_count_, i + 1);
+        CheckLocation(last_location_, checkMoreAccuracies);
     }
   }
 
-  result = gnss_hal_->stop();
-
-  ASSERT_TRUE(result.isOk());
-  ASSERT_TRUE(result);
+  StopAndClearLocations();
 }
 
 /*
@@ -372,7 +385,9 @@ TEST_F(GnssHalTest, InjectDelete) {
   ASSERT_TRUE(resultVoid.isOk());
 
   // Ensure we can get a good location after a bad injection has been deleted
-  StartAndGetSingleLocation(this, false);
+  StartAndGetSingleLocation(false);
+
+  StopAndClearLocations();
 }
 
 /*
@@ -441,13 +456,13 @@ int main(int argc, char** argv) {
    * stronger tests that require the presence of GPS signal.
    */
   for (int i = 1; i < argc; i++) {
-    if (strcmp(argv[i],"-agps") == 0) {
-      sAgpsIsPresent = true;
-    } else if (strcmp(argv[i],"-weak") == 0) {
-      sSignalIsWeak = true;
+      if (strcmp(argv[i], "-agps") == 0) {
+          sAgpsIsPresent = true;
+      } else if (strcmp(argv[i], "-weak") == 0) {
+          sSignalIsWeak = true;
     }
   }
   int status = RUN_ALL_TESTS();
   ALOGI("Test result = %d", status);
   return status;
-}
\ No newline at end of file
+}
index c0a5e1e0cbfcd03abded21645b2e3cc5d6538997..6cbb7915563ebc44900d058b1455106d46a3fcee 100644 (file)
@@ -200,8 +200,8 @@ uint64_t Gralloc1Allocator::toProducerUsage(uint64_t usage) {
     // should be filtered out
     uint64_t producerUsage =
         usage &
-        ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK |
-                               BufferUsage::CPU_WRITE_MASK);
+        ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK |
+                               BufferUsage::GPU_DATA_BUFFER);
 
     switch (usage & BufferUsage::CPU_WRITE_MASK) {
         case static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY):
@@ -225,6 +225,8 @@ uint64_t Gralloc1Allocator::toProducerUsage(uint64_t usage) {
             break;
     }
 
+    // BufferUsage::GPU_DATA_BUFFER is always filtered out
+
     return producerUsage;
 }
 
@@ -233,8 +235,8 @@ uint64_t Gralloc1Allocator::toConsumerUsage(uint64_t usage) {
     // should be filtered out
     uint64_t consumerUsage =
         usage &
-        ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK |
-                               BufferUsage::CPU_WRITE_MASK);
+        ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK |
+                               BufferUsage::SENSOR_DIRECT_DATA | BufferUsage::GPU_DATA_BUFFER);
 
     switch (usage & BufferUsage::CPU_READ_MASK) {
         case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY):
@@ -247,6 +249,12 @@ uint64_t Gralloc1Allocator::toConsumerUsage(uint64_t usage) {
             break;
     }
 
+    // BufferUsage::SENSOR_DIRECT_DATA is always filtered out
+
+    if (usage & BufferUsage::GPU_DATA_BUFFER) {
+        consumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER;
+    }
+
     return consumerUsage;
 }
 
index a43740c8750f13bc6318ab814ddb8d11256dd2cc..99f462cf24fa95fdd48e0263ba6d5f337b8ceb39 100644 (file)
@@ -24,5 +24,5 @@ using android::hardware::graphics::allocator::V2_0::IAllocator;
 using android::hardware::defaultPassthroughServiceImplementation;
 
 int main() {
-    return defaultPassthroughServiceImplementation<IAllocator>();
+    return defaultPassthroughServiceImplementation<IAllocator>(4);
 }
index 5a96e298fcbb8213ec0350f1631b8ec07cf05eb9..e79203404ec4c5ce202934b540c03d9ba015d307 100644 (file)
@@ -1149,6 +1149,13 @@ Error ComposerClient::CommandReader::lookupBuffer(BufferCache cache,
 
         // input handle is ignored
         *outHandle = entry->getHandle();
+    } else if (cache == BufferCache::LAYER_SIDEBAND_STREAMS) {
+        if (handle) {
+            *outHandle = native_handle_clone(handle);
+            if (*outHandle == nullptr) {
+                return Error::NO_RESOURCES;
+            }
+        }
     } else {
         if (!sHandleImporter.importBuffer(handle)) {
             return Error::NO_RESOURCES;
index ee825feb3d4d9ecc24ecea1997c891526c9dbee5..fc5c223095be2eb3adc1b4f6f1d445aedc1108f7 100644 (file)
@@ -110,6 +110,7 @@ public:
 protected:
     struct LayerBuffers {
         std::vector<BufferCacheEntry> Buffers;
+        // the handle is a sideband stream handle, not a buffer handle
         BufferCacheEntry SidebandStream;
     };
 
index 66323d4a4ff292cc85223f4a2e1bec1ec5510192..2e87144dbb63c348169876815a52a7da6a1e4abb 100644 (file)
 cc_library_static {
     name: "libVtsHalGraphicsComposerTestUtils",
     defaults: ["hidl_defaults"],
-    srcs: ["VtsHalGraphicsComposerTestUtils.cpp"],
-    shared_libs: ["android.hardware.graphics.composer@2.1"],
+    srcs: [
+        "GraphicsComposerCallback.cpp",
+        "TestCommandReader.cpp",
+        "VtsHalGraphicsComposerTestUtils.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.graphics.composer@2.1",
+        "libfmq",
+        "libsync",
+    ],
     static_libs: [
+        "libhwcomposer-command-buffer",
         "VtsHalHidlTargetTestBase",
     ],
     cflags: [
@@ -28,6 +37,7 @@ cc_library_static {
         "-Werror",
         "-O0",
         "-g",
+        "-DLOG_TAG=\"GraphicsComposerTestUtils\"",
     ],
     export_include_dirs: ["."],
 }
diff --git a/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.cpp b/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.cpp
new file mode 100644 (file)
index 0000000..0ad440c
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+#include "GraphicsComposerCallback.h"
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace tests {
+
+void GraphicsComposerCallback::setVsyncAllowed(bool allowed) {
+  std::lock_guard<std::mutex> lock(mMutex);
+  mVsyncAllowed = allowed;
+}
+
+std::vector<Display> GraphicsComposerCallback::getDisplays() const {
+  std::lock_guard<std::mutex> lock(mMutex);
+  return std::vector<Display>(mDisplays.begin(), mDisplays.end());
+}
+
+int GraphicsComposerCallback::getInvalidHotplugCount() const {
+  std::lock_guard<std::mutex> lock(mMutex);
+  return mInvalidHotplugCount;
+}
+
+int GraphicsComposerCallback::getInvalidRefreshCount() const {
+  std::lock_guard<std::mutex> lock(mMutex);
+  return mInvalidRefreshCount;
+}
+
+int GraphicsComposerCallback::getInvalidVsyncCount() const {
+  std::lock_guard<std::mutex> lock(mMutex);
+  return mInvalidVsyncCount;
+}
+
+Return<void> GraphicsComposerCallback::onHotplug(Display display,
+                                                 Connection connection) {
+  std::lock_guard<std::mutex> lock(mMutex);
+
+  if (connection == Connection::CONNECTED) {
+    if (!mDisplays.insert(display).second) {
+      mInvalidHotplugCount++;
+    }
+  } else if (connection == Connection::DISCONNECTED) {
+    if (!mDisplays.erase(display)) {
+      mInvalidHotplugCount++;
+    }
+  }
+
+  return Void();
+}
+
+Return<void> GraphicsComposerCallback::onRefresh(Display display) {
+  std::lock_guard<std::mutex> lock(mMutex);
+
+  if (mDisplays.count(display) == 0) {
+    mInvalidRefreshCount++;
+  }
+
+  return Void();
+}
+
+Return<void> GraphicsComposerCallback::onVsync(Display display, int64_t) {
+  std::lock_guard<std::mutex> lock(mMutex);
+
+  if (!mVsyncAllowed || mDisplays.count(display) == 0) {
+    mInvalidVsyncCount++;
+  }
+
+  return Void();
+}
+
+}  // namespace tests
+}  // namespace V2_1
+}  // namespace composer
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
diff --git a/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h b/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h
new file mode 100644 (file)
index 0000000..e332086
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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 GRAPHICS_COMPOSER_CALLBACK_H
+#define GRAPHICS_COMPOSER_CALLBACK_H
+
+#include <android/hardware/graphics/composer/2.1/IComposerCallback.h>
+
+#include <mutex>
+#include <unordered_set>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace tests {
+
+// IComposerCallback to be installed with IComposerClient::registerCallback.
+class GraphicsComposerCallback : public IComposerCallback {
+ public:
+  void setVsyncAllowed(bool allowed);
+
+  std::vector<Display> getDisplays() const;
+
+  int getInvalidHotplugCount() const;
+
+  int getInvalidRefreshCount() const;
+
+  int getInvalidVsyncCount() const;
+
+ private:
+  Return<void> onHotplug(Display display, Connection connection) override;
+  Return<void> onRefresh(Display display) override;
+  Return<void> onVsync(Display display, int64_t) override;
+
+  mutable std::mutex mMutex;
+  // the set of all currently connected displays
+  std::unordered_set<Display> mDisplays;
+  // true only when vsync is enabled
+  bool mVsyncAllowed = true;
+
+  // track invalid callbacks
+  int mInvalidHotplugCount = 0;
+  int mInvalidRefreshCount = 0;
+  int mInvalidVsyncCount = 0;
+};
+
+}  // namespace tests
+}  // namespace V2_1
+}  // namespace composer
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // GRAPHICS_COMPOSER_CALLBACK_H
diff --git a/graphics/composer/2.1/vts/functional/TestCommandReader.cpp b/graphics/composer/2.1/vts/functional/TestCommandReader.cpp
new file mode 100644 (file)
index 0000000..b1f9aca
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#include "TestCommandReader.h"
+
+#include <gtest/gtest.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace tests {
+
+void TestCommandReader::parse() {
+  while (!isEmpty()) {
+    IComposerClient::Command command;
+    uint16_t length;
+    ASSERT_TRUE(beginCommand(&command, &length));
+
+    switch (command) {
+      case IComposerClient::Command::SET_ERROR: {
+        ASSERT_EQ(2, length);
+        auto loc = read();
+        auto err = readSigned();
+        GTEST_FAIL() << "unexpected error " << err << " at location " << loc;
+      } break;
+      case IComposerClient::Command::SELECT_DISPLAY:
+      case IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES:
+      case IComposerClient::Command::SET_DISPLAY_REQUESTS:
+      case IComposerClient::Command::SET_PRESENT_FENCE:
+      case IComposerClient::Command::SET_RELEASE_FENCES:
+        break;
+      default:
+        GTEST_FAIL() << "unexpected return command " << std::hex
+                     << static_cast<int>(command);
+        break;
+    }
+
+    endCommand();
+  }
+}
+
+}  // namespace tests
+}  // namespace V2_1
+}  // namespace composer
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
diff --git a/graphics/composer/2.1/vts/functional/TestCommandReader.h b/graphics/composer/2.1/vts/functional/TestCommandReader.h
new file mode 100644 (file)
index 0000000..657a463
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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 TEST_COMMAND_READER_H
+#define TEST_COMMAND_READER_H
+
+#include <IComposerCommandBuffer.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace tests {
+
+// A command parser that checks that no error nor unexpected commands are
+// returned.
+class TestCommandReader : public CommandReaderBase {
+ public:
+  // Parse all commands in the return command queue.  Call GTEST_FAIL() for
+  // unexpected errors or commands.
+  void parse();
+};
+
+}  // namespace tests
+}  // namespace V2_1
+}  // namespace composer
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // TEST_COMMAND_READER_H
index 33cf84c37e01dbdf08fd8baf6d8d28a666fe26e4..c66cdd0c9ebd708ebdd3d61eddcbd877d144d1a2 100644 (file)
@@ -25,10 +25,17 @@ namespace composer {
 namespace V2_1 {
 namespace tests {
 
-Composer::Composer() { init(); }
+Composer::Composer() {
+  mComposer = ::testing::VtsHalHidlTargetTestBase::getService<IComposer>();
+  init();
+}
+
+Composer::Composer(const std::string& name) {
+  mComposer = ::testing::VtsHalHidlTargetTestBase::getService<IComposer>(name);
+  init();
+}
 
 void Composer::init() {
-  mComposer = ::testing::VtsHalHidlTargetTestBase::getService<IComposer>();
   ASSERT_NE(nullptr, mComposer.get()) << "failed to get composer service";
 
   std::vector<IComposer::Capability> capabilities = getCapabilities();
@@ -290,6 +297,44 @@ void ComposerClient::setVsyncEnabled(Display display, bool enabled) {
                                            : IComposerClient::Vsync::DISABLE;
   Error error = mClient->setVsyncEnabled(display, vsync);
   ASSERT_EQ(Error::NONE, error) << "failed to set vsync mode";
+
+  // give the hwbinder thread some time to handle any pending vsync callback
+  if (!enabled) {
+      usleep(5 * 1000);
+  }
+}
+
+void ComposerClient::execute(TestCommandReader* reader,
+                             CommandWriterBase* writer) {
+  bool queueChanged = false;
+  uint32_t commandLength = 0;
+  hidl_vec<hidl_handle> commandHandles;
+  ASSERT_TRUE(
+      writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
+
+  if (queueChanged) {
+    auto ret = mClient->setInputCommandQueue(*writer->getMQDescriptor());
+    ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
+    return;
+  }
+
+  mClient->executeCommands(
+      commandLength, commandHandles,
+      [&](const auto& tmpError, const auto& tmpOutQueueChanged,
+          const auto& tmpOutLength, const auto& tmpOutHandles) {
+        ASSERT_EQ(Error::NONE, tmpError);
+
+        if (tmpOutQueueChanged) {
+          mClient->getOutputCommandQueue(
+              [&](const auto& tmpError, const auto& tmpDescriptor) {
+                ASSERT_EQ(Error::NONE, tmpError);
+                reader->setMQDescriptor(tmpDescriptor);
+              });
+        }
+
+        ASSERT_TRUE(reader->readQueue(tmpOutLength, tmpOutHandles));
+        reader->parse();
+      });
 }
 
 }  // namespace tests
index 4b5726441d4d5dc6053d72ca4d6241051f73b949..4e69f61b87c3407f7c982803900dd5c21e4777af 100644 (file)
 #include <unordered_set>
 #include <vector>
 
+#include <IComposerCommandBuffer.h>
 #include <android/hardware/graphics/composer/2.1/IComposer.h>
 #include <utils/StrongPointer.h>
 
+#include "TestCommandReader.h"
+
 namespace android {
 namespace hardware {
 namespace graphics {
@@ -44,6 +47,7 @@ class ComposerClient;
 class Composer {
  public:
   Composer();
+  explicit Composer(const std::string& name);
 
   sp<IComposer> getRaw() const;
 
@@ -102,6 +106,8 @@ class ComposerClient {
   void setPowerMode(Display display, IComposerClient::PowerMode mode);
   void setVsyncEnabled(Display display, bool enabled);
 
+  void execute(TestCommandReader* reader, CommandWriterBase* writer);
+
  private:
   sp<IComposerClient> mClient;
 
index 387222fbbe02fcb4cb66686ab69d7e7974be30a7..0f03546558fe9b62e58a3a2d4446b1dd6a3c0631 100644 (file)
@@ -16,8 +16,9 @@
 
 #define LOG_TAG "graphics_composer_hidl_hal_test"
 
-#include <IComposerCommandBuffer.h>
 #include <android-base/logging.h>
+#include "GraphicsComposerCallback.h"
+#include "TestCommandReader.h"
 #include "VtsHalGraphicsComposerTestUtils.h"
 #include "VtsHalGraphicsMapperTestUtils.h"
 
@@ -49,83 +50,6 @@ using android::hardware::graphics::mapper::V2_0::IMapper;
 using android::hardware::graphics::mapper::V2_0::tests::Gralloc;
 using GrallocError = android::hardware::graphics::mapper::V2_0::Error;
 
-// IComposerCallback to be installed with IComposerClient::registerCallback.
-class GraphicsComposerCallback : public IComposerCallback {
- public:
-  void setVsyncAllowed(bool allowed) {
-    std::lock_guard<std::mutex> lock(mMutex);
-    mVsyncAllowed = allowed;
-  }
-
-  std::vector<Display> getDisplays() const {
-    std::lock_guard<std::mutex> lock(mMutex);
-    return std::vector<Display>(mDisplays.begin(), mDisplays.end());
-  }
-
-  int getInvalidHotplugCount() const {
-    std::lock_guard<std::mutex> lock(mMutex);
-    return mInvalidHotplugCount;
-  }
-
-  int getInvalidRefreshCount() const {
-    std::lock_guard<std::mutex> lock(mMutex);
-    return mInvalidRefreshCount;
-  }
-
-  int getInvalidVsyncCount() const {
-    std::lock_guard<std::mutex> lock(mMutex);
-    return mInvalidVsyncCount;
-  }
-
- private:
-  Return<void> onHotplug(Display display, Connection connection) override {
-    std::lock_guard<std::mutex> lock(mMutex);
-
-    if (connection == Connection::CONNECTED) {
-      if (!mDisplays.insert(display).second) {
-        mInvalidHotplugCount++;
-      }
-    } else if (connection == Connection::DISCONNECTED) {
-      if (!mDisplays.erase(display)) {
-        mInvalidHotplugCount++;
-      }
-    }
-
-    return Void();
-  }
-
-  Return<void> onRefresh(Display display) override {
-    std::lock_guard<std::mutex> lock(mMutex);
-
-    if (mDisplays.count(display) == 0) {
-      mInvalidRefreshCount++;
-    }
-
-    return Void();
-  }
-
-  Return<void> onVsync(Display display, int64_t) override {
-    std::lock_guard<std::mutex> lock(mMutex);
-
-    if (!mVsyncAllowed || mDisplays.count(display) == 0) {
-      mInvalidVsyncCount++;
-    }
-
-    return Void();
-  }
-
-  mutable std::mutex mMutex;
-  // the set of all currently connected displays
-  std::unordered_set<Display> mDisplays;
-  // true only when vsync is enabled
-  bool mVsyncAllowed = false;
-
-  // track invalid callbacks
-  int mInvalidHotplugCount = 0;
-  int mInvalidRefreshCount = 0;
-  int mInvalidVsyncCount = 0;
-};
-
 class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
  protected:
   void SetUp() override {
@@ -137,6 +61,10 @@ class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
 
     // assume the first display is primary and is never removed
     mPrimaryDisplay = waitForFirstDisplay();
+
+    // explicitly disable vsync
+    mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
+    mComposerCallback->setVsyncAllowed(false);
   }
 
   void TearDown() override {
@@ -404,7 +332,7 @@ class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
     ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
 
     mWriter = std::make_unique<CommandWriterBase>(1024);
-    mReader = std::make_unique<CommandReader>();
+    mReader = std::make_unique<TestCommandReader>();
   }
 
   void TearDown() override {
@@ -423,78 +351,10 @@ class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
       return mGralloc->allocate(info);
   }
 
-  void execute() {
-    bool queueChanged = false;
-    uint32_t commandLength = 0;
-    hidl_vec<hidl_handle> commandHandles;
-    ASSERT_TRUE(
-        mWriter->writeQueue(&queueChanged, &commandLength, &commandHandles));
-
-    if (queueChanged) {
-      auto ret = mComposerClient->getRaw()->setInputCommandQueue(
-          *mWriter->getMQDescriptor());
-      ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
-      return;
-    }
-
-    mComposerClient->getRaw()->executeCommands(
-        commandLength, commandHandles,
-        [&](const auto& tmpError, const auto& tmpOutQueueChanged,
-            const auto& tmpOutLength, const auto& tmpOutHandles) {
-          ASSERT_EQ(Error::NONE, tmpError);
-
-          if (tmpOutQueueChanged) {
-            mComposerClient->getRaw()->getOutputCommandQueue(
-                [&](const auto& tmpError, const auto& tmpDescriptor) {
-                  ASSERT_EQ(Error::NONE, tmpError);
-                  mReader->setMQDescriptor(tmpDescriptor);
-                });
-          }
-
-          ASSERT_TRUE(mReader->readQueue(tmpOutLength, tmpOutHandles));
-          mReader->parse();
-        });
-  }
-
-  // A command parser that checks that no error nor unexpected commands are
-  // returned.
-  class CommandReader : public CommandReaderBase {
-   public:
-    // Parse all commands in the return command queue.  Call GTEST_FAIL() for
-    // unexpected errors or commands.
-    void parse() {
-      while (!isEmpty()) {
-        IComposerClient::Command command;
-        uint16_t length;
-        ASSERT_TRUE(beginCommand(&command, &length));
-
-        switch (command) {
-          case IComposerClient::Command::SET_ERROR: {
-            ASSERT_EQ(2, length);
-            auto loc = read();
-            auto err = readSigned();
-            GTEST_FAIL() << "unexpected error " << err << " at location "
-                         << loc;
-          } break;
-          case IComposerClient::Command::SELECT_DISPLAY:
-          case IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES:
-          case IComposerClient::Command::SET_DISPLAY_REQUESTS:
-          case IComposerClient::Command::SET_PRESENT_FENCE:
-          case IComposerClient::Command::SET_RELEASE_FENCES:
-            break;
-          default:
-            GTEST_FAIL() << "unexpected return command " << std::hex
-                         << static_cast<int>(command);
-            break;
-        }
-
-        endCommand();
-      }
-    }
-  };
+  void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
 
   std::unique_ptr<CommandWriterBase> mWriter;
-  std::unique_ptr<CommandReader> mReader;
+  std::unique_ptr<TestCommandReader> mReader;
 
  private:
   std::unique_ptr<Gralloc> mGralloc;
index aa1aeaa4042178ba686ec1b3c78930bc37ccfffd..e876fe4494f510dd600804c4a54d6c5a34799e43 100644 (file)
@@ -18,7 +18,7 @@
 #define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC_MAPPER_H
 
 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
-#include <system/window.h>
+#include <cutils/native_handle.h>
 
 #include <mutex>
 #include <unordered_set>
index 3dad3c10b84d51c31a09236152e24ddc49051cc6..a01740462caba5e95bbc549ca82dd2ef63dbdb3b 100644 (file)
@@ -59,7 +59,7 @@ TEST_F(ConsumerIrHidlTest, TransmitTest) {
     uint32_t len = 16;
     hidl_vec<int32_t> vec;
     vec.resize(len);
-    std::fill(vec.begin(), vec.end(), 1);
+    std::fill(vec.begin(), vec.end(), 1000);
     for (auto range = ranges.begin(); range != ranges.end(); range++) {
       EXPECT_TRUE(ir->transmit(range->min, vec));
       EXPECT_TRUE(ir->transmit(range->max, vec));
@@ -74,7 +74,6 @@ TEST_F(ConsumerIrHidlTest, BadFreqTest) {
   vec.resize(len);
   std::fill(vec.begin(), vec.end(), 1);
   EXPECT_FALSE(ir->transmit(-1, vec));
-  EXPECT_FALSE(ir->transmit(0, vec));
 }
 
 int main(int argc, char **argv) {
index 9df5bf830775130e455d67e0e40d80c3fccc42af..87ad2450c1c072a39ebaf74b4b959964d8eb811d 100644 (file)
@@ -11,7 +11,8 @@ LOCAL_SHARED_LIBRARIES := \
     liblog \
     libsoftkeymasterdevice \
     libcrypto \
-    libkeymaster1 \
+    libkeymaster_portable \
+    libkeymaster_staging \
     libhidlbase \
     libhidltransport \
     libutils \
index fcdd32981e54a460ad2bb5bdbe0789c7b4ab6fc9..d83963fcc4511442ff32b04fa5f6e382099fc759 100644 (file)
@@ -64,7 +64,7 @@ static int keymaster0_device_initialize(const hw_module_t* mod, keymaster2_devic
     assert(mod->module_api_version < KEYMASTER_MODULE_API_VERSION_1_0);
     ALOGI("Found keymaster0 module %s, version %x", mod->name, mod->module_api_version);
 
-    UniquePtr<SoftKeymasterDevice> soft_keymaster(new SoftKeymasterDevice);
+    std::unique_ptr<SoftKeymasterDevice> soft_keymaster(new SoftKeymasterDevice);
     keymaster0_device_t* km0_device = NULL;
     keymaster_error_t error = KM_ERROR_OK;
 
@@ -107,7 +107,7 @@ static int keymaster1_device_initialize(const hw_module_t* mod, keymaster2_devic
     assert(mod->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0);
     ALOGI("Found keymaster1 module %s, version %x", mod->name, mod->module_api_version);
 
-    UniquePtr<SoftKeymasterDevice> soft_keymaster(new SoftKeymasterDevice);
+    std::unique_ptr<SoftKeymasterDevice> soft_keymaster(new SoftKeymasterDevice);
     keymaster1_device_t* km1_device = nullptr;
     keymaster_error_t error = KM_ERROR_OK;
 
index b9507651188071166acc7b60048dd0665013bab5..78353eaf256f1b0180893b10b7ac63ebd6843c15 100644 (file)
@@ -47,6 +47,7 @@ using ::std::string;
 string service_name = "default";
 
 static bool arm_deleteAllKeys = false;
+static bool dump_Attestations = false;
 
 namespace android {
 namespace hardware {
@@ -233,6 +234,19 @@ string hex2str(string a) {
     return b;
 }
 
+char nibble2hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
+                       '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+string bin2hex(const hidl_vec<uint8_t>& data) {
+    string retval;
+    retval.reserve(data.size() * 2 + 1);
+    for (uint8_t byte : data) {
+        retval.push_back(nibble2hex[0x0F & (byte >> 4)]);
+        retval.push_back(nibble2hex[0x0F & byte]);
+    }
+    return retval;
+}
+
 string rsa_key = hex2str(
     "30820275020100300d06092a864886f70d01010105000482025f3082025b"
     "02010002818100c6095409047d8634812d5a218176e45c41d60a75b13901"
@@ -286,11 +300,13 @@ X509* parse_cert_blob(const hidl_vec<uint8_t>& blob) {
 
 bool verify_chain(const hidl_vec<hidl_vec<uint8_t>>& chain) {
     for (size_t i = 0; i < chain.size() - 1; ++i) {
-        auto& key_cert_blob = chain[i];
-        auto& signing_cert_blob = chain[i + 1];
-
-        X509_Ptr key_cert(parse_cert_blob(key_cert_blob));
-        X509_Ptr signing_cert(parse_cert_blob(signing_cert_blob));
+        X509_Ptr key_cert(parse_cert_blob(chain[i]));
+        X509_Ptr signing_cert;
+        if (i < chain.size() - 1) {
+            signing_cert.reset(parse_cert_blob(chain[i + 1]));
+        } else {
+            signing_cert.reset(parse_cert_blob(chain[i]));
+        }
         EXPECT_TRUE(!!key_cert.get() && !!signing_cert.get());
         if (!key_cert.get() || !signing_cert.get()) return false;
 
@@ -300,6 +316,24 @@ bool verify_chain(const hidl_vec<hidl_vec<uint8_t>>& chain) {
 
         EXPECT_EQ(1, X509_verify(key_cert.get(), signing_pubkey.get()))
             << "Verification of certificate " << i << " failed";
+
+        char* cert_issuer =  //
+            X509_NAME_oneline(X509_get_issuer_name(key_cert.get()), nullptr, 0);
+        char* signer_subj =
+            X509_NAME_oneline(X509_get_subject_name(signing_cert.get()), nullptr, 0);
+        EXPECT_STREQ(cert_issuer, signer_subj) << "Cert " << i
+                                               << " has wrong issuer.  (Possibly b/38394614)";
+        if (i == 0) {
+            char* cert_sub = X509_NAME_oneline(X509_get_subject_name(key_cert.get()), nullptr, 0);
+            EXPECT_STREQ("/CN=Android Keystore Key", cert_sub)
+                << "Cert " << i << " has wrong subject.  (Possibly b/38394614)";
+            free(cert_sub);
+        }
+
+        free(cert_issuer);
+        free(signer_subj);
+
+        if (dump_Attestations) std::cout << bin2hex(chain[i]) << std::endl;
     }
 
     return true;
@@ -504,9 +538,10 @@ class KeymasterHidlTest : public ::testing::VtsHalHidlTargetTestBase {
     }
 
     ErrorCode DeleteKey(HidlBuf* key_blob, bool keep_key_blob = false) {
-        ErrorCode error = keymaster_->deleteKey(*key_blob);
+        auto rc = keymaster_->deleteKey(*key_blob);
         if (!keep_key_blob) *key_blob = HidlBuf();
-        return error;
+        if (!rc.isOk()) return ErrorCode::UNKNOWN_ERROR;
+        return rc;
     }
 
     ErrorCode DeleteKey(bool keep_key_blob = false) {
@@ -527,12 +562,15 @@ class KeymasterHidlTest : public ::testing::VtsHalHidlTargetTestBase {
 
     ErrorCode GetCharacteristics(const HidlBuf& key_blob, const HidlBuf& client_id,
                                  const HidlBuf& app_data, KeyCharacteristics* key_characteristics) {
-        ErrorCode error;
-        keymaster_->getKeyCharacteristics(
-            key_blob, client_id, app_data,
-            [&](ErrorCode hidl_error, const KeyCharacteristics& hidl_key_characteristics) {
-                error = hidl_error, *key_characteristics = hidl_key_characteristics;
-            });
+        ErrorCode error = ErrorCode::UNKNOWN_ERROR;
+        EXPECT_TRUE(
+            keymaster_
+                ->getKeyCharacteristics(
+                    key_blob, client_id, app_data,
+                    [&](ErrorCode hidl_error, const KeyCharacteristics& hidl_key_characteristics) {
+                        error = hidl_error, *key_characteristics = hidl_key_characteristics;
+                    })
+                .isOk());
         return error;
     }
 
@@ -670,12 +708,16 @@ class KeymasterHidlTest : public ::testing::VtsHalHidlTargetTestBase {
                         hidl_vec<hidl_vec<uint8_t>>* cert_chain) {
         SCOPED_TRACE("AttestKey");
         ErrorCode error;
-        keymaster_->attestKey(
+        auto rc = keymaster_->attestKey(
             key_blob, attest_params.hidl_data(),
             [&](ErrorCode hidl_error, const hidl_vec<hidl_vec<uint8_t>>& hidl_cert_chain) {
                 error = hidl_error;
                 *cert_chain = hidl_cert_chain;
             });
+
+        EXPECT_TRUE(rc.isOk()) << rc.description();
+        if (!rc.isOk()) return ErrorCode::UNKNOWN_ERROR;
+
         return error;
     }
 
@@ -975,11 +1017,13 @@ bool verify_attestation_record(const string& challenge, const string& app_id,
 
     att_sw_enforced.Sort();
     expected_sw_enforced.Sort();
-    EXPECT_EQ(filter_tags(expected_sw_enforced), filter_tags(att_sw_enforced));
+    EXPECT_EQ(filter_tags(expected_sw_enforced), filter_tags(att_sw_enforced))
+        << "(Possibly b/38394619)";
 
     att_tee_enforced.Sort();
     expected_tee_enforced.Sort();
-    EXPECT_EQ(filter_tags(expected_tee_enforced), filter_tags(att_tee_enforced));
+    EXPECT_EQ(filter_tags(expected_tee_enforced), filter_tags(att_tee_enforced))
+        << "(Possibly b/38394619)";
 
     return true;
 }
@@ -2429,12 +2473,11 @@ TEST_F(ImportKeyTest, EcdsaCurveMismatch) {
         return;
     }
 
-    ASSERT_EQ(
-        ErrorCode::IMPORT_PARAMETER_MISMATCH,
-        ImportKey(AuthorizationSetBuilder()
-                      .EcdsaSigningKey(EcCurve::P_224 /* Doesn't match key */)
-                      .Digest(Digest::NONE),
-                  KeyFormat::PKCS8, ec_256_key))
+    ASSERT_EQ(ErrorCode::IMPORT_PARAMETER_MISMATCH,
+              ImportKey(AuthorizationSetBuilder()
+                            .EcdsaSigningKey(EcCurve::P_224 /* Doesn't match key */)
+                            .Digest(Digest::NONE),
+                        KeyFormat::PKCS8, ec_256_key))
         << "(Possibly b/36233241)";
 }
 
@@ -3883,13 +3926,11 @@ TEST_F(AttestationTest, RsaAttestation) {
                                              .Authorization(TAG_INCLUDE_UNIQUE_ID)));
 
     hidl_vec<hidl_vec<uint8_t>> cert_chain;
-    EXPECT_EQ(
-        ErrorCode::OK,
-        AttestKey(
-            AuthorizationSetBuilder()
-                .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
-                .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")),
-            &cert_chain));
+    ASSERT_EQ(ErrorCode::OK,
+              AttestKey(AuthorizationSetBuilder()
+                            .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
+                            .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")),
+                        &cert_chain));
     EXPECT_GE(cert_chain.size(), 2U);
     EXPECT_TRUE(verify_chain(cert_chain));
     EXPECT_TRUE(
@@ -3933,13 +3974,11 @@ TEST_F(AttestationTest, EcAttestation) {
                                              .Authorization(TAG_INCLUDE_UNIQUE_ID)));
 
     hidl_vec<hidl_vec<uint8_t>> cert_chain;
-    EXPECT_EQ(
-        ErrorCode::OK,
-        AttestKey(
-            AuthorizationSetBuilder()
-                .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
-                .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")),
-            &cert_chain));
+    ASSERT_EQ(ErrorCode::OK,
+              AttestKey(AuthorizationSetBuilder()
+                            .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
+                            .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")),
+                        &cert_chain));
     EXPECT_GE(cert_chain.size(), 2U);
     EXPECT_TRUE(verify_chain(cert_chain));
 
@@ -4156,6 +4195,9 @@ int main(int argc, char** argv) {
             if (std::string(argv[i]) == "--arm_deleteAllKeys") {
                 arm_deleteAllKeys = true;
             }
+            if (std::string(argv[i]) == "--dump_attestations") {
+                dump_Attestations = true;
+            }
         } else {
             positional_args.push_back(argv[i]);
         }
index fe67cb9b2eb0838ef210d698744449f068c04489..336cab483252170a69e7a6f38d56252cf46c2882 100644 (file)
@@ -129,12 +129,22 @@ static ComponentTestEnvironment* gEnv = nullptr;
 
 // audio decoder test fixture class
 class AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   private:
+    typedef ::testing::VtsHalHidlTargetTestBase Super;
    public:
+    ::std::string getTestCaseInfo() const override {
+        return ::std::string() +
+                "Component: " + gEnv->getComponent().c_str() + " | " +
+                "Role: " + gEnv->getRole().c_str() + " | " +
+                "Instance: " + gEnv->getInstance().c_str() + " | " +
+                "Res: " + gEnv->getRes().c_str();
+    }
+
     virtual void SetUp() override {
+        Super::SetUp();
         disableTest = false;
         android::hardware::media::omx::V1_0::Status status;
-        omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
-            gEnv->getInstance());
+        omx = Super::getService<IOmx>(gEnv->getInstance());
         ASSERT_NE(omx, nullptr);
         observer =
             new CodecObserver([this](Message msg, const BufferInfo* buffer) {
@@ -217,6 +227,7 @@ class AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
             EXPECT_TRUE((omxNode->freeNode()).isOk());
             omxNode = nullptr;
         }
+        Super::TearDown();
     }
 
     // callback function to process messages received by onMessages() from IL
@@ -474,15 +485,20 @@ void GetURLForComponent(AudioDecHidlTest::standardComp comp, char* mURL,
 
 // port settings reconfiguration during runtime. reconfigures sample rate and
 // number
+typedef struct {
+    OMX_AUDIO_CODINGTYPE eEncoding;
+    AudioDecHidlTest::standardComp comp;
+} packedArgs;
 void portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
                          android::Vector<BufferInfo>* iBuffer,
                          android::Vector<BufferInfo>* oBuffer,
-                         OMX_AUDIO_CODINGTYPE eEncoding,
                          OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
-                         Message msg,
-                         AudioDecHidlTest::standardComp comp =
-                             AudioDecHidlTest::standardComp::unknown_comp) {
+                         Message msg, PortMode oPortMode, void* args) {
     android::hardware::media::omx::V1_0::Status status;
+    packedArgs* audioArgs = static_cast<packedArgs*>(args);
+    OMX_AUDIO_CODINGTYPE eEncoding = audioArgs->eEncoding;
+    AudioDecHidlTest::standardComp comp = audioArgs->comp;
+    (void)oPortMode;
 
     if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
         ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
@@ -568,7 +584,8 @@ void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
                             android::Vector<BufferInfo>* iBuffer,
                             android::Vector<BufferInfo>* oBuffer,
                             OMX_AUDIO_CODINGTYPE eEncoding,
-                            OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput) {
+                            OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
+                            AudioDecHidlTest::standardComp comp) {
     android::hardware::media::omx::V1_0::Status status;
     Message msg;
     int timeOut = TIMEOUT_COUNTER;
@@ -579,8 +596,10 @@ void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
         if (status == android::hardware::media::omx::V1_0::Status::OK) {
             EXPECT_EQ(msg.type, Message::Type::EVENT);
-            portReconfiguration(omxNode, observer, iBuffer, oBuffer, eEncoding,
-                                kPortIndexInput, kPortIndexOutput, msg);
+            packedArgs audioArgs = {eEncoding, comp};
+            portReconfiguration(omxNode, observer, iBuffer, oBuffer,
+                                kPortIndexInput, kPortIndexOutput, msg,
+                                PortMode::PRESET_BYTE_BUFFER, &audioArgs);
         }
         // status == TIMED_OUT, it could be due to process time being large
         // than DEFAULT_TIMEOUT or component needs output buffers to start
@@ -644,8 +663,10 @@ void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
         // Port Reconfiguration
         if (status == android::hardware::media::omx::V1_0::Status::OK &&
             msg.type == Message::Type::EVENT) {
-            portReconfiguration(omxNode, observer, iBuffer, oBuffer, eEncoding,
-                                kPortIndexInput, kPortIndexOutput, msg, comp);
+            packedArgs audioArgs = {eEncoding, comp};
+            portReconfiguration(omxNode, observer, iBuffer, oBuffer,
+                                kPortIndexInput, kPortIndexOutput, msg,
+                                PortMode::PRESET_BYTE_BUFFER, &audioArgs);
         }
 
         if (frameID == (int)Info->size() || frameID == (offset + range)) break;
@@ -789,8 +810,10 @@ TEST_F(AudioDecHidlTest, DecodeTest) {
                   (int)Info.size(), compName);
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
-                           kPortIndexInput, kPortIndexOutput);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag);
+                           kPortIndexInput, kPortIndexOutput, compName);
+    packedArgs audioArgs = {eEncoding, compName};
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, nullptr,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
     EXPECT_EQ(timestampUslist.empty(), true);
     // set state to idle
     changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
@@ -846,7 +869,9 @@ TEST_F(AudioDecHidlTest, DISABLED_EOSTest_M) {
     changeStateIdletoExecute(omxNode, observer);
 
     // request EOS at the start
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag);
+    packedArgs audioArgs = {eEncoding, compName};
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, nullptr,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     EXPECT_GE(framesReceived, 0U);
@@ -933,8 +958,10 @@ TEST_F(AudioDecHidlTest, ThumbnailTest) {
                   compName);
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
-                           kPortIndexInput, kPortIndexOutput);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag);
+                           kPortIndexInput, kPortIndexOutput, compName);
+    packedArgs audioArgs = {eEncoding, compName};
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, nullptr,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     EXPECT_GE(framesReceived, 1U);
@@ -949,8 +976,9 @@ TEST_F(AudioDecHidlTest, ThumbnailTest) {
                   compName, false);
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
-                           kPortIndexInput, kPortIndexOutput);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag);
+                           kPortIndexInput, kPortIndexOutput, compName);
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, nullptr,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     EXPECT_GE(framesReceived, 1U);
@@ -1034,8 +1062,10 @@ TEST_F(AudioDecHidlTest, SimpleEOSTest) {
                   (int)Info.size(), compName, false);
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
-                           kPortIndexInput, kPortIndexOutput);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag);
+                           kPortIndexInput, kPortIndexOutput, compName);
+    packedArgs audioArgs = {eEncoding, compName};
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, nullptr,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     framesReceived = 0;
index 7a5dceca886499f5209d004d99ad23eaba5bebcc..ae79e82621929378cdee52ab8bec8cd423cc0fe6 100644 (file)
@@ -129,12 +129,22 @@ static ComponentTestEnvironment* gEnv = nullptr;
 
 // audio encoder test fixture class
 class AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   private:
+    typedef ::testing::VtsHalHidlTargetTestBase Super;
    public:
+    ::std::string getTestCaseInfo() const override {
+        return ::std::string() +
+                "Component: " + gEnv->getComponent().c_str() + " | " +
+                "Role: " + gEnv->getRole().c_str() + " | " +
+                "Instance: " + gEnv->getInstance().c_str() + " | " +
+                "Res: " + gEnv->getRes().c_str();
+    }
+
     virtual void SetUp() override {
+        Super::SetUp();
         disableTest = false;
         android::hardware::media::omx::V1_0::Status status;
-        omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
-            gEnv->getInstance());
+        omx = Super::getService<IOmx>(gEnv->getInstance());
         ASSERT_NE(omx, nullptr);
         observer =
             new CodecObserver([this](Message msg, const BufferInfo* buffer) {
@@ -204,6 +214,7 @@ class AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
             EXPECT_TRUE((omxNode->freeNode()).isOk());
             omxNode = nullptr;
         }
+        Super::TearDown();
     }
 
     // callback function to process messages received by onMessages() from IL
index 7240964ecb960869731e0c2be95e8836f585b0e2..4c68219b4774b8dad5378453e940d9fe2e1764cf 100644 (file)
@@ -46,47 +46,6 @@ using ::android::sp;
 #include <media_hidl_test_common.h>
 #include <memory>
 
-Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
-    sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE eEncoding) {
-    OMX_U32 index = 0;
-    OMX_AUDIO_PARAM_PORTFORMATTYPE portFormat;
-    std::vector<OMX_AUDIO_CODINGTYPE> arrEncoding;
-    android::hardware::media::omx::V1_0::Status status;
-
-    while (1) {
-        portFormat.nIndex = index;
-        status = getPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
-                              &portFormat);
-        if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
-        arrEncoding.push_back(portFormat.eEncoding);
-        index++;
-        if (index == 512) {
-            // enumerated way too many formats, highly unusual for this to
-            // happen.
-            EXPECT_LE(index, 512U)
-                << "Expecting OMX_ErrorNoMore but not received";
-            break;
-        }
-    }
-    if (!index) return status;
-    for (index = 0; index < arrEncoding.size(); index++) {
-        if (arrEncoding[index] == eEncoding) {
-            portFormat.eEncoding = arrEncoding[index];
-            break;
-        }
-    }
-    if (index == arrEncoding.size()) {
-        ALOGE("setting default Port format %x", (int)arrEncoding[0]);
-        portFormat.eEncoding = arrEncoding[0];
-    }
-    // In setParam call nIndex shall be ignored as per omx-il specification.
-    // see how this holds up by corrupting nIndex
-    portFormat.nIndex = RANDOM_INDEX;
-    status = setPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
-                          &portFormat);
-    return status;
-}
-
 void enumerateProfile(sp<IOmxNode> omxNode, OMX_U32 portIndex,
                       std::vector<int32_t>* arrProfile) {
     android::hardware::media::omx::V1_0::Status status;
index 70142f2b05d82fdfce60115cdbdf876ae0f66e66..08b3d9cd58d9e6b642db5259a5368e9a905c8ed1 100644 (file)
@@ -27,9 +27,6 @@
 /*
  * Common audio utils
  */
-Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
-    sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE eEncoding);
-
 void enumerateProfile(sp<IOmxNode> omxNode, OMX_U32 portIndex,
                       std::vector<int32_t>* arrProfile);
 
index e81e6dd4d0dedacd64b2e0e236527fb2f0ded599..1f67e2b6a591ba6bf6b07cb02f3b796765f6be88 100755 (executable)
@@ -60,6 +60,132 @@ Return<android::hardware::media::omx::V1_0::Status> setRole(
     return setParam(omxNode, OMX_IndexParamStandardComponentRole, &params);
 }
 
+Return<android::hardware::media::omx::V1_0::Status> setPortBufferSize(
+    sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_U32 size) {
+    android::hardware::media::omx::V1_0::Status status;
+    OMX_PARAM_PORTDEFINITIONTYPE portDef;
+
+    status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
+                          &portDef);
+    if (status != ::android::hardware::media::omx::V1_0::Status::OK)
+        return status;
+    if (portDef.nBufferSize < size) {
+        portDef.nBufferSize = size;
+        status = setPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
+                              &portDef);
+        if (status != ::android::hardware::media::omx::V1_0::Status::OK)
+            return status;
+    }
+    return status;
+}
+
+// get/set video component port format
+Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
+    sp<IOmxNode> omxNode, OMX_U32 portIndex,
+    OMX_VIDEO_CODINGTYPE eCompressionFormat, OMX_COLOR_FORMATTYPE eColorFormat,
+    OMX_U32 xFramerate) {
+    OMX_U32 index = 0;
+    OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
+    std::vector<OMX_COLOR_FORMATTYPE> arrColorFormat;
+    std::vector<OMX_VIDEO_CODINGTYPE> arrCompressionFormat;
+    android::hardware::media::omx::V1_0::Status status;
+
+    while (1) {
+        portFormat.nIndex = index;
+        status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
+                              &portFormat);
+        if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
+        if (eCompressionFormat == OMX_VIDEO_CodingUnused)
+            arrColorFormat.push_back(portFormat.eColorFormat);
+        else
+            arrCompressionFormat.push_back(portFormat.eCompressionFormat);
+        index++;
+        if (index == 512) {
+            // enumerated way too many formats, highly unusual for this to
+            // happen.
+            EXPECT_LE(index, 512U)
+                << "Expecting OMX_ErrorNoMore but not received";
+            break;
+        }
+    }
+    if (!index) return status;
+    if (eCompressionFormat == OMX_VIDEO_CodingUnused) {
+        for (index = 0; index < arrColorFormat.size(); index++) {
+            if (arrColorFormat[index] == eColorFormat) {
+                portFormat.eColorFormat = arrColorFormat[index];
+                break;
+            }
+        }
+        if (index == arrColorFormat.size()) {
+            ALOGE("setting default color format %x", (int)arrColorFormat[0]);
+            portFormat.eColorFormat = arrColorFormat[0];
+        }
+        portFormat.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    } else {
+        for (index = 0; index < arrCompressionFormat.size(); index++) {
+            if (arrCompressionFormat[index] == eCompressionFormat) {
+                portFormat.eCompressionFormat = arrCompressionFormat[index];
+                break;
+            }
+        }
+        if (index == arrCompressionFormat.size()) {
+            ALOGE("setting default compression format %x",
+                  (int)arrCompressionFormat[0]);
+            portFormat.eCompressionFormat = arrCompressionFormat[0];
+        }
+        portFormat.eColorFormat = OMX_COLOR_FormatUnused;
+    }
+    // In setParam call nIndex shall be ignored as per omx-il specification.
+    // see how this holds up by corrupting nIndex
+    portFormat.nIndex = RANDOM_INDEX;
+    portFormat.xFramerate = xFramerate;
+    status = setPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
+                          &portFormat);
+    return status;
+}
+
+// get/set audio component port format
+Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
+    sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE eEncoding) {
+    OMX_U32 index = 0;
+    OMX_AUDIO_PARAM_PORTFORMATTYPE portFormat;
+    std::vector<OMX_AUDIO_CODINGTYPE> arrEncoding;
+    android::hardware::media::omx::V1_0::Status status;
+
+    while (1) {
+        portFormat.nIndex = index;
+        status = getPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
+                              &portFormat);
+        if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
+        arrEncoding.push_back(portFormat.eEncoding);
+        index++;
+        if (index == 512) {
+            // enumerated way too many formats, highly unusual for this to
+            // happen.
+            EXPECT_LE(index, 512U)
+                << "Expecting OMX_ErrorNoMore but not received";
+            break;
+        }
+    }
+    if (!index) return status;
+    for (index = 0; index < arrEncoding.size(); index++) {
+        if (arrEncoding[index] == eEncoding) {
+            portFormat.eEncoding = arrEncoding[index];
+            break;
+        }
+    }
+    if (index == arrEncoding.size()) {
+        ALOGE("setting default Port format %x", (int)arrEncoding[0]);
+        portFormat.eEncoding = arrEncoding[0];
+    }
+    // In setParam call nIndex shall be ignored as per omx-il specification.
+    // see how this holds up by corrupting nIndex
+    portFormat.nIndex = RANDOM_INDEX;
+    status = setPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
+                          &portFormat);
+    return status;
+}
+
 // allocate buffers needed on a component port
 void allocatePortBuffers(sp<IOmxNode> omxNode,
                          android::Vector<BufferInfo>* buffArray,
@@ -406,7 +532,8 @@ void flushPorts(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
 void testEOS(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
              android::Vector<BufferInfo>* iBuffer,
              android::Vector<BufferInfo>* oBuffer, bool signalEOS,
-             bool& eosFlag, PortMode* portMode) {
+             bool& eosFlag, PortMode* portMode, portreconfig fptr,
+             OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput, void* args) {
     android::hardware::media::omx::V1_0::Status status;
     PortMode defaultPortMode[2], *pm;
 
@@ -443,9 +570,15 @@ void testEOS(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
         status =
             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
         if (status == android::hardware::media::omx::V1_0::Status::OK) {
-            if (msg.data.eventData.event == OMX_EventBufferFlag) {
-                // soft omx components donot send this, we will just ignore it
-                // for now
+            if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
+                if (fptr) {
+                    (*fptr)(omxNode, observer, iBuffer, oBuffer,
+                            kPortIndexInput, kPortIndexOutput, msg, pm[1],
+                            args);
+                } else {
+                    // something unexpected happened
+                    EXPECT_TRUE(false);
+                }
             } else {
                 // something unexpected happened
                 EXPECT_TRUE(false);
index d617e45e43b328acafa92d39c605943dc6982eb1..0adea14e80baf7491705edee2a463df6a8160068 100644 (file)
 #define DEFAULT_TIMEOUT 100000
 #define TIMEOUT_COUNTER (10000000 / DEFAULT_TIMEOUT)
 
+/*
+ * Random Index used for monkey testing while get/set parameters
+ */
+#define RANDOM_INDEX 1729
+
+#define ALIGN_POWER_OF_TWO(value, n) \
+    (((value) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1))
+
 enum bufferOwner {
     client,
     component,
@@ -113,6 +121,12 @@ struct CodecObserver : public IOmxObserver {
                     android::hardware::media::omx::V1_0::Message::Type::EVENT) {
                     *msg = *it;
                     msgQueue.erase(it);
+                    // OMX_EventBufferFlag event is sent when the component has
+                    // processed a buffer with its EOS flag set. This event is
+                    // not sent by soft omx components. Vendor components can
+                    // send this. From IOMX point of view, we will ignore this
+                    // event.
+                    if (msg->data.eventData.event == OMX_EventBufferFlag) break;
                     return ::android::hardware::media::omx::V1_0::Status::OK;
                 } else if (it->type == android::hardware::media::omx::V1_0::
                                            Message::Type::FILL_BUFFER_DONE) {
@@ -259,6 +273,17 @@ Return<android::hardware::media::omx::V1_0::Status> setPortConfig(
 Return<android::hardware::media::omx::V1_0::Status> setRole(
     sp<IOmxNode> omxNode, const char* role);
 
+Return<android::hardware::media::omx::V1_0::Status> setPortBufferSize(
+    sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_U32 size);
+
+Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
+    sp<IOmxNode> omxNode, OMX_U32 portIndex,
+    OMX_VIDEO_CODINGTYPE eCompressionFormat, OMX_COLOR_FORMATTYPE eColorFormat,
+    OMX_U32 xFramerate);
+
+Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
+    sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE eEncoding);
+
 void allocatePortBuffers(sp<IOmxNode> omxNode,
                          android::Vector<BufferInfo>* buffArray,
                          OMX_U32 portIndex,
@@ -299,9 +324,16 @@ void flushPorts(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
                 android::Vector<BufferInfo>* oBuffer, OMX_U32 kPortIndexInput,
                 OMX_U32 kPortIndexOutput, int64_t timeoutUs = DEFAULT_TIMEOUT);
 
+typedef void (*portreconfig)(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
+                             android::Vector<BufferInfo>* iBuffer,
+                             android::Vector<BufferInfo>* oBuffer,
+                             OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
+                             Message msg, PortMode oPortMode, void* args);
 void testEOS(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
              android::Vector<BufferInfo>* iBuffer,
              android::Vector<BufferInfo>* oBuffer, bool signalEOS,
-             bool& eosFlag, PortMode* portMode = nullptr);
+             bool& eosFlag, PortMode* portMode = nullptr,
+             portreconfig fptr = nullptr, OMX_U32 kPortIndexInput = 0,
+             OMX_U32 kPortIndexOutput = 1, void* args = nullptr);
 
 #endif  // MEDIA_HIDL_TEST_COMMON_H
index 357c11e2b0781f4cadf00c83deccc177c6efe451..2d91e8275d6998512cc73cf2febf290d9be1f29f 100644 (file)
@@ -117,12 +117,21 @@ static ComponentTestEnvironment* gEnv = nullptr;
 
 // generic component test fixture class
 class ComponentHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   private:
+    typedef ::testing::VtsHalHidlTargetTestBase Super;
    public:
+    ::std::string getTestCaseInfo() const override {
+        return ::std::string() +
+                "Component: " + gEnv->getComponent().c_str() + " | " +
+                "Role: " + gEnv->getRole().c_str() + " | " +
+                "Instance: " + gEnv->getInstance().c_str();
+    }
+
     virtual void SetUp() override {
+        Super::SetUp();
         disableTest = false;
         android::hardware::media::omx::V1_0::Status status;
-        omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
-            gEnv->getInstance());
+        omx = Super::getService<IOmx>(gEnv->getInstance());
         ASSERT_NE(omx, nullptr);
         observer = new CodecObserver(nullptr);
         ASSERT_NE(observer, nullptr);
@@ -180,6 +189,7 @@ class ComponentHidlTest : public ::testing::VtsHalHidlTargetTestBase {
             EXPECT_TRUE((omxNode->freeNode()).isOk());
             omxNode = nullptr;
         }
+        Super::TearDown();
     }
 
     enum standardCompClass {
@@ -225,113 +235,6 @@ void initPortMode(PortMode* pm, bool isSecure,
     return;
 }
 
-// get/set video component port format
-Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
-    sp<IOmxNode> omxNode, OMX_U32 portIndex,
-    OMX_VIDEO_CODINGTYPE eCompressionFormat, OMX_COLOR_FORMATTYPE eColorFormat,
-    OMX_U32 xFramerate) {
-    OMX_U32 index = 0;
-    OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
-    std::vector<OMX_COLOR_FORMATTYPE> arrColorFormat;
-    std::vector<OMX_VIDEO_CODINGTYPE> arrCompressionFormat;
-    android::hardware::media::omx::V1_0::Status status;
-
-    while (1) {
-        portFormat.nIndex = index;
-        status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
-                              &portFormat);
-        if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
-        if (eCompressionFormat == OMX_VIDEO_CodingUnused)
-            arrColorFormat.push_back(portFormat.eColorFormat);
-        else
-            arrCompressionFormat.push_back(portFormat.eCompressionFormat);
-        index++;
-        if (index == 512) {
-            // enumerated way too many formats, highly unusual for this to
-            // happen.
-            EXPECT_LE(index, 512U)
-                << "Expecting OMX_ErrorNoMore but not received";
-            break;
-        }
-    }
-    if (!index) return status;
-    if (eCompressionFormat == OMX_VIDEO_CodingUnused) {
-        for (index = 0; index < arrColorFormat.size(); index++) {
-            if (arrColorFormat[index] == eColorFormat) {
-                portFormat.eColorFormat = arrColorFormat[index];
-                break;
-            }
-        }
-        if (index == arrColorFormat.size()) {
-            ALOGE("setting default color format %x", (int)arrColorFormat[0]);
-            portFormat.eColorFormat = arrColorFormat[0];
-        }
-        portFormat.eCompressionFormat = OMX_VIDEO_CodingUnused;
-    } else {
-        for (index = 0; index < arrCompressionFormat.size(); index++) {
-            if (arrCompressionFormat[index] == eCompressionFormat) {
-                portFormat.eCompressionFormat = arrCompressionFormat[index];
-                break;
-            }
-        }
-        if (index == arrCompressionFormat.size()) {
-            ALOGE("setting default compression format %x",
-                  (int)arrCompressionFormat[0]);
-            portFormat.eCompressionFormat = arrCompressionFormat[0];
-        }
-        portFormat.eColorFormat = OMX_COLOR_FormatUnused;
-    }
-    // In setParam call nIndex shall be ignored as per omx-il specification.
-    // see how this holds up by corrupting nIndex
-    portFormat.nIndex = RANDOM_INDEX;
-    portFormat.xFramerate = xFramerate;
-    status = setPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
-                          &portFormat);
-    return status;
-}
-
-// get/set audio component port format
-Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
-    sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE eEncoding) {
-    OMX_U32 index = 0;
-    OMX_AUDIO_PARAM_PORTFORMATTYPE portFormat;
-    std::vector<OMX_AUDIO_CODINGTYPE> arrEncoding;
-    android::hardware::media::omx::V1_0::Status status;
-
-    while (1) {
-        portFormat.nIndex = index;
-        status = getPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
-                              &portFormat);
-        if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
-        arrEncoding.push_back(portFormat.eEncoding);
-        index++;
-        if (index == 512) {
-            // enumerated way too many formats, highly unusual for this to
-            // happen.
-            EXPECT_LE(index, 512U)
-                << "Expecting OMX_ErrorNoMore but not received";
-            break;
-        }
-    }
-    if (!index) return status;
-    for (index = 0; index < arrEncoding.size(); index++) {
-        if (arrEncoding[index] == eEncoding) {
-            portFormat.eEncoding = arrEncoding[index];
-            break;
-        }
-    }
-    if (index == arrEncoding.size()) {
-        ALOGE("setting default Port format %x", (int)arrEncoding[0]);
-        portFormat.eEncoding = arrEncoding[0];
-    }
-    // In setParam call nIndex shall be ignored as per omx-il specification.
-    // see how this holds up by corrupting nIndex
-    portFormat.nIndex = RANDOM_INDEX;
-    status = setPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
-                          &portFormat);
-    return status;
-}
-
 // test dispatch message API call
 TEST_F(ComponentHidlTest, dispatchMsg) {
     description("test dispatch message API call");
index 9958869455b9717328181aa49767daa8219cdb85..e8f5f77dfda1897c85106b7ea1cc580bc55e46f4 100644 (file)
@@ -97,17 +97,22 @@ class ComponentTestEnvironment : public ::testing::Environment {
 static ComponentTestEnvironment* gEnv = nullptr;
 
 class MasterHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   private:
+    typedef ::testing::VtsHalHidlTargetTestBase Super;
    public:
     virtual void SetUp() override {
+        Super::SetUp();
         omxStore = nullptr;
-        omxStore = ::testing::VtsHalHidlTargetTestBase::getService<IOmxStore>();
+        omxStore = Super::getService<IOmxStore>();
         ASSERT_NE(omxStore, nullptr);
         omx = nullptr;
         omx = omxStore->getOmx(gEnv->getInstance());
         ASSERT_NE(omx, nullptr);
     }
 
-    virtual void TearDown() override {}
+    virtual void TearDown() override {
+        Super::TearDown();
+    }
 
     sp<IOmxStore> omxStore;
     sp<IOmx> omx;
index 2ff8ed3be0117666fe78079195194c8dbe11c03f..438dd7071e1732c518692b0b94a0160e809eeec7 100644 (file)
@@ -134,12 +134,22 @@ static ComponentTestEnvironment* gEnv = nullptr;
 
 // video decoder test fixture class
 class VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   private:
+    typedef ::testing::VtsHalHidlTargetTestBase Super;
    public:
+    ::std::string getTestCaseInfo() const override {
+        return ::std::string() +
+                "Component: " + gEnv->getComponent().c_str() + " | " +
+                "Role: " + gEnv->getRole().c_str() + " | " +
+                "Instance: " + gEnv->getInstance().c_str() + " | " +
+                "Res: " + gEnv->getRes().c_str();
+    }
+
     virtual void SetUp() override {
+        Super::SetUp();
         disableTest = false;
         android::hardware::media::omx::V1_0::Status status;
-        omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
-            gEnv->getInstance());
+        omx = Super::getService<IOmx>(gEnv->getInstance());
         ASSERT_NE(omx, nullptr);
         observer =
             new CodecObserver([this](Message msg, const BufferInfo* buffer) {
@@ -223,6 +233,7 @@ class VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
             EXPECT_TRUE((omxNode->freeNode()).isOk());
             omxNode = nullptr;
         }
+        Super::TearDown();
     }
 
     // callback function to process messages received by onMessages() from IL
@@ -474,8 +485,9 @@ void portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
                          android::Vector<BufferInfo>* iBuffer,
                          android::Vector<BufferInfo>* oBuffer,
                          OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
-                         Message msg, PortMode oPortMode) {
+                         Message msg, PortMode oPortMode, void* args) {
     android::hardware::media::omx::V1_0::Status status;
+    (void)args;
 
     if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
         ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
@@ -575,9 +587,6 @@ void portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
         std::cout << "[          ] Warning ! OMX_EventError/ "
                      "Decode Frame Call might be failed \n";
         return;
-    } else if (msg.data.eventData.event == OMX_EventBufferFlag) {
-        // soft omx components donot send this, we will just ignore it
-        // for now
     } else {
         // something unexpected happened
         ASSERT_TRUE(false);
@@ -602,7 +611,7 @@ void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
             EXPECT_EQ(msg.type, Message::Type::EVENT);
             portReconfiguration(omxNode, observer, iBuffer, oBuffer,
                                 kPortIndexInput, kPortIndexOutput, msg,
-                                oPortMode);
+                                oPortMode, nullptr);
         }
         // status == TIMED_OUT, it could be due to process time being large
         // than DEFAULT_TIMEOUT or component needs output buffers to start
@@ -668,7 +677,7 @@ void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
             msg.type == Message::Type::EVENT) {
             portReconfiguration(omxNode, observer, iBuffer, oBuffer,
                                 kPortIndexInput, kPortIndexOutput, msg,
-                                oPortMode);
+                                oPortMode, nullptr);
         }
 
         if (frameID == (int)Info->size() || frameID == (offset + range)) break;
@@ -770,7 +779,7 @@ TEST_F(VideoDecHidlTest, DecodeTest) {
     eleInfo.open(info);
     ASSERT_EQ(eleInfo.is_open(), true);
     android::Vector<FrameData> Info;
-    int bytesCount = 0;
+    int bytesCount = 0, maxBytesCount = 0;
     uint32_t flags = 0;
     uint32_t timestamp = 0;
     timestampDevTest = true;
@@ -781,9 +790,15 @@ TEST_F(VideoDecHidlTest, DecodeTest) {
         Info.push_back({bytesCount, flags, timestamp});
         if (flags != OMX_BUFFERFLAG_CODECCONFIG)
             timestampUslist.push_back(timestamp);
+        if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
     }
     eleInfo.close();
 
+    // As the frame sizes are known ahead, use it to configure i/p buffer size
+    maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
+    status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
     // set port mode
     portMode[0] = PortMode::PRESET_BYTE_BUFFER;
     portMode[1] = PortMode::DYNAMIC_ANW_BUFFER;
@@ -803,6 +818,8 @@ TEST_F(VideoDecHidlTest, DecodeTest) {
                         &xFramerate);
     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
+
+    // disabling adaptive playback.
     omxNode->prepareForAdaptivePlayback(kPortIndexOutput, false, 1920, 1080);
 
     android::Vector<BufferInfo> iBuffer, oBuffer;
@@ -834,7 +851,8 @@ TEST_F(VideoDecHidlTest, DecodeTest) {
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
                            kPortIndexInput, kPortIndexOutput, portMode[1]);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode);
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
     EXPECT_EQ(timestampUslist.empty(), true);
     // set state to idle
     changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
@@ -884,7 +902,8 @@ TEST_F(VideoDecHidlTest, EOSTest_M) {
     changeStateIdletoExecute(omxNode, observer);
 
     // request EOS at the start
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode);
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     EXPECT_GE(framesReceived, 0U);
@@ -923,7 +942,7 @@ TEST_F(VideoDecHidlTest, ThumbnailTest) {
     eleInfo.open(info);
     ASSERT_EQ(eleInfo.is_open(), true);
     android::Vector<FrameData> Info;
-    int bytesCount = 0;
+    int bytesCount = 0, maxBytesCount = 0;
     uint32_t flags = 0;
     uint32_t timestamp = 0;
     while (1) {
@@ -931,9 +950,21 @@ TEST_F(VideoDecHidlTest, ThumbnailTest) {
         eleInfo >> flags;
         eleInfo >> timestamp;
         Info.push_back({bytesCount, flags, timestamp});
+        if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
     }
     eleInfo.close();
 
+    // As the frame sizes are known ahead, use it to configure i/p buffer size
+    maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
+    status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
+    // set port mode
+    status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
     // set Port Params
     uint32_t nFrameWidth, nFrameHeight, xFramerate;
     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
@@ -968,7 +999,8 @@ TEST_F(VideoDecHidlTest, ThumbnailTest) {
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
                            kPortIndexInput, kPortIndexOutput, portMode[1]);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode);
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     EXPECT_GE(framesReceived, 1U);
@@ -983,7 +1015,8 @@ TEST_F(VideoDecHidlTest, ThumbnailTest) {
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
                            kPortIndexInput, kPortIndexOutput, portMode[1]);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode);
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     EXPECT_GE(framesReceived, 1U);
@@ -1022,7 +1055,7 @@ TEST_F(VideoDecHidlTest, SimpleEOSTest) {
     eleInfo.open(info);
     ASSERT_EQ(eleInfo.is_open(), true);
     android::Vector<FrameData> Info;
-    int bytesCount = 0;
+    int bytesCount = 0, maxBytesCount = 0;
     uint32_t flags = 0;
     uint32_t timestamp = 0;
     while (1) {
@@ -1030,9 +1063,21 @@ TEST_F(VideoDecHidlTest, SimpleEOSTest) {
         eleInfo >> flags;
         eleInfo >> timestamp;
         Info.push_back({bytesCount, flags, timestamp});
+        if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
     }
     eleInfo.close();
 
+    // As the frame sizes are known ahead, use it to configure i/p buffer size
+    maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
+    status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
+    // set port mode
+    status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
     // set Port Params
     uint32_t nFrameWidth, nFrameHeight, xFramerate;
     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
@@ -1066,7 +1111,8 @@ TEST_F(VideoDecHidlTest, SimpleEOSTest) {
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
                            kPortIndexInput, kPortIndexOutput, portMode[1]);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode);
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     framesReceived = 0;
@@ -1104,7 +1150,7 @@ TEST_F(VideoDecHidlTest, FlushTest) {
     eleInfo.open(info);
     ASSERT_EQ(eleInfo.is_open(), true);
     android::Vector<FrameData> Info;
-    int bytesCount = 0;
+    int bytesCount = 0, maxBytesCount = 0;
     uint32_t flags = 0;
     uint32_t timestamp = 0;
     while (1) {
@@ -1112,9 +1158,21 @@ TEST_F(VideoDecHidlTest, FlushTest) {
         eleInfo >> flags;
         eleInfo >> timestamp;
         Info.push_back({bytesCount, flags, timestamp});
+        if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
     }
     eleInfo.close();
 
+    // As the frame sizes are known ahead, use it to configure i/p buffer size
+    maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
+    status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
+    // set port mode
+    status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
     // set Port Params
     uint32_t nFrameWidth, nFrameHeight, xFramerate;
     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
@@ -1172,6 +1230,7 @@ TEST_F(VideoDecHidlTest, FlushTest) {
                       Info.size() - index, portMode[1], false);
     }
     // Note: Assumes 200 ms is enough to end any decode call that started
+    eleStream.close();
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput, 200000);
     framesReceived = 0;
index cd6eaf5632b3f2e66220582a8dd2a89b74ea8a69..7f9486d953a452c2c2d8db33aee1470b6efb90da 100644 (file)
@@ -147,12 +147,22 @@ static ComponentTestEnvironment* gEnv = nullptr;
 
 // video encoder test fixture class
 class VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   private:
+    typedef ::testing::VtsHalHidlTargetTestBase Super;
    public:
+    ::std::string getTestCaseInfo() const override {
+        return ::std::string() +
+                "Component: " + gEnv->getComponent().c_str() + " | " +
+                "Role: " + gEnv->getRole().c_str() + " | " +
+                "Instance: " + gEnv->getInstance().c_str() + " | " +
+                "Res: " + gEnv->getRes().c_str();
+    }
+
     virtual void SetUp() override {
+        Super::SetUp();
         disableTest = false;
         android::hardware::media::omx::V1_0::Status status;
-        omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
-            gEnv->getInstance());
+        omx = Super::getService<IOmx>(gEnv->getInstance());
         ASSERT_NE(omx, nullptr);
         observer =
             new CodecObserver([this](Message msg, const BufferInfo* buffer) {
@@ -235,6 +245,7 @@ class VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
             EXPECT_TRUE((omxNode->freeNode()).isOk());
             omxNode = nullptr;
         }
+        Super::TearDown();
     }
 
     // callback function to process messages received by onMessages() from IL
index 77763d172cfc9eb456141f6d67a9fb5203bbccfe..91aecf22e6790b460da8d4dc4642feb6f68d737a 100644 (file)
@@ -52,68 +52,6 @@ using ::android::sp;
 #include <media_video_hidl_test_common.h>
 #include <memory>
 
-Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
-    sp<IOmxNode> omxNode, OMX_U32 portIndex,
-    OMX_VIDEO_CODINGTYPE eCompressionFormat, OMX_COLOR_FORMATTYPE eColorFormat,
-    OMX_U32 xFramerate) {
-    OMX_U32 index = 0;
-    OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
-    std::vector<OMX_COLOR_FORMATTYPE> arrColorFormat;
-    std::vector<OMX_VIDEO_CODINGTYPE> arrCompressionFormat;
-    android::hardware::media::omx::V1_0::Status status;
-
-    while (1) {
-        portFormat.nIndex = index;
-        status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
-                              &portFormat);
-        if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
-        if (eCompressionFormat == OMX_VIDEO_CodingUnused)
-            arrColorFormat.push_back(portFormat.eColorFormat);
-        else
-            arrCompressionFormat.push_back(portFormat.eCompressionFormat);
-        index++;
-        if (index == 512) {
-            // enumerated way too many formats, highly unusual for this to
-            // happen.
-            EXPECT_LE(index, 512U)
-                << "Expecting OMX_ErrorNoMore but not received";
-            break;
-        }
-    }
-    if (!index) return status;
-    if (eCompressionFormat == OMX_VIDEO_CodingUnused) {
-        for (index = 0; index < arrColorFormat.size(); index++) {
-            if (arrColorFormat[index] == eColorFormat) {
-                portFormat.eColorFormat = arrColorFormat[index];
-                break;
-            }
-        }
-        if (index == arrColorFormat.size()) {
-            ALOGE("setting default color format %x", (int)arrColorFormat[0]);
-            portFormat.eColorFormat = arrColorFormat[0];
-        }
-        portFormat.eCompressionFormat = OMX_VIDEO_CodingUnused;
-    } else {
-        for (index = 0; index < arrCompressionFormat.size(); index++) {
-            if (arrCompressionFormat[index] == eCompressionFormat) {
-                portFormat.eCompressionFormat = arrCompressionFormat[index];
-                break;
-            }
-        }
-        if (index == arrCompressionFormat.size()) {
-            ALOGE("setting default compression format %x",
-                  (int)arrCompressionFormat[0]);
-            portFormat.eCompressionFormat = arrCompressionFormat[0];
-        }
-        portFormat.eColorFormat = OMX_COLOR_FormatUnused;
-    }
-    portFormat.nIndex = 0;
-    portFormat.xFramerate = xFramerate;
-    status = setPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
-                          &portFormat);
-    return status;
-}
-
 void enumerateProfileAndLevel(sp<IOmxNode> omxNode, OMX_U32 portIndex,
                               std::vector<int32_t>* arrProfile,
                               std::vector<int32_t>* arrLevel) {
index e4927792e3fdba576c5455b9bcf52c4d4c104c96..c1d7aeae55b8ec2bda42b7e2ba97a68a4b2e10a8 100644 (file)
  * Common video utils
  */
 
-Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
-    sp<IOmxNode> omxNode, OMX_U32 portIndex,
-    OMX_VIDEO_CODINGTYPE eCompressionFormat, OMX_COLOR_FORMATTYPE eColorFormat,
-    OMX_U32 xFramerate);
-
 void enumerateProfileAndLevel(sp<IOmxNode> omxNode, OMX_U32 portIndex,
                               std::vector<int32_t>* arrProfile,
                               std::vector<int32_t>* arrLevel);
diff --git a/oemlock/1.0/Android.bp b/oemlock/1.0/Android.bp
new file mode 100644 (file)
index 0000000..742061d
--- /dev/null
@@ -0,0 +1,66 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+    name: "android.hardware.oemlock@1.0_hal",
+    srcs: [
+        "types.hal",
+        "IOemLock.hal",
+    ],
+}
+
+genrule {
+    name: "android.hardware.oemlock@1.0_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.oemlock@1.0",
+    srcs: [
+        ":android.hardware.oemlock@1.0_hal",
+    ],
+    out: [
+        "android/hardware/oemlock/1.0/types.cpp",
+        "android/hardware/oemlock/1.0/OemLockAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.oemlock@1.0_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.oemlock@1.0",
+    srcs: [
+        ":android.hardware.oemlock@1.0_hal",
+    ],
+    out: [
+        "android/hardware/oemlock/1.0/types.h",
+        "android/hardware/oemlock/1.0/hwtypes.h",
+        "android/hardware/oemlock/1.0/IOemLock.h",
+        "android/hardware/oemlock/1.0/IHwOemLock.h",
+        "android/hardware/oemlock/1.0/BnHwOemLock.h",
+        "android/hardware/oemlock/1.0/BpHwOemLock.h",
+        "android/hardware/oemlock/1.0/BsOemLock.h",
+    ],
+}
+
+cc_library {
+    name: "android.hardware.oemlock@1.0",
+    defaults: ["hidl-module-defaults"],
+    generated_sources: ["android.hardware.oemlock@1.0_genc++"],
+    generated_headers: ["android.hardware.oemlock@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.oemlock@1.0_genc++_headers"],
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+    ],
+}
diff --git a/oemlock/1.0/Android.mk b/oemlock/1.0/Android.mk
new file mode 100644 (file)
index 0000000..91cc8f8
--- /dev/null
@@ -0,0 +1,83 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.oemlock-V1.0-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+    android.hidl.base-V1.0-java \
+
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES += core-oj hwbinder
+
+#
+# Build types.hal (OemLockSecureStatus)
+#
+GEN := $(intermediates)/android/hardware/oemlock/V1_0/OemLockSecureStatus.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.oemlock@1.0::types.OemLockSecureStatus
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (OemLockStatus)
+#
+GEN := $(intermediates)/android/hardware/oemlock/V1_0/OemLockStatus.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.oemlock@1.0::types.OemLockStatus
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IOemLock.hal
+#
+GEN := $(intermediates)/android/hardware/oemlock/V1_0/IOemLock.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IOemLock.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.oemlock@1.0::IOemLock
+
+$(GEN): $(LOCAL_PATH)/IOemLock.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/oemlock/1.0/IOemLock.hal b/oemlock/1.0/IOemLock.hal
new file mode 100644 (file)
index 0000000..d570123
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+package android.hardware.oemlock@1.0;
+
+/*
+ * The OEM lock prevents the bootloader from allowing the device to be flashed.
+ *
+ * Both the carrier and the device itself have a say as to whether OEM unlock is
+ * allowed and both must agree that is allowed in order for unlock to be
+ * possible.
+ */
+interface IOemLock {
+    /**
+     * Returns a vendor specific identifier of the HAL.
+     *
+     * The name returned must not be interpreted by the framework but must be
+     * passed to vendor code which may use it to identify the security protocol
+     * used by setOemUnlockAllowedByCarrier. This allows the vendor to identify
+     * the protocol without having to maintain a device-to-protocol mapping.
+     *
+     * @return name of the implementation.
+     */
+    getName() generates (OemLockStatus status, string name);
+
+    /**
+     * Updates whether OEM unlock is allowed by the carrier.
+     *
+     * The implementation may require a vendor defined signature to prove the
+     * validity of this request in order to harden its security.
+     *
+     * @param allowed is the new value of the flag.
+     * @param signature to prove validity of this request or empty if not
+     *        required.
+     * @return status is OK if the flag was successfully updated,
+     *         INVALID_SIGNATURE if a signature is required but the wrong one
+     *         was provided or FAILED if the update was otherwise unsuccessful.
+     */
+    setOemUnlockAllowedByCarrier(bool allowed, vec<uint8_t> signature)
+            generates (OemLockSecureStatus status);
+
+    /**
+     * Returns whether OEM unlock is allowed by the carrier.
+     *
+     * @return status is OK if the flag was successfully read.
+     * @return allowed is the current state of the flag.
+     */
+    isOemUnlockAllowedByCarrier() generates (OemLockStatus status, bool allowed);
+
+    /**
+     * Updates whether OEM unlock is allowed by the device.
+     *
+     * @param allowed is the new value of the flag.
+     * @return status is OK if the flag was successfully updated.
+     */
+    setOemUnlockAllowedByDevice(bool allowed) generates (OemLockStatus status);
+
+    /**
+     * Returns whether OEM unlock ia allowed by the device.
+     *
+     * @return status is OK if the flag was successfully read.
+     * @return allowed is the current state of the flag.
+     */
+    isOemUnlockAllowedByDevice() generates (OemLockStatus status, bool allowed);
+};
diff --git a/oemlock/1.0/types.hal b/oemlock/1.0/types.hal
new file mode 100644 (file)
index 0000000..0b4a8d1
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+package android.hardware.oemlock@1.0;
+
+enum OemLockStatus : uint32_t {
+    /** The operation completed successfully. */
+    OK,
+    /** The operation encountered a problem. */
+    FAILED,
+};
+
+enum OemLockSecureStatus : OemLockStatus {
+    /** An invalid signature was provided so the operation was not performed. */
+    INVALID_SIGNATURE,
+};
diff --git a/oemlock/1.0/vts/functional/Android.bp b/oemlock/1.0/vts/functional/Android.bp
new file mode 100644 (file)
index 0000000..a13b3dc
--- /dev/null
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "VtsHalOemLockV1_0TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalOemLockV1_0TargetTest.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.oemlock@1.0",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/oemlock/1.0/vts/functional/VtsHalOemLockV1_0TargetTest.cpp b/oemlock/1.0/vts/functional/VtsHalOemLockV1_0TargetTest.cpp
new file mode 100644 (file)
index 0000000..a924fec
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+#include <android/hardware/oemlock/1.0/IOemLock.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+using ::android::hardware::oemlock::V1_0::IOemLock;
+using ::android::hardware::oemlock::V1_0::OemLockStatus;
+using ::android::hardware::oemlock::V1_0::OemLockSecureStatus;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::sp;
+
+struct OemLockHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+    virtual void SetUp() override {
+        oemlock = ::testing::VtsHalHidlTargetTestBase::getService<IOemLock>();
+        ASSERT_NE(oemlock, nullptr);
+    }
+
+    virtual void TearDown() override {}
+
+    sp<IOemLock> oemlock;
+};
+
+/*
+ * Check the name can be retrieved
+ */
+TEST_F(OemLockHidlTest, GetName) {
+    std::string name;
+    OemLockStatus status;
+
+    bool callbackCalled = false;
+    const auto ret = oemlock->getName([&](OemLockStatus s, hidl_string n) {
+        callbackCalled = true;
+        status = s;
+        name = n.c_str();
+    });
+
+    ASSERT_TRUE(ret.isOk());
+    ASSERT_TRUE(callbackCalled);
+    EXPECT_EQ(status, OemLockStatus::OK);
+    // Any value acceptable
+};
+
+/*
+ * Check the unlock allowed by device state can be queried
+ */
+TEST_F(OemLockHidlTest, QueryUnlockAllowedByDevice) {
+    bool allowed;
+    OemLockStatus status;
+
+    bool callbackCalled = false;
+    const auto ret = oemlock->isOemUnlockAllowedByDevice([&](OemLockStatus s, bool a) {
+        callbackCalled = true;
+        status = s;
+        allowed = a;
+    });
+
+    ASSERT_TRUE(ret.isOk());
+    ASSERT_TRUE(callbackCalled);
+    EXPECT_EQ(status, OemLockStatus::OK);
+    // Any value acceptable
+}
+
+/*
+ * Check unlock allowed by device state can be toggled
+ */
+TEST_F(OemLockHidlTest, AllowedByDeviceCanBeToggled) {
+    bool allowed;
+    OemLockStatus status;
+
+    auto getAllowedCallback = [&](OemLockStatus s, bool a) {
+        status = s;
+        allowed = a;
+    };
+
+    // Get the original state so it can be restored
+    const auto get_ret = oemlock->isOemUnlockAllowedByDevice(getAllowedCallback);
+    ASSERT_TRUE(get_ret.isOk());
+    ASSERT_EQ(status, OemLockStatus::OK);
+    const bool originallyAllowed = allowed;
+
+    // Toggle the state
+    const auto set_ret = oemlock->setOemUnlockAllowedByDevice(!originallyAllowed);
+    ASSERT_TRUE(set_ret.isOk());
+    ASSERT_EQ(set_ret, OemLockStatus::OK);
+    const auto check_set_ret = oemlock->isOemUnlockAllowedByDevice(getAllowedCallback);
+    ASSERT_TRUE(check_set_ret.isOk());
+    ASSERT_EQ(status, OemLockStatus::OK);
+    ASSERT_EQ(allowed, !originallyAllowed);
+
+    // Restore the state
+    const auto restore_ret = oemlock->setOemUnlockAllowedByDevice(originallyAllowed);
+    ASSERT_TRUE(restore_ret.isOk());
+    ASSERT_EQ(restore_ret, OemLockStatus::OK);
+    const auto check_restore_ret = oemlock->isOemUnlockAllowedByDevice(getAllowedCallback);
+    ASSERT_TRUE(check_restore_ret.isOk());
+    ASSERT_EQ(status, OemLockStatus::OK);
+    ASSERT_EQ(allowed, originallyAllowed);
+};
+
+/*
+ * Check the unlock allowed by device state can be queried
+ */
+TEST_F(OemLockHidlTest, QueryUnlockAllowedByCarrier) {
+    bool allowed;
+    OemLockStatus status;
+
+    bool callbackCalled = false;
+    const auto ret = oemlock->isOemUnlockAllowedByCarrier([&](OemLockStatus s, bool a) {
+        callbackCalled = true;
+        status = s;
+        allowed = a;
+    });
+
+    ASSERT_TRUE(ret.isOk());
+    ASSERT_TRUE(callbackCalled);
+    EXPECT_EQ(status, OemLockStatus::OK);
+    // Any value acceptable
+}
+
+/*
+ * Attempt to check unlock allowed by carrier can be toggled
+ *
+ * The implementation may involve a signature which cannot be tested here. That
+ * is a valid implementation so the test will pass. If there is no signature
+ * required, the test will toggle the value.
+ */
+TEST_F(OemLockHidlTest, CarrierUnlock) {
+    const hidl_vec<uint8_t> noSignature = {};
+    bool allowed;
+    OemLockStatus status;
+
+    auto getAllowedCallback = [&](OemLockStatus s, bool a) {
+        status = s;
+        allowed = a;
+    };
+
+    // Get the original state so it can be restored
+    const auto get_ret = oemlock->isOemUnlockAllowedByCarrier(getAllowedCallback);
+    ASSERT_TRUE(get_ret.isOk());
+    ASSERT_EQ(status, OemLockStatus::OK);
+    const bool originallyAllowed = allowed;
+
+    if (originallyAllowed) {
+        // Only applied to locked devices
+        return;
+    }
+
+    // Toggle the state
+    const auto set_ret = oemlock->setOemUnlockAllowedByCarrier(!originallyAllowed, noSignature);
+    ASSERT_TRUE(set_ret.isOk());
+    ASSERT_NE(set_ret, OemLockSecureStatus::FAILED);
+    const auto check_set_ret = oemlock->isOemUnlockAllowedByCarrier(getAllowedCallback);
+    ASSERT_TRUE(check_set_ret.isOk());
+    ASSERT_EQ(status, OemLockStatus::OK);
+
+    if (set_ret == OemLockSecureStatus::INVALID_SIGNATURE) {
+        // Signature is required so we cannot toggle the value in the test, but this is allowed
+        ASSERT_EQ(allowed, originallyAllowed);
+        return;
+    }
+
+    ASSERT_EQ(set_ret, OemLockSecureStatus::OK);
+    ASSERT_EQ(allowed, !originallyAllowed);
+
+    // Restore the state
+    const auto restore_ret = oemlock->setOemUnlockAllowedByCarrier(originallyAllowed, noSignature);
+    ASSERT_TRUE(restore_ret.isOk());
+    ASSERT_EQ(restore_ret, OemLockSecureStatus::OK);
+    const auto check_restore_ret = oemlock->isOemUnlockAllowedByCarrier(getAllowedCallback);
+    ASSERT_TRUE(check_restore_ret.isOk());
+    ASSERT_EQ(status, OemLockStatus::OK);
+    ASSERT_EQ(allowed, originallyAllowed);
+};
diff --git a/oemlock/Android.bp b/oemlock/Android.bp
new file mode 100644 (file)
index 0000000..33f70eb
--- /dev/null
@@ -0,0 +1,5 @@
+// This is an autogenerated file, do not edit.
+subdirs = [
+    "1.0",
+    "1.0/vts/functional",
+]
diff --git a/power/1.1/Android.bp b/power/1.1/Android.bp
new file mode 100644 (file)
index 0000000..fb10aba
--- /dev/null
@@ -0,0 +1,68 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+    name: "android.hardware.power@1.1_hal",
+    srcs: [
+        "types.hal",
+        "IPower.hal",
+    ],
+}
+
+genrule {
+    name: "android.hardware.power@1.1_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.power@1.1",
+    srcs: [
+        ":android.hardware.power@1.1_hal",
+    ],
+    out: [
+        "android/hardware/power/1.1/types.cpp",
+        "android/hardware/power/1.1/PowerAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.power@1.1_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.power@1.1",
+    srcs: [
+        ":android.hardware.power@1.1_hal",
+    ],
+    out: [
+        "android/hardware/power/1.1/types.h",
+        "android/hardware/power/1.1/hwtypes.h",
+        "android/hardware/power/1.1/IPower.h",
+        "android/hardware/power/1.1/IHwPower.h",
+        "android/hardware/power/1.1/BnHwPower.h",
+        "android/hardware/power/1.1/BpHwPower.h",
+        "android/hardware/power/1.1/BsPower.h",
+    ],
+}
+
+cc_library {
+    name: "android.hardware.power@1.1",
+    defaults: ["hidl-module-defaults"],
+    generated_sources: ["android.hardware.power@1.1_genc++"],
+    generated_headers: ["android.hardware.power@1.1_genc++_headers"],
+    export_generated_headers: ["android.hardware.power@1.1_genc++_headers"],
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hardware.power@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.power@1.0",
+    ],
+}
diff --git a/power/1.1/Android.mk b/power/1.1/Android.mk
new file mode 100644 (file)
index 0000000..5044cfa
--- /dev/null
@@ -0,0 +1,84 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.power-V1.1-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+    android.hardware.power-V1.0-java \
+    android.hidl.base-V1.0-java \
+
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES += core-oj hwbinder
+
+#
+# Build types.hal (PowerStateSubsystem)
+#
+GEN := $(intermediates)/android/hardware/power/V1_1/PowerStateSubsystem.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.power@1.1::types.PowerStateSubsystem
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (PowerStateSubsystemSleepState)
+#
+GEN := $(intermediates)/android/hardware/power/V1_1/PowerStateSubsystemSleepState.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.power@1.1::types.PowerStateSubsystemSleepState
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IPower.hal
+#
+GEN := $(intermediates)/android/hardware/power/V1_1/IPower.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IPower.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.power@1.1::IPower
+
+$(GEN): $(LOCAL_PATH)/IPower.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/power/1.1/IPower.hal b/power/1.1/IPower.hal
new file mode 100644 (file)
index 0000000..086904e
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+package android.hardware.power@1.1;
+
+import android.hardware.power@1.0;
+
+/**
+ * Interface to collect subsystem level sleep information
+ */
+interface IPower extends android.hardware.power@1.0::IPower {
+
+    /**
+     * Subsystem-level sleep state stats:
+     * Report cumulative info on the statistics on subsystem-level sleep states
+     * since boot.
+     *
+     * @return subsystems supported on this device and their sleep states
+     * @return retval SUCCESS on success or FILESYSTEM_ERROR on filesystem
+     * nodes access error.
+     */
+    getSubsystemLowPowerStats()
+            generates (vec<PowerStateSubsystem> subsystems, Status retval);
+
+    /**
+     * powerHintAsync() is called to pass hints on power requirements which
+     * may result in adjustment of power/performance parameters of the
+     * cpufreq governor and other controls.
+     *
+     * A particular platform may choose to ignore any hint.
+     *
+     * @param hint PowerHint which is passed
+     * @param data contains additional information about the hint
+     * and is described along with the comments for each of the hints.
+     */
+    oneway powerHintAsync(PowerHint hint, int32_t data);
+
+};
diff --git a/power/1.1/default/Android.bp b/power/1.1/default/Android.bp
new file mode 100644 (file)
index 0000000..0b3598b
--- /dev/null
@@ -0,0 +1,33 @@
+// 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.
+
+cc_binary {
+    proprietary: true,
+    defaults: ["hidl_defaults"],
+    relative_install_path: "hw",
+    name: "android.hardware.power@1.1-service",
+    init_rc: ["android.hardware.power@1.1-service.rc"],
+    srcs: ["service.cpp" , "Power.cpp"],
+
+    shared_libs: [
+        "liblog",
+        "libdl",
+        "libutils",
+        "libhardware",
+        "libhidlbase",
+        "libhidltransport",
+        "android.hardware.power@1.0",
+        "android.hardware.power@1.1",
+    ],
+}
diff --git a/power/1.1/default/Power.cpp b/power/1.1/default/Power.cpp
new file mode 100644 (file)
index 0000000..b5d0c84
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * 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 "android.hardware.power@1.1-impl"
+
+#include <log/log.h>
+
+#include <hardware/hardware.h>
+#include <hardware/power.h>
+
+#include "Power.h"
+
+namespace android {
+namespace hardware {
+namespace power {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::power::V1_0::Feature;
+using ::android::hardware::power::V1_0::PowerHint;
+using ::android::hardware::power::V1_0::PowerStatePlatformSleepState;
+using ::android::hardware::power::V1_0::Status;
+using ::android::hardware::power::V1_1::PowerStateSubsystem;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+Power::Power(power_module_t *module) : mModule(module) {
+    if (mModule)
+        mModule->init(mModule);
+}
+
+Power::~Power() {
+    delete(mModule);
+}
+
+// Methods from ::android::hardware::power::V1_0::IPower follow.
+Return<void> Power::setInteractive(bool interactive)  {
+    if (mModule->setInteractive)
+        mModule->setInteractive(mModule, interactive ? 1 : 0);
+    return Void();
+}
+
+Return<void> Power::powerHint(PowerHint hint, int32_t data)  {
+    int32_t param = data;
+    if (mModule->powerHint) {
+        if (data)
+            mModule->powerHint(mModule, static_cast<power_hint_t>(hint), &param);
+        else
+            mModule->powerHint(mModule, static_cast<power_hint_t>(hint), NULL);
+    }
+    return Void();
+}
+
+Return<void> Power::setFeature(Feature feature, bool activate)  {
+    if (mModule->setFeature)
+        mModule->setFeature(mModule, static_cast<feature_t>(feature),
+                activate ? 1 : 0);
+    return Void();
+}
+
+Return<void> Power::getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb)  {
+    hidl_vec<PowerStatePlatformSleepState> states;
+    ssize_t number_platform_modes;
+    size_t *voters = nullptr;
+    power_state_platform_sleep_state_t *legacy_states = nullptr;
+    int ret;
+
+    if (mModule->get_number_of_platform_modes == nullptr ||
+            mModule->get_voter_list == nullptr ||
+            mModule->get_platform_low_power_stats == nullptr)
+    {
+        _hidl_cb(states, Status::SUCCESS);
+        return Void();
+    }
+
+    number_platform_modes = mModule->get_number_of_platform_modes(mModule);
+    if (number_platform_modes)
+    {
+       if ((ssize_t) (SIZE_MAX / sizeof(size_t)) <= number_platform_modes)  // overflow
+           goto done;
+       voters = new (std::nothrow) size_t [number_platform_modes];
+       if (voters == nullptr)
+           goto done;
+
+       ret = mModule->get_voter_list(mModule, voters);
+       if (ret != 0)
+           goto done;
+
+       if ((ssize_t) (SIZE_MAX / sizeof(power_state_platform_sleep_state_t))
+           <= number_platform_modes)  // overflow
+           goto done;
+       legacy_states = new (std::nothrow)
+           power_state_platform_sleep_state_t [number_platform_modes];
+       if (legacy_states == nullptr)
+           goto done;
+
+       for (int i = 0; i < number_platform_modes; i++)
+       {
+          legacy_states[i].voters = nullptr;
+          legacy_states[i].voters = new power_state_voter_t [voters[i]];
+          if (legacy_states[i].voters == nullptr)
+              goto done;
+       }
+
+       ret = mModule->get_platform_low_power_stats(mModule, legacy_states);
+       if (ret != 0)
+           goto done;
+
+       states.resize(number_platform_modes);
+       for (int i = 0; i < number_platform_modes; i++)
+       {
+          power_state_platform_sleep_state_t& legacy_state = legacy_states[i];
+          PowerStatePlatformSleepState& state = states[i];
+          state.name = legacy_state.name;
+          state.residencyInMsecSinceBoot = legacy_state.residency_in_msec_since_boot;
+          state.totalTransitions = legacy_state.total_transitions;
+          state.supportedOnlyInSuspend = legacy_state.supported_only_in_suspend;
+          state.voters.resize(voters[i]);
+          for(size_t j = 0; j < voters[i]; j++)
+          {
+              state.voters[j].name = legacy_state.voters[j].name;
+              state.voters[j].totalTimeInMsecVotedForSinceBoot = legacy_state.voters[j].total_time_in_msec_voted_for_since_boot;
+              state.voters[j].totalNumberOfTimesVotedSinceBoot = legacy_state.voters[j].total_number_of_times_voted_since_boot;
+          }
+       }
+    }
+done:
+    if (legacy_states)
+    {
+        for (int i = 0; i < number_platform_modes; i++)
+        {
+            if(legacy_states[i].voters)
+                delete(legacy_states[i].voters);
+        }
+    }
+    delete[] legacy_states;
+    delete[] voters;
+    _hidl_cb(states, Status::SUCCESS);
+    return Void();
+}
+
+// Methods from ::android::hardware::power::V1_1::IPower follow.
+Return<void> Power::getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) {
+    hidl_vec<PowerStateSubsystem> subsystems;
+    ssize_t number_subsystems = 0;
+
+    //This API will report zero subsystems to support older devices
+    //For devices that support this API, they will have their own implementation
+    subsystems.resize(number_subsystems);
+    _hidl_cb(subsystems, Status::SUCCESS);
+    return Void();
+}
+
+Return<void> Power::powerHintAsync(PowerHint hint, int32_t data) {
+    // just call the normal power hint in this oneway function
+    return powerHint(hint, data);
+}
+
+} // namespace implementation
+}  // namespace V1_1
+}  // namespace power
+}  // namespace hardware
+}  // namespace android
diff --git a/power/1.1/default/Power.h b/power/1.1/default/Power.h
new file mode 100644 (file)
index 0000000..e779d64
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_POWER_V1_1_POWER_H
+#define ANDROID_HARDWARE_POWER_V1_1_POWER_H
+
+#include <android/hardware/power/1.1/IPower.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <hardware/power.h>
+
+namespace android {
+namespace hardware {
+namespace power {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::power::V1_0::Feature;
+using ::android::hardware::power::V1_0::PowerHint;
+using ::android::hardware::power::V1_1::IPower;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct Power : public IPower {
+    Power(power_module_t* module);
+    ~Power();
+
+    // Methods from ::android::hardware::power::V1_0::IPower follow
+    Return<void> setInteractive(bool interactive) override;
+    Return<void> powerHint(PowerHint hint, int32_t data) override;
+    Return<void> setFeature(Feature feature, bool activate) override;
+    Return<void> getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) override;
+
+    // Methods from ::android::hardware::power::V1_1::IPower follow.
+    Return<void> getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) override;
+    Return<void> powerHintAsync(PowerHint hint, int32_t data) override;
+
+    // Methods from ::android::hidl::base::V1_0::IBase follow.
+
+  private:
+    power_module_t* mModule;
+};
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace power
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_POWER_V1_1_POWER_H
diff --git a/power/1.1/default/android.hardware.power@1.1-service.rc b/power/1.1/default/android.hardware.power@1.1-service.rc
new file mode 100644 (file)
index 0000000..f2512f1
--- /dev/null
@@ -0,0 +1,4 @@
+service power-hal-1-1 /vendor/bin/hw/android.hardware.power@1.1-service
+    class hal
+    user system
+    group system
diff --git a/power/1.1/default/service.cpp b/power/1.1/default/service.cpp
new file mode 100644 (file)
index 0000000..571db2f
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * 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 "android.hardware.power@1.1-service"
+
+#include <android/log.h>
+#include <hidl/HidlTransportSupport.h>
+#include <android/hardware/power/1.1/IPower.h>
+#include <hardware/power.h>
+#include "Power.h"
+
+using android::sp;
+using android::status_t;
+using android::OK;
+
+// libhwbinder:
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+
+// Generated HIDL files
+using android::hardware::power::V1_1::IPower;
+using android::hardware::power::V1_1::implementation::Power;
+
+int main() {
+
+    status_t status;
+    android::sp<IPower> service = nullptr;
+    const hw_module_t* hw_module = nullptr;
+    power_module_t* power_module = nullptr;
+    int err;
+
+    ALOGI("Power HAL Service 1.1 (Default) is starting.");
+
+    err = hw_get_module(POWER_HARDWARE_MODULE_ID, &hw_module);
+    if (err) {
+        ALOGE("hw_get_module %s failed: %d", POWER_HARDWARE_MODULE_ID, err);
+        goto shutdown;
+    }
+
+    if (!hw_module->methods || !hw_module->methods->open) {
+        power_module = reinterpret_cast<power_module_t*>(
+            const_cast<hw_module_t*>(hw_module));
+    } else {
+        err = hw_module->methods->open(hw_module, POWER_HARDWARE_MODULE_ID,
+                                           reinterpret_cast<hw_device_t**>(&power_module));
+        if (err) {
+            ALOGE("Passthrough failed to load legacy HAL.");
+            goto shutdown;
+        }
+    }
+
+    service = new Power(power_module);
+    if (service == nullptr) {
+        ALOGE("Can not create an instance of Power HAL Iface, exiting.");
+
+        goto shutdown;
+    }
+
+    configureRpcThreadpool(1, true /*callerWillJoin*/);
+
+    status = service->registerAsService();
+    if (status != OK) {
+        ALOGE("Could not register service for Power HAL Iface (%d).", status);
+        goto shutdown;
+    }
+
+    ALOGI("Power Service is ready");
+    joinRpcThreadpool();
+    //Should not pass this line
+
+shutdown:
+    // In normal operation, we don't expect the thread pool to exit
+
+    ALOGE("Power Service is shutting down");
+    return 1;
+}
diff --git a/power/1.1/types.hal b/power/1.1/types.hal
new file mode 100644 (file)
index 0000000..5298d4e
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+package android.hardware.power@1.1;
+
+/**
+ * Subsytem-level sleep state stats:
+ * PowerStateSubsystemSleepState represents the sleep states
+ * a subsystem (e.g. wifi, bt) is capable of getting into.
+ *
+ * SoCs like wifi, bt usually have more than one subsystem level sleep state.
+ */
+struct PowerStateSubsystemSleepState {
+    /**
+     * Subsystem-level Sleep state name.
+     */
+    string name;
+
+    /**
+     * Time spent in msec at this subsystem-level sleep state since boot.
+     */
+    uint64_t residencyInMsecSinceBoot;
+
+    /**
+     * Total number of times sub-system entered this state.
+     */
+    uint64_t totalTransitions;
+
+    /**
+     * Timestamp of last entry of this state measured in MSec
+     */
+    uint64_t lastEntryTimestampMs;
+
+    /**
+     * This subsystem-level sleep state can only be reached during system suspend
+     */
+    bool supportedOnlyInSuspend;
+};
+
+/**
+ * Subsytem-level sleep state stats:
+ * PowerStateSubsystem represents a subsystem (e.g. wifi, bt)
+ * and all the sleep states this susbsystem is capable of getting into.
+ *
+ * SoCs like wifi, bt usually have more than one subsystem level sleep state.
+ */
+struct PowerStateSubsystem {
+    /**
+     * Subsystem name (e.g. wifi, bt etc.)
+     */
+    string name;
+
+    /**
+     * states represents the list of sleep states supported by this susbsystem.
+     * Higher the index in the returned <states> vector deeper the state is
+     * i.e. lesser steady-state power is consumed by the subsystem to
+     * to be resident in that state.
+     *
+     * Vector of size zero implies either the info is not available
+     * or the subsystem does not have any sleep states.
+     */
+    vec<PowerStateSubsystemSleepState> states;
+};
diff --git a/power/1.1/vts/functional/Android.bp b/power/1.1/vts/functional/Android.bp
new file mode 100644 (file)
index 0000000..f886bd2
--- /dev/null
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "VtsHalPowerV1_1TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalPowerV1_1TargetTest.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libhidlbase",
+        "libhidltransport",
+        "libutils",
+        "android.hardware.power@1.1",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ]
+}
diff --git a/power/1.1/vts/functional/VtsHalPowerV1_1TargetTest.cpp b/power/1.1/vts/functional/VtsHalPowerV1_1TargetTest.cpp
new file mode 100644 (file)
index 0000000..dc843f4
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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 "power_hidl_hal_test"
+#include <android-base/logging.h>
+#include <android/hardware/power/1.1/IPower.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+using ::android::hardware::power::V1_1::IPower;
+using ::android::hardware::power::V1_1::PowerStateSubsystem;
+using ::android::hardware::power::V1_0::Status;
+using ::android::hardware::power::V1_0::PowerHint;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::sp;
+
+class PowerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+  virtual void SetUp() override {
+    power = ::testing::VtsHalHidlTargetTestBase::getService<IPower>();
+    ASSERT_NE(power, nullptr);
+  }
+
+  virtual void TearDown() override {}
+
+  sp<IPower> power;
+};
+
+// Sanity check Power::getSubsystemLowPowerStats().
+TEST_F(PowerHidlTest, GetSubsystemLowPowerStats) {
+  hidl_vec<PowerStateSubsystem> vec;
+  Status s;
+  auto cb = [&vec, &s](hidl_vec<PowerStateSubsystem> subsystems,
+                       Status status) {
+    vec = subsystems;
+    s = status;
+  };
+
+  Return<void> ret = power->getSubsystemLowPowerStats(cb);
+  ASSERT_TRUE(ret.isOk());
+  ASSERT_TRUE(s == Status::SUCCESS || s == Status::FILESYSTEM_ERROR);
+}
+
+// Sanity check Power::powerHintAsync on good and bad inputs.
+TEST_F(PowerHidlTest, PowerHintAsync) {
+    PowerHint badHint = static_cast<PowerHint>(0xA);
+    auto hints = {PowerHint::VSYNC,        PowerHint::INTERACTION, PowerHint::VIDEO_ENCODE,
+                  PowerHint::VIDEO_DECODE, PowerHint::LOW_POWER,   PowerHint::SUSTAINED_PERFORMANCE,
+                  PowerHint::VR_MODE,      PowerHint::LAUNCH,      badHint};
+    Return<void> ret;
+    for (auto hint : hints) {
+        ret = power->powerHintAsync(hint, 30000);
+        ASSERT_TRUE(ret.isOk());
+
+        ret = power->powerHintAsync(hint, 0);
+        ASSERT_TRUE(ret.isOk());
+    }
+
+    // Turning these hints on in different orders triggers different code paths,
+    // so iterate over possible orderings.
+    std::vector<PowerHint> hints2 = {PowerHint::LAUNCH, PowerHint::VR_MODE,
+                                     PowerHint::SUSTAINED_PERFORMANCE, PowerHint::INTERACTION};
+    auto compareHints = [](PowerHint l, PowerHint r) {
+        return static_cast<uint32_t>(l) < static_cast<uint32_t>(r);
+    };
+    std::sort(hints2.begin(), hints2.end(), compareHints);
+    do {
+        for (auto iter = hints2.begin(); iter != hints2.end(); iter++) {
+            ret = power->powerHintAsync(*iter, 0);
+            ASSERT_TRUE(ret.isOk());
+        }
+        for (auto iter = hints2.begin(); iter != hints2.end(); iter++) {
+            ret = power->powerHintAsync(*iter, 30000);
+            ASSERT_TRUE(ret.isOk());
+        }
+    } while (std::next_permutation(hints2.begin(), hints2.end(), compareHints));
+}
+
+int main(int argc, char **argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  LOG(INFO) << "Test result = " << status;
+  return status;
+}
index ed19a37034cf68a33182e63e39bd7905d3e62731..7a315faab3c010d0ede54eed835289ffa98e553c 100644 (file)
@@ -3,4 +3,7 @@ subdirs = [
     "1.0",
     "1.0/default",
     "1.0/vts/functional",
+    "1.1",
+    "1.1/default",
+    "1.1/vts/functional",
 ]
index 35ab899bfb923170fa2284d69b7d176198fe2538..a94aac3352012a5e455b22de5f50ad7a1bf8b96f 100644 (file)
@@ -28,6 +28,12 @@ interface IRadioResponse {
      *
      * Valid errors returned:
      *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getIccCardStatusResponse(RadioResponseInfo info, CardStatus cardStatus);
 
@@ -39,6 +45,13 @@ interface IRadioResponse {
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
      *   RadioError:PASSWORD_INCORRECT
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway supplyIccPinForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -50,6 +63,13 @@ interface IRadioResponse {
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
      *   RadioError:PASSWORD_INCORRECT (PUK is invalid)
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway supplyIccPukForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -61,6 +81,13 @@ interface IRadioResponse {
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
      *   RadioError:PASSWORD_INCORRECT
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway supplyIccPin2ForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -71,6 +98,13 @@ interface IRadioResponse {
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
      *   RadioError:PASSWORD_INCORRECT (PUK is invalid)
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway supplyIccPuk2ForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -82,6 +116,13 @@ interface IRadioResponse {
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
      *   RadioError:PASSWORD_INCORRECT
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway changeIccPinForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -93,6 +134,13 @@ interface IRadioResponse {
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
      *   RadioError:PASSWORD_INCORRECT (old PIN2 is invalid)
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway changeIccPin2ForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -102,6 +150,7 @@ interface IRadioResponse {
      *
      * Valid errors returned:
      *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:PASSWORD_INCORRECT (code is invalid)
      *   RadioError:NO_MEMORY
      *   RadioError:INVALID_SIM_STATE
@@ -109,6 +158,9 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway supplyNetworkDepersonalizationResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -124,6 +176,8 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getCurrentCallsResponse(RadioResponseInfo info, vec<Call> calls);
 
@@ -147,11 +201,12 @@ interface IRadioResponse {
      *   RadioError:NO_NETWORK_FOUND
      *   RadioError:INVALID_CALL_ID
      *   RadioError:DEVICE_IN_USE
-     *   RadioError:MODE_NOT_SUPPORTED
+     *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:ABORTED
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:CANCELLED
      */
     oneway dialResponse(RadioResponseInfo info);
 
@@ -162,6 +217,13 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:SIM_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getIMSIForAppResponse(RadioResponseInfo info, string imsi);
 
@@ -177,6 +239,9 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
      *   RadioError:INVALID_CALL_ID
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway hangupConnectionResponse(RadioResponseInfo info);
 
@@ -196,6 +261,7 @@ interface IRadioResponse {
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:CANCELLED
      */
     oneway hangupWaitingOrBackgroundResponse(RadioResponseInfo info);
 
@@ -215,6 +281,8 @@ interface IRadioResponse {
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway hangupForegroundResumeBackgroundResponse(RadioResponseInfo info);
 
@@ -235,6 +303,8 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway switchWaitingOrHoldingAndActiveResponse(RadioResponseInfo info);
 
@@ -254,6 +324,8 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway conferenceResponse(RadioResponseInfo info);
 
@@ -274,6 +346,8 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway rejectCallResponse(RadioResponseInfo info);
 
@@ -322,6 +396,9 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getLastCallFailCauseResponse(RadioResponseInfo info,
             LastCallFailCauseInfo failCauseinfo);
@@ -339,6 +416,8 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:NOT_PROVISIONED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getSignalStrengthResponse(RadioResponseInfo info, SignalStrength sigStrength);
 
@@ -350,6 +429,11 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getVoiceRegistrationStateResponse(RadioResponseInfo info,
             VoiceRegStateResult voiceRegResponse);
@@ -368,6 +452,8 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:NOT_PROVISIONED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getDataRegistrationStateResponse(RadioResponseInfo info,
             DataRegStateResult dataRegResponse);
@@ -385,6 +471,8 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getOperatorResponse(RadioResponseInfo info, string longName, string shortName,
             string numeric);
@@ -406,6 +494,8 @@ interface IRadioResponse {
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setRadioPowerResponse(RadioResponseInfo info);
 
@@ -423,6 +513,7 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      */
     oneway sendDtmfResponse(RadioResponseInfo info);
@@ -446,12 +537,13 @@ interface IRadioResponse {
      *   RadioError:INVALID_SMSC_ADDRESS
      *   RadioError:MODEM_ERR
      *   RadioError:NETWORK_ERR
-     *   RadioError:MODE_NOT_SUPPORTED
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NETWORK_NOT_READY
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway sendSmsResponse(RadioResponseInfo info, SendSmsResult sms);
 
@@ -475,12 +567,13 @@ interface IRadioResponse {
      *   RadioError:INVALID_SMSC_ADDRESS
      *   RadioError:MODEM_ERR
      *   RadioError:NETWORK_ERR
-     *   RadioError:MODE_NOT_SUPPORTED
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NETWORK_NOT_READY
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway sendSMSExpectMoreResponse(RadioResponseInfo info, SendSmsResult sms);
 
@@ -497,7 +590,10 @@ interface IRadioResponse {
      *   RadioError:OP_NOT_ALLOWED_DURING_VOICE_CALL
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setupDataCallResponse(RadioResponseInfo info, SetupDataCallResult dcResponse);
 
@@ -510,6 +606,13 @@ interface IRadioResponse {
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SIM_PIN2
      *   RadioError:SIM_PUK2
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:SIM_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway iccIOForAppResponse(RadioResponseInfo info, IccIoResult iccIo);
 
@@ -534,6 +637,8 @@ interface IRadioResponse {
      *   RadioError:INVALID_STATE
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway sendUssdResponse(RadioResponseInfo info);
 
@@ -553,6 +658,8 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway cancelPendingUssdResponse(RadioResponseInfo info);
 
@@ -574,6 +681,8 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getClirResponse(RadioResponseInfo info, int32_t n, int32_t m);
 
@@ -591,6 +700,8 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setClirResponse(RadioResponseInfo info);
 
@@ -620,6 +731,8 @@ interface IRadioResponse {
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:SYSTEM_ERR
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getCallForwardStatusResponse(RadioResponseInfo info,
             vec<CallForwardInfo> callForwardInfos);
@@ -642,6 +755,8 @@ interface IRadioResponse {
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setCallForwardResponse(RadioResponseInfo info);
 
@@ -669,6 +784,8 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getCallWaitingResponse(RadioResponseInfo info, bool enable, int32_t serviceClass);
 
@@ -690,6 +807,8 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setCallWaitingResponse(RadioResponseInfo info);
 
@@ -699,6 +818,11 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway acknowledgeLastIncomingGsmSmsResponse(RadioResponseInfo info);
 
@@ -717,6 +841,8 @@ interface IRadioResponse {
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway acceptCallResponse(RadioResponseInfo info);
 
@@ -730,6 +856,10 @@ interface IRadioResponse {
      *   RadioError:INVALID_STATE
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway deactivateDataCallResponse(RadioResponseInfo info);
 
@@ -752,6 +882,8 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getFacilityLockForAppResponse(RadioResponseInfo info, int32_t response);
 
@@ -774,6 +906,8 @@ interface IRadioResponse {
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setFacilityLockForAppResponse(RadioResponseInfo info, int32_t retry);
 
@@ -793,6 +927,8 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setBarringPasswordResponse(RadioResponseInfo info);
 
@@ -809,6 +945,8 @@ interface IRadioResponse {
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getNetworkSelectionModeResponse(RadioResponseInfo info, bool manual);
 
@@ -826,6 +964,8 @@ interface IRadioResponse {
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      *
      * Returns RadioError:ILLEGAL_SIM_OR_ME when the failure is permanent and
      * no retries needed, such as illegal SIM or ME.
@@ -847,6 +987,8 @@ interface IRadioResponse {
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      *
      * Returns RadioError:ILLEGAL_SIM_OR_ME when the failure is permanent and
      * no retries needed, such as illegal SIM or ME.
@@ -869,6 +1011,8 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:CANCELLED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:INTERNAL_ERR
      */
     oneway getAvailableNetworksResponse(RadioResponseInfo info,
             vec<OperatorInfo> networkInfos);
@@ -888,6 +1032,7 @@ interface IRadioResponse {
      *   RadioError:INVALID_CALL_ID
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      */
     oneway startDtmfResponse(RadioResponseInfo info);
@@ -907,6 +1052,7 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:INVALID_CALL_ID
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      */
     oneway stopDtmfResponse(RadioResponseInfo info);
@@ -925,6 +1071,8 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:NOT_PROVISIONED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getBasebandVersionResponse(RadioResponseInfo info, string version);
 
@@ -945,6 +1093,7 @@ interface IRadioResponse {
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:CANCELLED
      */
     oneway separateConnectionResponse(RadioResponseInfo info);
 
@@ -960,6 +1109,8 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setMuteResponse(RadioResponseInfo info);
 
@@ -979,6 +1130,8 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getMuteResponse(RadioResponseInfo info, bool enable);
 
@@ -996,6 +1149,8 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getClipResponse(RadioResponseInfo info, ClipStatus status);
 
@@ -1006,6 +1161,11 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getDataCallListResponse(RadioResponseInfo info, vec<SetupDataCallResult> dcResponse);
 
@@ -1022,6 +1182,8 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setSuppServiceNotificationsResponse(RadioResponseInfo info);
 
@@ -1031,6 +1193,7 @@ interface IRadioResponse {
      *
      * Valid errors returned:
      *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SIM_FULL
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INVALID_SMS_FORMAT
@@ -1040,11 +1203,13 @@ interface IRadioResponse {
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:INVALID_MODEM_STATE
-     *   RadioError:MODE_NOT_SUPPORTED
+     *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:INVALID_SMSC_ADDRESS
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway writeSmsToSimResponse(RadioResponseInfo info, int32_t index);
 
@@ -1053,6 +1218,8 @@ interface IRadioResponse {
      *
      * Valid errors returned:
      *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:SIM_FULL
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:NO_MEMORY
      *   RadioError:SYSTEM_ERR
@@ -1061,6 +1228,8 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      */
     oneway deleteSmsOnSimResponse(RadioResponseInfo info);
@@ -1078,6 +1247,8 @@ interface IRadioResponse {
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setBandModeResponse(RadioResponseInfo info);
 
@@ -1094,6 +1265,8 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getAvailableBandModesResponse(RadioResponseInfo info, vec<RadioBandMode> bandModes);
 
@@ -1107,6 +1280,13 @@ interface IRadioResponse {
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SIM_BUSY
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:MODEM_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway sendEnvelopeResponse(RadioResponseInfo info, string commandResponse);
 
@@ -1118,6 +1298,12 @@ interface IRadioResponse {
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway sendTerminalResponseToSimResponse(RadioResponseInfo info);
 
@@ -1126,11 +1312,15 @@ interface IRadioResponse {
      *
      * Valid errors returned:
      *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:NO_MEMORY
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway handleStkCallSetupRequestFromSimResponse(RadioResponseInfo info);
 
@@ -1151,6 +1341,8 @@ interface IRadioResponse {
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway explicitCallTransferResponse(RadioResponseInfo info);
 
@@ -1168,6 +1360,8 @@ interface IRadioResponse {
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setPreferredNetworkTypeResponse(RadioResponseInfo info);
 
@@ -1184,6 +1378,8 @@ interface IRadioResponse {
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getPreferredNetworkTypeResponse(RadioResponseInfo info,
             PreferredNetworkType nwType);
@@ -1202,6 +1398,8 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:NO_NETWORK_FOUND
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getNeighboringCidsResponse(RadioResponseInfo info, vec<NeighboringCell> cells);
 
@@ -1217,6 +1415,8 @@ interface IRadioResponse {
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setLocationUpdatesResponse(RadioResponseInfo info);
 
@@ -1228,6 +1428,11 @@ interface IRadioResponse {
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SIM_ABSENT
      *   RadioError:SUBSCRIPTION_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway setCdmaSubscriptionSourceResponse(RadioResponseInfo info);
 
@@ -1244,6 +1449,8 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setCdmaRoamingPreferenceResponse(RadioResponseInfo info);
 
@@ -1260,6 +1467,8 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getCdmaRoamingPreferenceResponse(RadioResponseInfo info, CdmaRoamingType type);
 
@@ -1275,6 +1484,8 @@ interface IRadioResponse {
      *   RadioError:NO_MEMORY
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setTTYModeResponse(RadioResponseInfo info);
 
@@ -1291,6 +1502,8 @@ interface IRadioResponse {
      *   RadioError:NO_MEMORY
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getTTYModeResponse(RadioResponseInfo info, TtyMode mode);
 
@@ -1307,6 +1520,8 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_CALL_ID
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setPreferredVoicePrivacyResponse(RadioResponseInfo info);
 
@@ -1324,6 +1539,8 @@ interface IRadioResponse {
      *   RadioError:NO_MEMORY
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getPreferredVoicePrivacyResponse(RadioResponseInfo info, bool enable);
 
@@ -1344,6 +1561,9 @@ interface IRadioResponse {
      *   RadioError:INVALID_STATE
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:OPERATION_NOT_ALLOWED
      */
     oneway sendCDMAFeatureCodeResponse(RadioResponseInfo info);
 
@@ -1361,7 +1581,10 @@ interface IRadioResponse {
      *   RadioError:INVALID_CALL_ID
      *   RadioError:INVALID_STATE
      *   RadioError:REQUEST_NOT_SUPPORTED
-     *   RadioError:MODE_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:OPERATION_NOT_ALLOWED
      */
     oneway sendBurstDtmfResponse(RadioResponseInfo info);
 
@@ -1385,12 +1608,13 @@ interface IRadioResponse {
      *   RadioError:NETWORK_ERR
      *   RadioError:ENCODING_ERR
      *   RadioError:INVALID_SMSC_ADDRESS
-     *   RadioError:MODE_NOT_SUPPORTED
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:ENCODING_ERR
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway sendCdmaSmsResponse(RadioResponseInfo info, SendSmsResult sms);
 
@@ -1407,12 +1631,13 @@ interface IRadioResponse {
      *   RadioError:REQUEST_RATE_LIMITED
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
-     *   RadioError:MODE_NOT_SUPPORTED
      *   RadioError:NETWORK_NOT_READY
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway acknowledgeLastIncomingCdmaSmsResponse(RadioResponseInfo info);
 
@@ -1432,6 +1657,9 @@ interface IRadioResponse {
      *   RadioError:NO_RESOURCES
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway getGsmBroadcastConfigResponse(RadioResponseInfo info,
             vec<GsmBroadcastSmsConfigInfo> configs);
@@ -1450,6 +1678,9 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway setGsmBroadcastConfigResponse(RadioResponseInfo info);
 
@@ -1468,6 +1699,9 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway setGsmBroadcastActivationResponse(RadioResponseInfo info);
 
@@ -1487,6 +1721,9 @@ interface IRadioResponse {
      *   RadioError:NO_RESOURCES
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway getCdmaBroadcastConfigResponse(RadioResponseInfo info,
             vec<CdmaBroadcastSmsConfigInfo> configs);
@@ -1505,6 +1742,9 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway setCdmaBroadcastConfigResponse(RadioResponseInfo info);
 
@@ -1523,6 +1763,9 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway setCdmaBroadcastActivationResponse(RadioResponseInfo info);
 
@@ -1547,6 +1790,8 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:NOT_PROVISIONED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getCDMASubscriptionResponse(RadioResponseInfo info, string mdn, string hSid,
             string hNid, string min, string prl);
@@ -1567,11 +1812,13 @@ interface IRadioResponse {
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:INVALID_MODEM_STATE
-     *   RadioError:MODE_NOT_SUPPORTED
      *   RadioError:INVALID_SMSC_ADDRESS
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway writeSmsToRuimResponse(RadioResponseInfo info, uint32_t index);
 
@@ -1588,6 +1835,9 @@ interface IRadioResponse {
      *   RadioError:NO_SUCH_ENTRY
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      */
     oneway deleteSmsOnRuimResponse(RadioResponseInfo info);
@@ -1608,6 +1858,9 @@ interface IRadioResponse {
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:NOT_PROVISIONED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      *
      * If a empty string value is returned for any of the device id, it means that there was error
      * accessing the device.
@@ -1629,6 +1882,8 @@ interface IRadioResponse {
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway exitEmergencyCallbackModeResponse(RadioResponseInfo info);
 
@@ -1649,6 +1904,8 @@ interface IRadioResponse {
      *   RadioError:NOT_PROVISIONED
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getSmscAddressResponse(RadioResponseInfo info, string smsc);
 
@@ -1668,6 +1925,8 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setSmscAddressResponse(RadioResponseInfo info);
 
@@ -1685,6 +1944,8 @@ interface IRadioResponse {
      *   RadioError:INVALID_STATE
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway reportSmsMemoryStatusResponse(RadioResponseInfo info);
 
@@ -1694,6 +1955,11 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway reportStkServiceIsRunningResponse(RadioResponseInfo info);
 
@@ -1705,6 +1971,11 @@ interface IRadioResponse {
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SUBSCRIPTION_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getCdmaSubscriptionSourceResponse(RadioResponseInfo info, CdmaSubscriptionSource source);
 
@@ -1715,6 +1986,13 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway requestIsimAuthenticationResponse(RadioResponseInfo info, string response);
 
@@ -1724,6 +2002,11 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway acknowledgeIncomingGsmSmsWithPduResponse(RadioResponseInfo info);
 
@@ -1736,6 +2019,11 @@ interface IRadioResponse {
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SIM_BUSY
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway sendEnvelopeWithStatusResponse(RadioResponseInfo info, IccIoResult iccIo);
 
@@ -1746,6 +2034,11 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getVoiceRadioTechnologyResponse(RadioResponseInfo info, RadioTechnology rat);
 
@@ -1762,6 +2055,8 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:NO_NETWORK_FOUND
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getCellInfoListResponse(RadioResponseInfo info, vec<CellInfo> cellInfo);
 
@@ -1775,6 +2070,9 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway setCellInfoListRateResponse(RadioResponseInfo info);
 
@@ -1792,6 +2090,8 @@ interface IRadioResponse {
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:NOT_PROVISIONED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setInitialAttachApnResponse(RadioResponseInfo info);
 
@@ -1804,12 +2104,12 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:NO_MEMORY
      *   RadioError:INTERNAL_ERR
-     *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
-     *   RadioError:MODEM_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getImsRegistrationStateResponse(RadioResponseInfo info, bool isRegistered,
             RadioTechnologyFamily ratFamily);
@@ -1833,10 +2133,12 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:NETWORK_ERR
      *   RadioError:ENCODING_ERR
-     *   RadioError:MODE_NOT_SUPPORTED
+     *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NETWORK_NOT_READY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway sendImsSmsResponse(RadioResponseInfo info, SendSmsResult sms);
 
@@ -1847,6 +2149,11 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway iccTransmitApduBasicChannelResponse(RadioResponseInfo info, IccIoResult result);
 
@@ -1861,6 +2168,14 @@ interface IRadioResponse {
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:MISSING_RESOURCE
      *   RadioError:NO_SUCH_ELEMENT
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:SIM_ERR
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:MISSING_RESOURCE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway iccOpenLogicalChannelResponse(RadioResponseInfo info, int32_t channelId,
             vec<int8_t> selectResponse);
@@ -1871,6 +2186,11 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway iccCloseLogicalChannelResponse(RadioResponseInfo info);
 
@@ -1881,6 +2201,11 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway iccTransmitApduLogicalChannelResponse(RadioResponseInfo info, IccIoResult result);
 
@@ -1891,6 +2216,7 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway nvReadItemResponse(RadioResponseInfo info, string result);
 
@@ -1900,6 +2226,7 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway nvWriteItemResponse(RadioResponseInfo info);
 
@@ -1909,6 +2236,7 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway nvWriteCdmaPrlResponse(RadioResponseInfo info);
 
@@ -1918,6 +2246,7 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway nvResetConfigResponse(RadioResponseInfo info);
 
@@ -1934,6 +2263,8 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setUiccSubscriptionResponse(RadioResponseInfo info);
 
@@ -1950,6 +2281,9 @@ interface IRadioResponse {
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:DEVICE_IN_USE
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway setDataAllowedResponse(RadioResponseInfo info);
 
@@ -1960,6 +2294,7 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getHardwareConfigResponse(RadioResponseInfo info, vec<HardwareConfig> config);
 
@@ -1970,6 +2305,14 @@ interface IRadioResponse {
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:SIM_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway requestIccSimAuthenticationResponse(RadioResponseInfo info, IccIoResult result);
 
@@ -1980,6 +2323,11 @@ interface IRadioResponse {
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SUBSCRIPTION_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway setDataProfileResponse(RadioResponseInfo info);
 
@@ -1994,6 +2342,8 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway requestShutdownResponse(RadioResponseInfo info);
 
@@ -2007,6 +2357,10 @@ interface IRadioResponse {
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:INVALID_STATE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getRadioCapabilityResponse(RadioResponseInfo info, RadioCapability rc);
 
@@ -2026,6 +2380,8 @@ interface IRadioResponse {
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_STATE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setRadioCapabilityResponse(RadioResponseInfo info, RadioCapability rc);
 
@@ -2039,6 +2395,9 @@ interface IRadioResponse {
      *   RadioError:LCE_NOT_SUPPORTED
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway startLceServiceResponse(RadioResponseInfo info, LceStatusInfo statusInfo);
 
@@ -2050,6 +2409,11 @@ interface IRadioResponse {
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:LCE_NOT_SUPPORTED
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway stopLceServiceResponse(RadioResponseInfo info, LceStatusInfo statusInfo);
 
@@ -2062,6 +2426,10 @@ interface IRadioResponse {
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:LCE_NOT_SUPPORTED
      *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway pullLceDataResponse(RadioResponseInfo info, LceDataInfo lceInfo);
 
@@ -2077,6 +2445,9 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:NOT_PROVISIONED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getModemActivityInfoResponse(RadioResponseInfo info, ActivityStatsInfo activityInfo);
 
@@ -2122,6 +2493,8 @@ interface IRadioResponse {
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway sendDeviceStateResponse(RadioResponseInfo info);
 
@@ -2136,6 +2509,8 @@ interface IRadioResponse {
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setIndicationFilterResponse(RadioResponseInfo info);
 
@@ -2147,6 +2522,10 @@ interface IRadioResponse {
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setSimCardPowerResponse(RadioResponseInfo info);
 
index 747b2f4731ee6698ea2b36703946c492b6eb859e..a81861d699a92f624e651298a88d9076dd7998af 100644 (file)
@@ -123,7 +123,8 @@ TEST_F(RadioHidlTest, setCdmaBroadcastConfig) {
 
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
+                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                    radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
@@ -140,7 +141,7 @@ TEST_F(RadioHidlTest, getCdmaBroadcastConfig) {
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(CheckGeneralError());
+        ASSERT_TRUE(CheckGeneralError() || radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
@@ -159,7 +160,8 @@ TEST_F(RadioHidlTest, setCdmaBroadcastActivation) {
 
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
+                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                    radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
index 35d97ee68667cf4efda48023039e7e225b392707..df3156325400e9d3e795666ff89af45ab91e479a 100644 (file)
@@ -98,7 +98,10 @@ TEST_F(RadioHidlTest, deactivateDataCall) {
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        EXPECT_EQ(RadioError::INVALID_CALL_ID, radioRsp->rspInfo.error);
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::INVALID_CALL_ID ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT || CheckOEMError() ||
+                    radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE);
     }
 }
 
@@ -220,6 +223,9 @@ TEST_F(RadioHidlTest, setDataProfile) {
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        // TODO(shuoq): Will add error check when we know the expected error from QC
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT ||
+                    radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
     }
 }
index 8f01d8d43b06c08e3298f473b8f03ab37eaa3fa3..9e003e2d77abe11b2746b8ece6456ca4ac310350 100644 (file)
@@ -24,299 +24,299 @@ TEST_F(RadioHidlTest, getIccCardStatus) {
     EXPECT_LT(cardStatus.gsmUmtsSubscriptionAppIndex, (int)RadioConst::CARD_MAX_APPS);
     EXPECT_LT(cardStatus.cdmaSubscriptionAppIndex, (int)RadioConst::CARD_MAX_APPS);
     EXPECT_LT(cardStatus.imsSubscriptionAppIndex, (int)RadioConst::CARD_MAX_APPS);
-}
+    }
 
-/*
- * Test IRadio.supplyIccPinForApp() for the response returned
- */
-TEST_F(RadioHidlTest, supplyIccPinForApp) {
-    int serial = GetRandomSerialNumber();
-
-    // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
-    // 3GPP2 apps only
-    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
-        if (cardStatus.applications[i].appType == AppType::SIM ||
-            cardStatus.applications[i].appType == AppType::USIM ||
-            cardStatus.applications[i].appType == AppType::RUIM ||
-            cardStatus.applications[i].appType == AppType::CSIM) {
-            radio->supplyIccPinForApp(serial, hidl_string("test1"),
-                                      cardStatus.applications[i].aidPtr);
-            EXPECT_EQ(std::cv_status::no_timeout, wait());
-            EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-            EXPECT_EQ(RadioError::PASSWORD_INCORRECT, radioRsp->rspInfo.error);
+    /*
+     * Test IRadio.supplyIccPinForApp() for the response returned
+     */
+    TEST_F(RadioHidlTest, supplyIccPinForApp) {
+        int serial = GetRandomSerialNumber();
+
+        // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
+        // 3GPP2 apps only
+        for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+            if (cardStatus.applications[i].appType == AppType::SIM ||
+                cardStatus.applications[i].appType == AppType::USIM ||
+                cardStatus.applications[i].appType == AppType::RUIM ||
+                cardStatus.applications[i].appType == AppType::CSIM) {
+                radio->supplyIccPinForApp(serial, hidl_string("test1"),
+                                          cardStatus.applications[i].aidPtr);
+                EXPECT_EQ(std::cv_status::no_timeout, wait());
+                EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+                EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+                EXPECT_EQ(RadioError::PASSWORD_INCORRECT, radioRsp->rspInfo.error);
+            }
         }
     }
-}
 
-/*
- * Test IRadio.supplyIccPukForApp() for the response returned.
- */
-TEST_F(RadioHidlTest, supplyIccPukForApp) {
-    int serial = GetRandomSerialNumber();
-
-    // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
-    // 3GPP2 apps only
-    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
-        if (cardStatus.applications[i].appType == AppType::SIM ||
-            cardStatus.applications[i].appType == AppType::USIM ||
-            cardStatus.applications[i].appType == AppType::RUIM ||
-            cardStatus.applications[i].appType == AppType::CSIM) {
-            radio->supplyIccPukForApp(serial, hidl_string("test1"), hidl_string("test2"),
-                                      cardStatus.applications[i].aidPtr);
-            EXPECT_EQ(std::cv_status::no_timeout, wait());
-            EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-            EXPECT_EQ(RadioError::PASSWORD_INCORRECT, radioRsp->rspInfo.error);
+    /*
+     * Test IRadio.supplyIccPukForApp() for the response returned.
+     */
+    TEST_F(RadioHidlTest, supplyIccPukForApp) {
+        int serial = GetRandomSerialNumber();
+
+        // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
+        // 3GPP2 apps only
+        for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+            if (cardStatus.applications[i].appType == AppType::SIM ||
+                cardStatus.applications[i].appType == AppType::USIM ||
+                cardStatus.applications[i].appType == AppType::RUIM ||
+                cardStatus.applications[i].appType == AppType::CSIM) {
+                radio->supplyIccPukForApp(serial, hidl_string("test1"), hidl_string("test2"),
+                                          cardStatus.applications[i].aidPtr);
+                EXPECT_EQ(std::cv_status::no_timeout, wait());
+                EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+                EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+                EXPECT_EQ(RadioError::PASSWORD_INCORRECT, radioRsp->rspInfo.error);
+            }
         }
     }
-}
 
-/*
- * Test IRadio.supplyIccPin2ForApp() for the response returned.
- */
-TEST_F(RadioHidlTest, supplyIccPin2ForApp) {
-    int serial = GetRandomSerialNumber();
-
-    // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
-    // 3GPP2 apps only
-    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
-        if (cardStatus.applications[i].appType == AppType::SIM ||
-            cardStatus.applications[i].appType == AppType::USIM ||
-            cardStatus.applications[i].appType == AppType::RUIM ||
-            cardStatus.applications[i].appType == AppType::CSIM) {
-            radio->supplyIccPin2ForApp(serial, hidl_string("test1"),
-                                       cardStatus.applications[i].aidPtr);
-            EXPECT_EQ(std::cv_status::no_timeout, wait());
-            EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-            EXPECT_EQ(RadioError::PASSWORD_INCORRECT, radioRsp->rspInfo.error);
+    /*
+     * Test IRadio.supplyIccPin2ForApp() for the response returned.
+     */
+    TEST_F(RadioHidlTest, supplyIccPin2ForApp) {
+        int serial = GetRandomSerialNumber();
+
+        // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
+        // 3GPP2 apps only
+        for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+            if (cardStatus.applications[i].appType == AppType::SIM ||
+                cardStatus.applications[i].appType == AppType::USIM ||
+                cardStatus.applications[i].appType == AppType::RUIM ||
+                cardStatus.applications[i].appType == AppType::CSIM) {
+                radio->supplyIccPin2ForApp(serial, hidl_string("test1"),
+                                           cardStatus.applications[i].aidPtr);
+                EXPECT_EQ(std::cv_status::no_timeout, wait());
+                EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+                EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+                EXPECT_EQ(RadioError::PASSWORD_INCORRECT, radioRsp->rspInfo.error);
+            }
         }
     }
-}
 
-/*
- * Test IRadio.supplyIccPuk2ForApp() for the response returned.
- */
-TEST_F(RadioHidlTest, supplyIccPuk2ForApp) {
-    int serial = GetRandomSerialNumber();
-
-    // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
-    // 3GPP2 apps only
-    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
-        if (cardStatus.applications[i].appType == AppType::SIM ||
-            cardStatus.applications[i].appType == AppType::USIM ||
-            cardStatus.applications[i].appType == AppType::RUIM ||
-            cardStatus.applications[i].appType == AppType::CSIM) {
-            radio->supplyIccPuk2ForApp(serial, hidl_string("test1"), hidl_string("test2"),
-                                       cardStatus.applications[i].aidPtr);
-            EXPECT_EQ(std::cv_status::no_timeout, wait());
-            EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-            EXPECT_EQ(RadioError::PASSWORD_INCORRECT, radioRsp->rspInfo.error);
+    /*
+     * Test IRadio.supplyIccPuk2ForApp() for the response returned.
+     */
+    TEST_F(RadioHidlTest, supplyIccPuk2ForApp) {
+        int serial = GetRandomSerialNumber();
+
+        // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
+        // 3GPP2 apps only
+        for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+            if (cardStatus.applications[i].appType == AppType::SIM ||
+                cardStatus.applications[i].appType == AppType::USIM ||
+                cardStatus.applications[i].appType == AppType::RUIM ||
+                cardStatus.applications[i].appType == AppType::CSIM) {
+                radio->supplyIccPuk2ForApp(serial, hidl_string("test1"), hidl_string("test2"),
+                                           cardStatus.applications[i].aidPtr);
+                EXPECT_EQ(std::cv_status::no_timeout, wait());
+                EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+                EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+                EXPECT_EQ(RadioError::PASSWORD_INCORRECT, radioRsp->rspInfo.error);
+            }
         }
     }
-}
 
-/*
- * Test IRadio.changeIccPinForApp() for the response returned.
- */
-TEST_F(RadioHidlTest, changeIccPinForApp) {
-    int serial = GetRandomSerialNumber();
-
-    // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
-    // 3GPP2 apps only
-    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
-        if (cardStatus.applications[i].appType == AppType::SIM ||
-            cardStatus.applications[i].appType == AppType::USIM ||
-            cardStatus.applications[i].appType == AppType::RUIM ||
-            cardStatus.applications[i].appType == AppType::CSIM) {
-            radio->changeIccPinForApp(serial, hidl_string("test1"), hidl_string("test2"),
-                                      cardStatus.applications[i].aidPtr);
-            EXPECT_EQ(std::cv_status::no_timeout, wait());
-            EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-            EXPECT_EQ(RadioError::PASSWORD_INCORRECT, radioRsp->rspInfo.error);
+    /*
+     * Test IRadio.changeIccPinForApp() for the response returned.
+     */
+    TEST_F(RadioHidlTest, changeIccPinForApp) {
+        int serial = GetRandomSerialNumber();
+
+        // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
+        // 3GPP2 apps only
+        for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+            if (cardStatus.applications[i].appType == AppType::SIM ||
+                cardStatus.applications[i].appType == AppType::USIM ||
+                cardStatus.applications[i].appType == AppType::RUIM ||
+                cardStatus.applications[i].appType == AppType::CSIM) {
+                radio->changeIccPinForApp(serial, hidl_string("test1"), hidl_string("test2"),
+                                          cardStatus.applications[i].aidPtr);
+                EXPECT_EQ(std::cv_status::no_timeout, wait());
+                EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+                EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+                EXPECT_EQ(RadioError::PASSWORD_INCORRECT, radioRsp->rspInfo.error);
+            }
         }
     }
-}
 
-/*
- * Test IRadio.changeIccPin2ForApp() for the response returned.
- */
-TEST_F(RadioHidlTest, changeIccPin2ForApp) {
-    int serial = GetRandomSerialNumber();
-
-    // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
-    // 3GPP2 apps only
-    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
-        if (cardStatus.applications[i].appType == AppType::SIM ||
-            cardStatus.applications[i].appType == AppType::USIM ||
-            cardStatus.applications[i].appType == AppType::RUIM ||
-            cardStatus.applications[i].appType == AppType::CSIM) {
-            radio->changeIccPin2ForApp(serial, hidl_string("test1"), hidl_string("test2"),
-                                       cardStatus.applications[i].aidPtr);
-            EXPECT_EQ(std::cv_status::no_timeout, wait());
-            EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-            EXPECT_EQ(RadioError::PASSWORD_INCORRECT, radioRsp->rspInfo.error);
+    /*
+     * Test IRadio.changeIccPin2ForApp() for the response returned.
+     */
+    TEST_F(RadioHidlTest, changeIccPin2ForApp) {
+        int serial = GetRandomSerialNumber();
+
+        // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
+        // 3GPP2 apps only
+        for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+            if (cardStatus.applications[i].appType == AppType::SIM ||
+                cardStatus.applications[i].appType == AppType::USIM ||
+                cardStatus.applications[i].appType == AppType::RUIM ||
+                cardStatus.applications[i].appType == AppType::CSIM) {
+                radio->changeIccPin2ForApp(serial, hidl_string("test1"), hidl_string("test2"),
+                                           cardStatus.applications[i].aidPtr);
+                EXPECT_EQ(std::cv_status::no_timeout, wait());
+                EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+                EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+                EXPECT_EQ(RadioError::PASSWORD_INCORRECT, radioRsp->rspInfo.error);
+            }
         }
     }
-}
 
-/*
- * Test IRadio.getImsiForApp() for the response returned.
- */
-TEST_F(RadioHidlTest, getImsiForApp) {
-    int serial = GetRandomSerialNumber();
-
-    // Check success returned while getting imsi for 3GPP and 3GPP2 apps only
-    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
-        if (cardStatus.applications[i].appType == AppType::SIM ||
-            cardStatus.applications[i].appType == AppType::USIM ||
-            cardStatus.applications[i].appType == AppType::RUIM ||
-            cardStatus.applications[i].appType == AppType::CSIM) {
-            radio->getImsiForApp(serial, cardStatus.applications[i].aidPtr);
+    /*
+     * Test IRadio.getImsiForApp() for the response returned.
+     */
+    TEST_F(RadioHidlTest, getImsiForApp) {
+        int serial = GetRandomSerialNumber();
+
+        // Check success returned while getting imsi for 3GPP and 3GPP2 apps only
+        for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+            if (cardStatus.applications[i].appType == AppType::SIM ||
+                cardStatus.applications[i].appType == AppType::USIM ||
+                cardStatus.applications[i].appType == AppType::RUIM ||
+                cardStatus.applications[i].appType == AppType::CSIM) {
+                radio->getImsiForApp(serial, cardStatus.applications[i].aidPtr);
+                EXPECT_EQ(std::cv_status::no_timeout, wait());
+                EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+                EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+                EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+
+                // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more than 15
+                if (radioRsp->rspInfo.error == RadioError::NONE) {
+                    EXPECT_NE(radioRsp->imsi, hidl_string());
+                    EXPECT_GE((int)(radioRsp->imsi).size(), 6);
+                    EXPECT_LE((int)(radioRsp->imsi).size(), 15);
+                }
+            }
+        }
+    }
+
+    /*
+     * Test IRadio.iccIOForApp() for the response returned.
+     */
+    TEST_F(RadioHidlTest, iccIOForApp) {
+        int serial = GetRandomSerialNumber();
+
+        for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+            IccIo iccIo;
+            iccIo.command = 0xc0;
+            iccIo.fileId = 0x6f11;
+            iccIo.path = hidl_string("3F007FFF");
+            iccIo.p1 = 0;
+            iccIo.p2 = 0;
+            iccIo.p3 = 0;
+            iccIo.data = hidl_string();
+            iccIo.pin2 = hidl_string();
+            iccIo.aid = cardStatus.applications[i].aidPtr;
+
+            radio->iccIOForApp(serial, iccIo);
             EXPECT_EQ(std::cv_status::no_timeout, wait());
             EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
             EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-            EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
-
-            // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more than 15
-            if (radioRsp->rspInfo.error == RadioError::NONE) {
-                EXPECT_NE(radioRsp->imsi, hidl_string());
-                EXPECT_GE((int)(radioRsp->imsi).size(), 6);
-                EXPECT_LE((int)(radioRsp->imsi).size(), 15);
-            }
         }
     }
-}
 
-/*
- * Test IRadio.iccIOForApp() for the response returned.
- */
-TEST_F(RadioHidlTest, iccIOForApp) {
-    int serial = GetRandomSerialNumber();
-
-    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
-        IccIo iccIo;
-        iccIo.command = 0xc0;
-        iccIo.fileId = 0x6f11;
-        iccIo.path = hidl_string("3F007FFF");
-        iccIo.p1 = 0;
-        iccIo.p2 = 0;
-        iccIo.p3 = 0;
-        iccIo.data = hidl_string();
-        iccIo.pin2 = hidl_string();
-        iccIo.aid = cardStatus.applications[i].aidPtr;
-
-        radio->iccIOForApp(serial, iccIo);
+    /*
+     * Test IRadio.iccTransmitApduBasicChannel() for the response returned.
+     */
+    TEST_F(RadioHidlTest, iccTransmitApduBasicChannel) {
+        int serial = GetRandomSerialNumber();
+        SimApdu msg;
+        memset(&msg, 0, sizeof(msg));
+        msg.data = hidl_string();
+
+        radio->iccTransmitApduBasicChannel(serial, msg);
         EXPECT_EQ(std::cv_status::no_timeout, wait());
         EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
         EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+        // TODO(sanketpadawe): Add test for error code
     }
-}
 
-/*
- * Test IRadio.iccTransmitApduBasicChannel() for the response returned.
- */
-TEST_F(RadioHidlTest, iccTransmitApduBasicChannel) {
-    int serial = GetRandomSerialNumber();
-    SimApdu msg;
-    memset(&msg, 0, sizeof(msg));
-    msg.data = hidl_string();
-
-    radio->iccTransmitApduBasicChannel(serial, msg);
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
-    // TODO(sanketpadawe): Add test for error code
-}
+    /*
+     * Test IRadio.iccOpenLogicalChannel() for the response returned.
+     */
+    TEST_F(RadioHidlTest, iccOpenLogicalChannel) {
+        int serial = GetRandomSerialNumber();
+        int p2 = 0x04;
+        // Specified in ISO 7816-4 clause 7.1.1 0x04 means that FCP template is requested.
+        for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+            radio->iccOpenLogicalChannel(serial, cardStatus.applications[i].aidPtr, p2);
+            EXPECT_EQ(std::cv_status::no_timeout, wait());
+            EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+        }
+    }
 
-/*
- * Test IRadio.iccOpenLogicalChannel() for the response returned.
- */
-TEST_F(RadioHidlTest, iccOpenLogicalChannel) {
-    int serial = GetRandomSerialNumber();
-    int p2 = 0x04;
-    // Specified in ISO 7816-4 clause 7.1.1 0x04 means that FCP template is requested.
-    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
-        radio->iccOpenLogicalChannel(serial, cardStatus.applications[i].aidPtr, p2);
+    /*
+     * Test IRadio.iccCloseLogicalChannel() for the response returned.
+     */
+    TEST_F(RadioHidlTest, iccCloseLogicalChannel) {
+        int serial = GetRandomSerialNumber();
+        // Try closing invalid channel and check INVALID_ARGUMENTS returned as error
+        radio->iccCloseLogicalChannel(serial, 0);
         EXPECT_EQ(std::cv_status::no_timeout, wait());
-        EXPECT_EQ(serial, radioRsp->rspInfo.serial);
         EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-    }
-}
-
-/*
- * Test IRadio.iccCloseLogicalChannel() for the response returned.
- */
-TEST_F(RadioHidlTest, iccCloseLogicalChannel) {
-    int serial = GetRandomSerialNumber();
-    // Try closing invalid channel and check INVALID_ARGUMENTS returned as error
-    radio->iccCloseLogicalChannel(serial, 0);
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
-    EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
-}
+        EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
-/*
- * Test IRadio.iccTransmitApduLogicalChannel() for the response returned.
- */
-TEST_F(RadioHidlTest, iccTransmitApduLogicalChannel) {
-    int serial = GetRandomSerialNumber();
-    SimApdu msg;
-    memset(&msg, 0, sizeof(msg));
-    msg.data = hidl_string();
-
-    radio->iccTransmitApduLogicalChannel(serial, msg);
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
-    // TODO(sanketpadawe): Add test for error code
-}
+        EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
+    }
 
-/*
- * Test IRadio.requestIccSimAuthentication() for the response returned.
- */
-TEST_F(RadioHidlTest, requestIccSimAuthentication) {
-    int serial = GetRandomSerialNumber();
+    /*
+     * Test IRadio.iccTransmitApduLogicalChannel() for the response returned.
+     */
+    TEST_F(RadioHidlTest, iccTransmitApduLogicalChannel) {
+        int serial = GetRandomSerialNumber();
+        SimApdu msg;
+        memset(&msg, 0, sizeof(msg));
+        msg.data = hidl_string();
 
-    // Pass wrong challenge string and check RadioError::INVALID_ARGUMENTS
-    // returned as error.
-    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
-        radio->requestIccSimAuthentication(serial, 0, hidl_string("test"),
-                                           cardStatus.applications[i].aidPtr);
+        radio->iccTransmitApduLogicalChannel(serial, msg);
         EXPECT_EQ(std::cv_status::no_timeout, wait());
-        EXPECT_EQ(serial, radioRsp->rspInfo.serial);
         EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-        EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
+        EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+        // TODO(sanketpadawe): Add test for error code
     }
-}
 
-/*
- * Test IRadio.supplyNetworkDepersonalization() for the response returned.
- */
-TEST_F(RadioHidlTest, supplyNetworkDepersonalization) {
-    int serial = GetRandomSerialNumber();
-
-    radio->supplyNetworkDepersonalization(serial, hidl_string("test"));
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
-    if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
-                    radioRsp->rspInfo.error == RadioError::SYSTEM_ERR ||
-                    radioRsp->rspInfo.error == RadioError::NO_MEMORY ||
-                    radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_SIM_STATE ||
-                    radioRsp->rspInfo.error == RadioError::PASSWORD_INCORRECT ||
-                    radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+    /*
+     * Test IRadio.requestIccSimAuthentication() for the response returned.
+     */
+    TEST_F(RadioHidlTest, requestIccSimAuthentication) {
+        int serial = GetRandomSerialNumber();
+
+        // Pass wrong challenge string and check RadioError::INVALID_ARGUMENTS
+        // returned as error.
+        for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+            radio->requestIccSimAuthentication(serial, 0, hidl_string("test"),
+                                               cardStatus.applications[i].aidPtr);
+            EXPECT_EQ(std::cv_status::no_timeout, wait());
+            EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+            EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
+        }
     }
+
+    /*
+     * Test IRadio.supplyNetworkDepersonalization() for the response returned.
+     */
+    TEST_F(RadioHidlTest, supplyNetworkDepersonalization) {
+        int serial = GetRandomSerialNumber();
+
+        radio->supplyNetworkDepersonalization(serial, hidl_string("test"));
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+        EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+        if (cardStatus.cardState == CardState::ABSENT) {
+            ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+                        radioRsp->rspInfo.error == RadioError::SYSTEM_ERR ||
+                        radioRsp->rspInfo.error == RadioError::NO_MEMORY ||
+                        radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
+                        radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                        radioRsp->rspInfo.error == RadioError::INVALID_SIM_STATE ||
+                        radioRsp->rspInfo.error == RadioError::PASSWORD_INCORRECT ||
+                        radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+        }
 }
index e791edeb80c2f2ffea44fb5c5b2501beb8768b2a..0507cc98f5a2cc86f1bdde6c6fa31cba17118131 100644 (file)
@@ -153,7 +153,7 @@ TEST_F(RadioHidlTest, getAvailableNetworks) {
                     radioRsp->rspInfo.error == RadioError::CANCELLED ||
                     radioRsp->rspInfo.error == RadioError::OPERATION_NOT_ALLOWED ||
                     radioRsp->rspInfo.error == RadioError::MODEM_ERR);
-    }
+  }
 }
 
 /*
@@ -184,7 +184,7 @@ TEST_F(RadioHidlTest, setBandMode) {
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        EXPECT_EQ(radioRsp->rspInfo.error, RadioError::NONE);
+        ASSERT_TRUE(CheckGeneralError() || radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
@@ -216,7 +216,7 @@ TEST_F(RadioHidlTest, setPreferredNetworkType) {
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        EXPECT_EQ(radioRsp->rspInfo.error, RadioError::NONE);
+        ASSERT_TRUE(CheckGeneralError() || radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
@@ -397,7 +397,8 @@ TEST_F(RadioHidlTest, getDeviceIdentity) {
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::EMPTY_RECORD);
     }
 }
 
@@ -657,7 +658,6 @@ TEST_F(RadioHidlTest, setRadioCapability) {
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
         ASSERT_TRUE(CheckGeneralError() ||
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
                     radioRsp->rspInfo.error == RadioError::INVALID_STATE);
@@ -676,7 +676,6 @@ TEST_F(RadioHidlTest, startLceService) {
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
         ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE ||
                     radioRsp->rspInfo.error == RadioError::LCE_NOT_SUPPORTED ||
                     radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
@@ -714,7 +713,8 @@ TEST_F(RadioHidlTest, pullLceData) {
 
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE || CheckOEMError() ||
-                    radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+                    radioRsp->rspInfo.error == RadioError::INTERNAL_ERR ||
+                    radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
@@ -755,7 +755,8 @@ TEST_F(RadioHidlTest, setAllowedCarriers) {
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        EXPECT_EQ(radioRsp->rspInfo.error, RadioError::NONE);
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
     }
 
     /* Reset back to no carrier restriction */
@@ -769,7 +770,8 @@ TEST_F(RadioHidlTest, setAllowedCarriers) {
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        EXPECT_EQ(radioRsp->rspInfo.error, RadioError::NONE);
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
     }
 }
 
@@ -840,8 +842,7 @@ TEST_F(RadioHidlTest, setSimCardPower) {
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
         ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
                     radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
     }
-}
+}
\ No newline at end of file
index 4c7655914be6099aec13bfa9a32796a2465586eb..f97f5febd6ee4e9b4d90173f49f1679b2ffbf071 100644 (file)
@@ -37,24 +37,8 @@ TEST_F(RadioHidlTest, sendEnvelope) {
         std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
         ASSERT_TRUE(CheckGeneralError() ||
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::NONE);
-    }
-
-    // Test with sending random string
-    serial = GetRandomSerialNumber();
-    content = "0";
-
-    radio->sendEnvelope(serial, content);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
-    if (cardStatus.cardState == CardState::ABSENT) {
-        std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
-        ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::NONE);
+                    radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
     }
 }
 
@@ -79,23 +63,6 @@ TEST_F(RadioHidlTest, sendTerminalResponseToSim) {
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
                     radioRsp->rspInfo.error == RadioError::NONE);
     }
-
-    serial = GetRandomSerialNumber();
-
-    // Test with sending random string
-    commandResponse = "0";
-
-    radio->sendTerminalResponseToSim(serial, commandResponse);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
-    if (cardStatus.cardState == CardState::ABSENT) {
-        std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
-        ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
-    }
 }
 
 /*
@@ -112,8 +79,7 @@ TEST_F(RadioHidlTest, handleStkCallSetupRequestFromSim) {
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::NONE ||
+        ASSERT_TRUE(CheckGeneralError() || radioRsp->rspInfo.error == RadioError::NONE ||
                     radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
     }
@@ -132,8 +98,7 @@ TEST_F(RadioHidlTest, reportStkServiceIsRunning) {
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::NONE);
+        ASSERT_TRUE(CheckGeneralError() || radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
@@ -155,21 +120,7 @@ TEST_F(RadioHidlTest, sendEnvelopeWithStatus) {
 
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
-    }
-
-    // Test with sending random string
-    serial = GetRandomSerialNumber();
-    contents = "0";
-
-    radio->sendEnvelopeWithStatus(serial, contents);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
-    if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
+                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
     }
 }
index 5f2815562f86da5bf821b6c328ba4b882cb89871..ed2c6bb6ab0a688f8fd9de5f0da08c323af2751a 100644 (file)
@@ -37,6 +37,10 @@ void RadioHidlTest::SetUp() {
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
     EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+
+    /* Vts Testing with Sim Absent only. This needs to be removed later in P when sim present
+     * scenarios will be tested. */
+    EXPECT_EQ(CardState::ABSENT, cardStatus.cardState);
 }
 
 void RadioHidlTest::TearDown() {}
index db0fb7b7e1340bf1629f5a6276983fc5fc4819cc..8d6e200f273b0217c4b4ac9e24bcb826fc291ff6 100644 (file)
@@ -57,7 +57,7 @@ TEST_F(RadioHidlTest, dial) {
                     radioRsp->rspInfo.error == RadioError::NO_NETWORK_FOUND ||
                     radioRsp->rspInfo.error == RadioError::INVALID_CALL_ID ||
                     radioRsp->rspInfo.error == RadioError::DEVICE_IN_USE ||
-                    radioRsp->rspInfo.error == RadioError::MODE_NOT_SUPPORTED ||
+                    radioRsp->rspInfo.error == RadioError::OPERATION_NOT_ALLOWED ||
                     radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE ||
                     radioRsp->rspInfo.error == RadioError::CANCELLED);
     }
@@ -214,7 +214,8 @@ TEST_F(RadioHidlTest, cancelPendingUssd) {
 
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() || radioRsp->rspInfo.error == RadioError::INVALID_STATE ||
-                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
+                    radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
+                    radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
@@ -365,13 +366,13 @@ TEST_F(RadioHidlTest, sendCDMAFeatureCode) {
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
         ASSERT_TRUE(CheckGeneralError() ||
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
                     radioRsp->rspInfo.error == RadioError::NONE ||
                     radioRsp->rspInfo.error == RadioError::INVALID_CALL_ID ||
                     radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE ||
-                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
+                    radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
+                    radioRsp->rspInfo.error == RadioError::OPERATION_NOT_ALLOWED);
     }
 }
 
@@ -486,6 +487,6 @@ TEST_F(RadioHidlTest, sendBurstDtmf) {
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
                     radioRsp->rspInfo.error == RadioError::INVALID_STATE ||
                     radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
-                    radioRsp->rspInfo.error == RadioError::MODE_NOT_SUPPORTED);
+                    radioRsp->rspInfo.error == RadioError::OPERATION_NOT_ALLOWED);
     }
 }
\ No newline at end of file
index fc8cb2af5158fb5146c3d5c67b2dc40a40a82d54..772050548bccd52deca77fc2077cd9159e5d9bc4 100644 (file)
@@ -34,19 +34,19 @@ void SapHidlTest::notify() {
     std::unique_lock<std::mutex> lock(mtx);
     count++;
     cv.notify_one();
-}
+    }
 
-std::cv_status SapHidlTest::wait() {
-    std::unique_lock<std::mutex> lock(mtx);
+    std::cv_status SapHidlTest::wait() {
+        std::unique_lock<std::mutex> lock(mtx);
 
-    std::cv_status status = std::cv_status::no_timeout;
-    auto now = std::chrono::system_clock::now();
-    while (count == 0) {
-        status = cv.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
-        if (status == std::cv_status::timeout) {
-            return status;
+        std::cv_status status = std::cv_status::no_timeout;
+        auto now = std::chrono::system_clock::now();
+        while (count == 0) {
+            status = cv.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
+            if (status == std::cv_status::timeout) {
+                return status;
+            }
         }
-    }
-    count--;
-    return status;
-}
\ No newline at end of file
+        count--;
+        return status;
+    }
\ No newline at end of file
index a8d836c88c505491893a51660f7df636d1255a70..93d5d44a1c51600350152e0e949a5f66f83f630b 100644 (file)
@@ -176,26 +176,6 @@ struct NetworkScanResult {
     vec<CellInfo> networkInfos;             // List of network information as CellInfo
 };
 
-struct ImsiEncryptionInfo {
-    string mcc;                   // MCC of the Carrier.
-    string mnc;                   // MNC of the Carrier.
-    vec<uint8_t> carrierKey;      // Carrier specific key to be used for encryption. It must
-                                  // be opaque to the framework. This is the byte-stream
-                                  // representation of the key. This is an external encoded
-                                  // form for the key used when a standard representation of
-                                  // the key is needed outside the Java Virtual Machine, as
-                                  // when transmitting the key to some other party.
-                                  // The key is encoded according to a standard format
-                                  // (such as X.509 SubjectPublicKeyInfo or PKCS#8), and is
-                                  // returned using the getEncoded method as defined on the
-                                  // java.security.Key interface.
-    string keyIdentifier;         // This is an opaque value we're given by the carrier
-                                  // and is returned to the carrier. This is used by the server to
-                                  // help it locate the private key to decrypt the permanent
-                                  // identity.
-    int64_t expirationTime;       // date-time in UTC when the key will expire.
-};
-
 struct KeepaliveRequest {
     KeepaliveType type;                     // The format of the keepalive packet
     vec<uint8_t> sourceAddress;             // source address with type = family, in network
@@ -216,3 +196,23 @@ struct KeepaliveStatus {
     int32_t sessionHandle;                  // the sessionHandle provided by the api
     KeepaliveStatusCode code;               // status for the given keepalive
 };
+
+struct ImsiEncryptionInfo {
+    string mcc;                   // MCC of the Carrier.
+    string mnc;                   // MNC of the Carrier.
+    vec<uint8_t> carrierKey;      // Carrier specific key to be used for encryption. It must
+                                  // be opaque to the framework. This is the byte-stream
+                                  // representation of the key. This is an external encoded
+                                  // form for the key used when a standard representation of
+                                  // the key is needed outside the Java Virtual Machine, as
+                                  // when transmitting the key to some other party.
+                                  // The key is encoded according to a standard format
+                                  // (such as X.509 SubjectPublicKeyInfo or PKCS#8), and is
+                                  // returned using the getEncoded method as defined on the
+                                  // java.security.Key interface.
+    string keyIdentifier;         // This is an opaque value we're given by the carrier
+                                  // and is returned to the carrier. This is used by the server to
+                                  // help it locate the private key to decrypt the permanent
+                                  // identity.
+    int64_t expirationTime;       // date-time in UTC when the key will expire.
+};
index 075d54359fdcfdeee5592c13b27e68ab3c56bc90..e7195ee7da56a898c065b244a511123e09ff037c 100644 (file)
@@ -31,4 +31,3 @@ cc_test {
         "radio.util.header@1.0",
     ],
 }
-
index 9676c5c3589016709640fd25ffe8ad0888aafae2..10f8f62a503af915d60afd2f919f615638370f9a 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <radio_hidl_hal_utils_v1_1.h>
+#include <vector>
 
 /*
  * Test IRadio.setSimCardPower() for the response returned.
@@ -135,3 +136,115 @@ TEST_F(RadioHidlTest_v1_1, setCarrierInfoForImsiEncryption) {
                     radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
     }
 }
+
+/*
+ * Test IRadio.startKeepalive() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_1, startKeepalive) {
+    std::vector<KeepaliveRequest> requests = {
+        {
+            // Invalid IPv4 source address
+            KeepaliveType::NATT_IPV4,
+            {192, 168, 0 /*, 100*/},
+            1234,
+            {8, 8, 4, 4},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid IPv4 destination address
+            KeepaliveType::NATT_IPV4,
+            {192, 168, 0, 100},
+            1234,
+            {8, 8, 4, 4, 1, 2, 3, 4},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid Keepalive Type
+            static_cast<KeepaliveType>(-1),
+            {192, 168, 0, 100},
+            1234,
+            {8, 8, 4, 4},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid IPv6 source address
+            KeepaliveType::NATT_IPV6,
+            {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xED,
+             0xBE, 0xEF, 0xBD},
+            1234,
+            {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+             0x88, 0x44},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid IPv6 destination address
+            KeepaliveType::NATT_IPV6,
+            {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xED,
+             0xBE, 0xEF},
+            1234,
+            {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+             0x88,
+             /*0x44*/},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid Context ID (cid), this should survive the initial
+            // range checking and fail in the modem data layer
+            KeepaliveType::NATT_IPV4,
+            {192, 168, 0, 100},
+            1234,
+            {8, 8, 4, 4},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid Context ID (cid), this should survive the initial
+            // range checking and fail in the modem data layer
+            KeepaliveType::NATT_IPV6,
+            {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xED,
+             0xBE, 0xEF},
+            1234,
+            {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+             0x88, 0x44},
+            4500,
+            20000,
+            0xBAD,
+        }};
+
+    for (auto req = requests.begin(); req != requests.end(); req++) {
+        int serial = GetRandomSerialNumber();
+        radio_v1_1->startKeepalive(serial, *req);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
+        EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
+
+        ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                    radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+    }
+}
+
+/*
+ * Test IRadio.stopKeepalive() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_1, stopKeepalive) {
+    int serial = GetRandomSerialNumber();
+
+    radio_v1_1->stopKeepalive(serial, 0xBAD);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
+
+    ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+}
index b009dba9993fd167ad08bb4f6c8fee6d7b3e639c..e0b1ad4bc9feb4c6acdfa1254abc999ef36d64d7 100644 (file)
@@ -38,6 +38,10 @@ void RadioHidlTest_v1_1::SetUp() {
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
     EXPECT_EQ(RadioError::NONE, radioRsp_v1_1->rspInfo.error);
+
+    /* Vts Testing with Sim Absent only. This needs to be removed later in P when sim present
+     * scenarios will be tested. */
+    EXPECT_EQ(CardState::ABSENT, cardStatus.cardState);
 }
 
 void RadioHidlTest_v1_1::TearDown() {}
@@ -75,4 +79,4 @@ bool RadioHidlTest_v1_1::CheckGeneralError() {
 bool RadioHidlTest_v1_1::CheckOEMError() {
     return (radioRsp_v1_1->rspInfo.error >= RadioError::OEM_ERROR_1 &&
             radioRsp_v1_1->rspInfo.error <= RadioError::OEM_ERROR_25);
-}
\ No newline at end of file
+}
index dd4f1efc0f15e9ee1fe496e6e620a2fa2c523c53..c797e352bdb8f3d0e59c856836611ee1d2e4638e 100644 (file)
@@ -53,6 +53,7 @@ class RadioResponse_v1_1 : public ::android::hardware::radio::V1_1::IRadioRespon
     hidl_string imsi;
     IccIoResult iccIoResult;
     int channelId;
+    KeepaliveStatus keepaliveStatus;
 
     // Sms
     SendSmsResult sendSmsResult;
@@ -567,4 +568,4 @@ class RadioHidlEnvironment : public ::testing::Environment {
    public:
     virtual void SetUp() {}
     virtual void TearDown() {}
-};
\ No newline at end of file
+};
index 407b4640dbdf995918f977852bfcb0fa6dcaa6a6..400ef3c00138031ed6a7717b9dc7fddf7f0eee71 100644 (file)
@@ -683,11 +683,16 @@ Return<void> RadioResponse_v1_1::stopNetworkScanResponse(const RadioResponseInfo
     return Void();
 }
 
-Return<void> RadioResponse_v1_1::startKeepaliveResponse(const RadioResponseInfo& /*info*/,
-                                                        const KeepaliveStatus& /*status*/) {
+Return<void> RadioResponse_v1_1::startKeepaliveResponse(const RadioResponseInfo& info,
+                                                        const KeepaliveStatus& status) {
+    rspInfo = info;
+    keepaliveStatus = status;
+    parent_v1_1.notify();
     return Void();
 }
 
-Return<void> RadioResponse_v1_1::stopKeepaliveResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_1::stopKeepaliveResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_1.notify();
     return Void();
-}
\ No newline at end of file
+}
index 635e2e66c0e2c720c90bc99dea6294e2318b5f70..5256c1f9da397d579e1a96e652ce4cda81b4b0cd 100644 (file)
@@ -32,6 +32,7 @@ cc_test {
         "libhidltransport",
         "libnativehelper",
         "libutils",
+        "libnativewindow",
         "android.hardware.renderscript@1.0",
     ],
     static_libs: ["VtsHalHidlTargetTestBase"],
index 4b50f111ac877fd26b735c6994b615ab0b8bed95..f3c7021ca8971e59330b224a6d337f30dbd56620 100644 (file)
@@ -1,5 +1,7 @@
 // This is an autogenerated file, do not edit.
 subdirs = [
     "config/1.0",
+    "config/1.0/vts/functional",
     "control/1.0",
+    "control/1.0/vts/functional",
 ]
diff --git a/tetheroffload/config/1.0/vts/functional/Android.bp b/tetheroffload/config/1.0/vts/functional/Android.bp
new file mode 100644 (file)
index 0000000..2e720c6
--- /dev/null
@@ -0,0 +1,33 @@
+// 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.
+
+cc_test {
+    name: "VtsHalTetheroffloadConfigV1_0TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalTetheroffloadConfigV1_0TargetTest.cpp"],
+    shared_libs: [
+        "android.hardware.tetheroffload.config@1.0",
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp b/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp
new file mode 100644 (file)
index 0000000..fc61e1c
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * 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 "VtsOffloadConfigV1_0TargetTest"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <log/log.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <set>
+
+using android::base::StringPrintf;
+using android::base::unique_fd;
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::Return;
+using android::hardware::tetheroffload::config::V1_0::IOffloadConfig;
+using android::hardware::Void;
+using android::sp;
+
+#define ASSERT_TRUE_CALLBACK \
+    [&](bool success, const hidl_string& errMsg) { ASSERT_TRUE(success) << errMsg.c_str(); }
+
+#define ASSERT_FALSE_CALLBACK \
+    [&](bool success, const hidl_string& errMsg) { ASSERT_FALSE(success) << errMsg.c_str(); }
+
+const unsigned kFd1Groups = NFNLGRP_CONNTRACK_NEW | NFNLGRP_CONNTRACK_DESTROY;
+const unsigned kFd2Groups = NFNLGRP_CONNTRACK_UPDATE | NFNLGRP_CONNTRACK_DESTROY;
+
+inline const sockaddr* asSockaddr(const sockaddr_nl* nladdr) {
+    return reinterpret_cast<const sockaddr*>(nladdr);
+}
+
+int netlinkSocket(int protocol, unsigned groups) {
+    unique_fd s(socket(AF_NETLINK, SOCK_DGRAM, protocol));
+    if (s.get() < 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl bind_addr = {
+        .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+    };
+    if (::bind(s.get(), asSockaddr(&bind_addr), sizeof(bind_addr)) != 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl kernel_addr = {
+        .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+    };
+    if (::connect(s.get(), asSockaddr(&kernel_addr), sizeof(kernel_addr)) != 0) {
+        return -errno;
+    }
+
+    return s.release();
+}
+
+int netlinkSocket(unsigned groups) {
+    return netlinkSocket(NETLINK_NETFILTER, groups);
+}
+
+class OffloadConfigHidlTest : public testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        config = testing::VtsHalHidlTargetTestBase::getService<IOffloadConfig>();
+        ASSERT_NE(nullptr, config.get()) << "Could not get HIDL instance";
+    }
+
+    virtual void TearDown() override {}
+
+    sp<IOffloadConfig> config;
+};
+
+// Ensure handles can be set with correct socket options.
+TEST_F(OffloadConfigHidlTest, TestSetHandles) {
+    unique_fd fd1(netlinkSocket(kFd1Groups));
+    if (fd1.get() < 0) {
+        ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+        FAIL();
+    }
+    native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
+    nativeHandle1->data[0] = fd1.release();
+    const hidl_handle h1 = hidl_handle(nativeHandle1);
+
+    unique_fd fd2(netlinkSocket(kFd2Groups));
+    if (fd2.get() < 0) {
+        ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+        FAIL();
+    }
+    native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
+    nativeHandle2->data[0] = fd2.release();
+    const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+    const Return<void> ret = config->setHandles(h1, h2, ASSERT_TRUE_CALLBACK);
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Passing a handle without an associated file descriptor should return an error
+// (e.g. "Failed Input Checks"). Check that this occurs when both FDs are empty.
+TEST_F(OffloadConfigHidlTest, TestSetHandleNone) {
+    native_handle_t* const nativeHandle1 = native_handle_create(0, 0);
+    const hidl_handle h1 = hidl_handle(nativeHandle1);
+    native_handle_t* const nativeHandle2 = native_handle_create(0, 0);
+    const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+    const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Passing a handle without an associated file descriptor should return an error
+// (e.g. "Failed Input Checks"). Check that this occurs when FD2 is empty.
+TEST_F(OffloadConfigHidlTest, TestSetHandle1Only) {
+    unique_fd fd1(netlinkSocket(kFd1Groups));
+    if (fd1.get() < 0) {
+        ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+        FAIL();
+    }
+    native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
+    nativeHandle1->data[0] = fd1.release();
+    const hidl_handle h1 = hidl_handle(nativeHandle1);
+
+    native_handle_t* const nativeHandle2 = native_handle_create(0, 0);
+    const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+    const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Passing a handle without an associated file descriptor should return an error
+// (e.g. "Failed Input Checks"). Check that this occurs when FD1 is empty.
+TEST_F(OffloadConfigHidlTest, TestSetHandle2OnlyNotOk) {
+    native_handle_t* const nativeHandle1 = native_handle_create(0, 0);
+    const hidl_handle h1 = hidl_handle(nativeHandle1);
+
+    unique_fd fd2(netlinkSocket(kFd2Groups));
+    if (fd2.get() < 0) {
+        ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+        FAIL();
+    }
+    native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
+    nativeHandle2->data[0] = fd2.release();
+    const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+    const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
+    ASSERT_TRUE(ret.isOk());
+}
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGE("Test result with status=%d", status);
+    return status;
+}
diff --git a/tetheroffload/control/1.0/vts/functional/Android.bp b/tetheroffload/control/1.0/vts/functional/Android.bp
new file mode 100644 (file)
index 0000000..69fac6e
--- /dev/null
@@ -0,0 +1,34 @@
+// 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.
+
+cc_test {
+    name: "VtsHalTetheroffloadControlV1_0TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalTetheroffloadControlV1_0TargetTest.cpp"],
+    shared_libs: [
+        "android.hardware.tetheroffload.config@1.0",
+        "android.hardware.tetheroffload.control@1.0",
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
new file mode 100644 (file)
index 0000000..3059eac
--- /dev/null
@@ -0,0 +1,625 @@
+/*
+ * 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 "VtsOffloadControlV1_0TargetTest"
+
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
+#include <android/hardware/tetheroffload/control/1.0/IOffloadControl.h>
+#include <android/hardware/tetheroffload/control/1.0/types.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netlink.h>
+#include <log/log.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <set>
+
+using android::base::StringPrintf;
+using android::base::unique_fd;
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::tetheroffload::config::V1_0::IOffloadConfig;
+using android::hardware::tetheroffload::control::V1_0::IOffloadControl;
+using android::hardware::tetheroffload::control::V1_0::IPv4AddrPortPair;
+using android::hardware::tetheroffload::control::V1_0::ITetheringOffloadCallback;
+using android::hardware::tetheroffload::control::V1_0::OffloadCallbackEvent;
+using android::hardware::tetheroffload::control::V1_0::NatTimeoutUpdate;
+using android::hardware::tetheroffload::control::V1_0::NetworkProtocol;
+using android::hardware::Void;
+using android::sp;
+
+// We use #defines here so as to get local lamba captures and error message line numbers
+#define ASSERT_TRUE_CALLBACK                            \
+    [&](bool success, std::string errMsg) {             \
+        if (!success) {                                 \
+            ALOGI("Error message: %s", errMsg.c_str()); \
+        }                                               \
+        ASSERT_TRUE(success);                           \
+    }
+
+#define ASSERT_FALSE_CALLBACK                           \
+    [&](bool success, std::string errMsg) {             \
+        if (!success) {                                 \
+            ALOGI("Error message: %s", errMsg.c_str()); \
+        }                                               \
+        ASSERT_FALSE(success);                          \
+    }
+
+#define ASSERT_ZERO_BYTES_CALLBACK            \
+    [&](uint64_t rxBytes, uint64_t txBytes) { \
+        EXPECT_EQ(0ULL, rxBytes);             \
+        EXPECT_EQ(0ULL, txBytes);             \
+    }
+
+inline const sockaddr* asSockaddr(const sockaddr_nl* nladdr) {
+    return reinterpret_cast<const sockaddr*>(nladdr);
+}
+
+int conntrackSocket(unsigned groups) {
+    unique_fd s(socket(AF_NETLINK, SOCK_DGRAM, NETLINK_NETFILTER));
+    if (s.get() < 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl bind_addr = {
+        .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+    };
+    if (::bind(s.get(), asSockaddr(&bind_addr), sizeof(bind_addr)) < 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl kernel_addr = {
+        .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+    };
+    if (connect(s.get(), asSockaddr(&kernel_addr), sizeof(kernel_addr)) != 0) {
+        return -errno;
+    }
+
+    return s.release();
+}
+
+constexpr char kCallbackOnEvent[] = "onEvent";
+constexpr char kCallbackUpdateTimeout[] = "updateTimeout";
+
+class TetheringOffloadCallbackArgs {
+   public:
+    OffloadCallbackEvent last_event;
+    NatTimeoutUpdate last_params;
+};
+
+class OffloadControlHidlTestBase : public testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        setupConfigHal();
+        prepareControlHal();
+    }
+
+    virtual void TearDown() override { stopOffload(false); }
+
+    // The IOffloadConfig HAL is tested more thoroughly elsewhere. He we just
+    // setup everything correctly and verify basic readiness.
+    void setupConfigHal() {
+        config = testing::VtsHalHidlTargetTestBase::getService<IOffloadConfig>();
+        ASSERT_NE(nullptr, config.get()) << "Could not get HIDL instance";
+
+        unique_fd fd1(conntrackSocket(NFNLGRP_CONNTRACK_NEW | NFNLGRP_CONNTRACK_DESTROY));
+        if (fd1.get() < 0) {
+            ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+            FAIL();
+        }
+        native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
+        nativeHandle1->data[0] = fd1.release();
+        hidl_handle h1 = hidl_handle(nativeHandle1);
+
+        unique_fd fd2(conntrackSocket(NFNLGRP_CONNTRACK_UPDATE | NFNLGRP_CONNTRACK_DESTROY));
+        if (fd2.get() < 0) {
+            ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+            FAIL();
+        }
+        native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
+        nativeHandle2->data[0] = fd2.release();
+        hidl_handle h2 = hidl_handle(nativeHandle2);
+
+        const Return<void> ret = config->setHandles(h1, h2, ASSERT_TRUE_CALLBACK);
+        ASSERT_TRUE(ret.isOk());
+    }
+
+    void prepareControlHal() {
+        control = testing::VtsHalHidlTargetTestBase::getService<IOffloadControl>();
+        ASSERT_NE(nullptr, control.get()) << "Could not get HIDL instance";
+
+        control_cb = new TetheringOffloadCallback();
+        ASSERT_NE(nullptr, control_cb.get()) << "Could not get get offload callback";
+    }
+
+    void initOffload(const bool expected_result) {
+        auto init_cb = [&](bool success, std::string errMsg) {
+            if (!success) {
+                ALOGI("Error message: %s", errMsg.c_str());
+            }
+            ASSERT_EQ(expected_result, success);
+        };
+        const Return<void> ret = control->initOffload(control_cb, init_cb);
+        ASSERT_TRUE(ret.isOk());
+    }
+
+    void setupControlHal() {
+        prepareControlHal();
+        initOffload(true);
+    }
+
+    void stopOffload(const bool expected_result) {
+        auto cb = [&](bool success, const hidl_string& errMsg) {
+            if (!success) {
+                ALOGI("Error message: %s", errMsg.c_str());
+            }
+            ASSERT_EQ(expected_result, success);
+        };
+        const Return<void> ret = control->stopOffload(cb);
+        ASSERT_TRUE(ret.isOk());
+    }
+
+    // Callback class for both events and NAT timeout updates.
+    class TetheringOffloadCallback
+        : public testing::VtsHalHidlTargetCallbackBase<TetheringOffloadCallbackArgs>,
+          public ITetheringOffloadCallback {
+       public:
+        TetheringOffloadCallback() = default;
+        virtual ~TetheringOffloadCallback() = default;
+
+        Return<void> onEvent(OffloadCallbackEvent event) override {
+            const TetheringOffloadCallbackArgs args{.last_event = event};
+            NotifyFromCallback(kCallbackOnEvent, args);
+            return Void();
+        };
+
+        Return<void> updateTimeout(const NatTimeoutUpdate& params) override {
+            const TetheringOffloadCallbackArgs args{.last_params = params};
+            NotifyFromCallback(kCallbackUpdateTimeout, args);
+            return Void();
+        };
+    };
+
+    sp<IOffloadConfig> config;
+    sp<IOffloadControl> control;
+    sp<TetheringOffloadCallback> control_cb;
+};
+
+// Call initOffload() multiple times. Check that non-first initOffload() calls return false.
+TEST_F(OffloadControlHidlTestBase, AdditionalInitsWithoutStopReturnFalse) {
+    initOffload(true);
+    initOffload(false);
+    initOffload(false);
+    initOffload(false);
+    stopOffload(true);  // balance out initOffload(true)
+}
+
+// Check that calling stopOffload() without first having called initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, MultipleStopsWithoutInitReturnFalse) {
+    stopOffload(false);
+    stopOffload(false);
+    stopOffload(false);
+}
+
+// Check that calling stopOffload() after a complete init/stop cycle returns false.
+TEST_F(OffloadControlHidlTestBase, AdditionalStopsWithInitReturnFalse) {
+    initOffload(true);
+    stopOffload(true);  // balance out initOffload(true)
+    stopOffload(false);
+    stopOffload(false);
+}
+
+// Check that calling setLocalPrefixes() without first having called initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, SetLocalPrefixesWithoutInitReturnsFalse) {
+    const vector<hidl_string> prefixes{hidl_string("2001:db8::/64")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling getForwardedStats() without first having called initOffload()
+// returns zero bytes statistics.
+TEST_F(OffloadControlHidlTestBase, GetForwardedStatsWithoutInitReturnsZeroValues) {
+    const hidl_string upstream("rmnet_data0");
+    const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling setDataLimit() without first having called initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, SetDataLimitWithoutInitReturnsFalse) {
+    const hidl_string upstream("rmnet_data0");
+    const uint64_t limit = 5000ULL;
+    const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling setUpstreamParameters() without first having called initOffload()
+// returns false.
+TEST_F(OffloadControlHidlTestBase, SetUpstreamParametersWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.0/24");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling addDownstream() with an IPv4 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, AddIPv4DownstreamWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string prefix("192.0.2.0/24");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling addDownstream() with an IPv6 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, AddIPv6DownstreamWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string prefix("2001:db8::/64");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling removeDownstream() with an IPv4 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, RemoveIPv4DownstreamWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string prefix("192.0.2.0/24");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling removeDownstream() with an IPv6 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, RemoveIPv6DownstreamWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string prefix("2001:db8::/64");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+class OffloadControlHidlTest : public OffloadControlHidlTestBase {
+   public:
+    virtual void SetUp() override {
+        setupConfigHal();
+        setupControlHal();
+    }
+
+    virtual void TearDown() override { stopOffload(true); }
+};
+
+/*
+ * Tests for IOffloadControl::setLocalPrefixes().
+ */
+
+// Test setLocalPrefixes() accepts an IPv4 address.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv4AddressOk) {
+    const vector<hidl_string> prefixes{hidl_string("192.0.2.1")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test setLocalPrefixes() accepts an IPv6 address.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv6AddressOk) {
+    const vector<hidl_string> prefixes{hidl_string("fe80::1")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test setLocalPrefixes() accepts both IPv4 and IPv6 prefixes.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv4v6PrefixesOk) {
+    const vector<hidl_string> prefixes{hidl_string("192.0.2.0/24"), hidl_string("fe80::/64")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test that setLocalPrefixes() fails given empty input. There is always
+// a non-empty set of local prefixes; when all networking interfaces are down
+// we still apply {127.0.0.0/8, ::1/128, fe80::/64} here.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesEmptyFails) {
+    const vector<hidl_string> prefixes{};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test setLocalPrefixes() fails on incorrectly formed input strings.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesInvalidFails) {
+    const vector<hidl_string> prefixes{hidl_string("192.0.2.0/24"), hidl_string("invalid")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+/*
+ * Tests for IOffloadControl::getForwardedStats().
+ */
+
+// Test that getForwardedStats() for a non-existent upstream yields zero bytes statistics.
+TEST_F(OffloadControlHidlTest, GetForwardedStatsInvalidUpstreamIface) {
+    const hidl_string upstream("invalid");
+    const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, GetForwardedStatsDummyIface) {
+    const hidl_string upstream("rmnet_data0");
+    const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+/*
+ * Tests for IOffloadControl::setDataLimit().
+ */
+
+// Test that setDataLimit() for an empty interface name fails.
+TEST_F(OffloadControlHidlTest, SetDataLimitEmptyUpstreamIfaceFails) {
+    const hidl_string upstream("");
+    const uint64_t limit = 5000ULL;
+    const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetDataLimitNonZeroOk) {
+    const hidl_string upstream("rmnet_data0");
+    const uint64_t limit = 5000ULL;
+    const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetDataLimitZeroOk) {
+    const hidl_string upstream("rmnet_data0");
+    const uint64_t limit = 0ULL;
+    const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+/*
+ * Tests for IOffloadControl::setUpstreamParameters().
+ */
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv6OnlyOk) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("");
+    const hidl_string v4Gw("");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8:2")};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersAlternateIPv6OnlyOk) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr;
+    const hidl_string v4Gw;
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8:3")};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv4OnlyOk) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.2");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv4v6Ok) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.2");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8:2")};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test that setUpstreamParameters() fails when all parameters are empty.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersEmptyFails) {
+    const hidl_string iface("");
+    const hidl_string v4Addr("");
+    const hidl_string v4Gw("");
+    const vector<hidl_string> v6Gws{};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test that setUpstreamParameters() fails when given empty or non-existent interface names.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersBogusIfaceFails) {
+    const hidl_string v4Addr("192.0.2.2");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+    for (const auto& bogus : {"", "invalid"}) {
+        SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
+        const hidl_string iface(bogus);
+        const Return<void> ret =
+            control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv4 addresses.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersInvalidIPv4AddrFails) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+    for (const auto& bogus : {"invalid", "192.0.2"}) {
+        SCOPED_TRACE(StringPrintf("v4addr='%s'", bogus));
+        const hidl_string v4Addr(bogus);
+        const Return<void> ret =
+            control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv4 gateways.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersInvalidIPv4GatewayFails) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.2");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+    for (const auto& bogus : {"invalid", "192.0.2"}) {
+        SCOPED_TRACE(StringPrintf("v4gateway='%s'", bogus));
+        const hidl_string v4Gw(bogus);
+        const Return<void> ret =
+            control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv6 gateways.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersBadIPv6GatewaysFail) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.2");
+    const hidl_string v4Gw("192.0.2.1");
+    for (const auto& bogus : {"", "invalid", "fe80::bogus", "192.0.2.66"}) {
+        SCOPED_TRACE(StringPrintf("v6gateway='%s'", bogus));
+        const vector<hidl_string> v6Gws{hidl_string("fe80::1"), hidl_string(bogus)};
+        const Return<void> ret =
+            control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+/*
+ * Tests for IOffloadControl::addDownstream().
+ */
+
+// Test addDownstream() works given an IPv4 prefix.
+TEST_F(OffloadControlHidlTest, AddDownstreamIPv4) {
+    const hidl_string iface("dummy0");
+    const hidl_string prefix("192.0.2.0/24");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test addDownstream() works given an IPv6 prefix.
+TEST_F(OffloadControlHidlTest, AddDownstreamIPv6) {
+    const hidl_string iface("dummy0");
+    const hidl_string prefix("2001:db8::/64");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test addDownstream() fails given all empty parameters.
+TEST_F(OffloadControlHidlTest, AddDownstreamEmptyFails) {
+    const hidl_string iface("");
+    const hidl_string prefix("");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test addDownstream() fails given empty or non-existent interface names.
+TEST_F(OffloadControlHidlTest, AddDownstreamInvalidIfaceFails) {
+    const hidl_string prefix("192.0.2.0/24");
+    for (const auto& bogus : {"", "invalid"}) {
+        SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
+        const hidl_string iface(bogus);
+        const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test addDownstream() fails given unparseable prefix arguments.
+TEST_F(OffloadControlHidlTest, AddDownstreamBogusPrefixFails) {
+    const hidl_string iface("dummy0");
+    for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
+        SCOPED_TRACE(StringPrintf("prefix='%s'", bogus));
+        const hidl_string prefix(bogus);
+        const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+/*
+ * Tests for IOffloadControl::removeDownstream().
+ */
+
+// Test removeDownstream() works given an IPv4 prefix.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamIPv4) {
+    const hidl_string iface("dummy0");
+    const hidl_string prefix("192.0.2.0/24");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test removeDownstream() works given an IPv6 prefix.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamIPv6) {
+    const hidl_string iface("dummy0");
+    const hidl_string prefix("2001:db8::/64");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test removeDownstream() fails given all empty parameters.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamEmptyFails) {
+    const hidl_string iface("");
+    const hidl_string prefix("");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test removeDownstream() fails given empty or non-existent interface names.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamBogusIfaceFails) {
+    const hidl_string prefix("192.0.2.0/24");
+    for (const auto& bogus : {"", "invalid"}) {
+        SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
+        const hidl_string iface(bogus);
+        const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test removeDownstream() fails given unparseable prefix arguments.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamBogusPrefixFails) {
+    const hidl_string iface("dummy0");
+    for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
+        SCOPED_TRACE(StringPrintf("prefix='%s'", bogus));
+        const hidl_string prefix(bogus);
+        const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGE("Test result with status=%d", status);
+    return status;
+}
index 3989c94bcf9352f5b571984ee3569020fe2d1be5..dfa11a1dc177c2e79910d3d0c11e2bb879615334 100644 (file)
@@ -68,10 +68,12 @@ class ThermalHidlTest : public ::testing::VtsHalHidlTargetTestBase {
       if (i < baseSize_) {
         EXPECT_EQ(names_[i], temperatures[i].name.c_str());
       } else {
-        // Names must be unique.
-        EXPECT_EQ(names_.end(), std::find(names_.begin(), names_.end(),
-                                          temperatures[i].name.c_str()));
-        names_.push_back(temperatures[i].name);
+          // Names must be unique only for known temperature types.
+          if (temperatures[i].type != TemperatureType::UNKNOWN) {
+              EXPECT_EQ(names_.end(), std::find(names_.begin(), names_.end(),
+                                                temperatures[i].name.c_str()));
+          }
+          names_.push_back(temperatures[i].name);
       }
     }
     baseSize_ = size;
@@ -88,10 +90,9 @@ class ThermalHidlTest : public ::testing::VtsHalHidlTargetTestBase {
       if (i < baseSize_) {
         EXPECT_EQ(names_[i], cpuUsages[i].name.c_str());
       } else {
-        // Names must be unique.
-        EXPECT_EQ(names_.end(), std::find(names_.begin(), names_.end(),
-                                          cpuUsages[i].name.c_str()));
-        names_.push_back(cpuUsages[i].name);
+          // Names are not guaranteed to be unique because of the current
+          // default Thermal HAL implementation.
+          names_.push_back(cpuUsages[i].name);
       }
     }
     baseSize_ = size;
diff --git a/usb/1.1/Android.bp b/usb/1.1/Android.bp
new file mode 100644 (file)
index 0000000..5466001
--- /dev/null
@@ -0,0 +1,75 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+    name: "android.hardware.usb@1.1_hal",
+    srcs: [
+        "types.hal",
+        "IUsb.hal",
+        "IUsbCallback.hal",
+    ],
+}
+
+genrule {
+    name: "android.hardware.usb@1.1_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.usb@1.1",
+    srcs: [
+        ":android.hardware.usb@1.1_hal",
+    ],
+    out: [
+        "android/hardware/usb/1.1/types.cpp",
+        "android/hardware/usb/1.1/UsbAll.cpp",
+        "android/hardware/usb/1.1/UsbCallbackAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.usb@1.1_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.usb@1.1",
+    srcs: [
+        ":android.hardware.usb@1.1_hal",
+    ],
+    out: [
+        "android/hardware/usb/1.1/types.h",
+        "android/hardware/usb/1.1/hwtypes.h",
+        "android/hardware/usb/1.1/IUsb.h",
+        "android/hardware/usb/1.1/IHwUsb.h",
+        "android/hardware/usb/1.1/BnHwUsb.h",
+        "android/hardware/usb/1.1/BpHwUsb.h",
+        "android/hardware/usb/1.1/BsUsb.h",
+        "android/hardware/usb/1.1/IUsbCallback.h",
+        "android/hardware/usb/1.1/IHwUsbCallback.h",
+        "android/hardware/usb/1.1/BnHwUsbCallback.h",
+        "android/hardware/usb/1.1/BpHwUsbCallback.h",
+        "android/hardware/usb/1.1/BsUsbCallback.h",
+    ],
+}
+
+cc_library {
+    name: "android.hardware.usb@1.1",
+    defaults: ["hidl-module-defaults"],
+    generated_sources: ["android.hardware.usb@1.1_genc++"],
+    generated_headers: ["android.hardware.usb@1.1_genc++_headers"],
+    export_generated_headers: ["android.hardware.usb@1.1_genc++_headers"],
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hardware.usb@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.usb@1.0",
+    ],
+}
diff --git a/usb/1.1/Android.mk b/usb/1.1/Android.mk
new file mode 100644 (file)
index 0000000..57147f1
--- /dev/null
@@ -0,0 +1,138 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.usb-V1.1-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+    android.hardware.usb-V1.0-java \
+    android.hidl.base-V1.0-java \
+
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES += core-oj hwbinder
+
+#
+# Build types.hal (PortMode_1_1)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_1/PortMode_1_1.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.usb@1.1::types.PortMode_1_1
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (PortStatus_1_1)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_1/PortStatus_1_1.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.usb@1.1::types.PortStatus_1_1
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IUsb.hal
+#
+GEN := $(intermediates)/android/hardware/usb/V1_1/IUsb.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IUsb.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.usb@1.1::IUsb
+
+$(GEN): $(LOCAL_PATH)/IUsb.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IUsbCallback.hal
+#
+GEN := $(intermediates)/android/hardware/usb/V1_1/IUsbCallback.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IUsbCallback.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.usb@1.1::IUsbCallback
+
+$(GEN): $(LOCAL_PATH)/IUsbCallback.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.usb-V1.1-java-constants
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_1/Constants.java
+$(GEN): $(HIDL)
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/IUsb.hal
+$(GEN): $(LOCAL_PATH)/IUsbCallback.hal
+
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava-constants \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.usb@1.1
+
+$(GEN):
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+# Avoid dependency cycle of framework.jar -> this-library -> framework.jar
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core-oj
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/usb/1.1/IUsb.hal b/usb/1.1/IUsb.hal
new file mode 100644 (file)
index 0000000..9cedea0
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package android.hardware.usb@1.1;
+
+import android.hardware.usb@1.0;
+
+interface IUsb extends android.hardware.usb@1.0::IUsb {
+    /**
+     * The setCallback function in V1_0 is used to register the V1_1
+     * IUsbCallback object as well. The implementation can use the
+     * castFrom method to cast the IUsbCallback object.
+     */
+};
+
diff --git a/usb/1.1/IUsbCallback.hal b/usb/1.1/IUsbCallback.hal
new file mode 100644 (file)
index 0000000..369ffc8
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+package android.hardware.usb@1.1;
+
+import android.hardware.usb@1.0;
+
+/**
+ * Callback object used for all the IUsb async methods which expects a result.
+ * Caller is expected to register the callback object using setCallback method
+ * to receive updates on the PortStatus.
+ */
+interface IUsbCallback extends @1.0::IUsbCallback {
+    /**
+     * Used to convey the current port status to the caller.
+     * Must be called either when PortState changes due to the port partner or
+     * when caller requested for the PortStatus update through queryPortStatus.
+     *
+     * @param currentPortStatus vector object of current status(PortStatus_1_1
+     * of all the typeC ports in the device.
+     * @param retval SUCCESS when the required information was enquired form
+     *               kernel and the PortStatus_1_1 object was built.
+     *               ERROR otherwise.
+     */
+    oneway notifyPortStatusChange_1_1(vec<PortStatus_1_1> currentPortStatus,
+        Status retval);
+};
diff --git a/usb/1.1/types.hal b/usb/1.1/types.hal
new file mode 100644 (file)
index 0000000..2261e09
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+package android.hardware.usb@1.1;
+
+import android.hardware.usb@1.0;
+
+@export
+enum PortMode_1_1 : PortMode {
+    /*
+     * Indicates that the port supports Audio Accessory mode.
+     */
+    AUDIO_ACCESSORY = 1 << 2,
+
+    /*
+     * Indicates that the port supports Debug Accessory mode.
+     */
+    DEBUG_ACCESSORY = 1 << 3,
+
+    NUM_MODES_1_1 = 1 << 4,
+};
+
+/*
+ * Used as the container to report data back to the caller.
+ * Represents the current connection status of a single USB port.
+ */
+struct PortStatus_1_1 {
+    /*
+     * The supportedModes and the currentMode fields of the status
+     * object should be set to NONE.
+     */
+    PortStatus status;
+
+    /*
+     * Identifies the modes supported by the port.
+     * Refer to PortMode_1_1 for the significance of the individual bits.
+     */
+    bitfield<PortMode_1_1> supportedModes;
+
+    /*
+     * Indicates the current mode in which the port is operating.
+     */
+    PortMode_1_1 currentMode;
+};
diff --git a/usb/1.1/vts/functional/Android.bp b/usb/1.1/vts/functional/Android.bp
new file mode 100644 (file)
index 0000000..820f794
--- /dev/null
@@ -0,0 +1,38 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "VtsHalUsbV1_1TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalUsbV1_1TargetTest.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.usb@1.0",
+        "android.hardware.usb@1.1",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
+
diff --git a/usb/1.1/vts/functional/VtsHalUsbV1_1TargetTest.cpp b/usb/1.1/vts/functional/VtsHalUsbV1_1TargetTest.cpp
new file mode 100644 (file)
index 0000000..8a30993
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * 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 "VtsHalUsbV1_0TargetTest"
+#include <android-base/logging.h>
+
+#include <android/hardware/usb/1.0/types.h>
+#include <android/hardware/usb/1.1/IUsb.h>
+#include <android/hardware/usb/1.1/IUsbCallback.h>
+#include <android/hardware/usb/1.1/types.h>
+
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <VtsHalHidlTargetTestBase.h>
+#include <log/log.h>
+#include <stdlib.h>
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+
+using ::android::hardware::usb::V1_1::IUsbCallback;
+using ::android::hardware::usb::V1_0::IUsb;
+using ::android::hardware::usb::V1_0::PortDataRole;
+using ::android::hardware::usb::V1_0::PortMode;
+using ::android::hardware::usb::V1_1::PortMode_1_1;
+using ::android::hardware::usb::V1_0::PortPowerRole;
+using ::android::hardware::usb::V1_0::PortRole;
+using ::android::hardware::usb::V1_0::PortRoleType;
+using ::android::hardware::usb::V1_0::PortStatus;
+using ::android::hardware::usb::V1_1::PortStatus_1_1;
+using ::android::hardware::usb::V1_0::Status;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+constexpr char kCallbackNameNotifyPortStatusChange_1_1[] = "notifyPortStatusChange_1_1";
+
+// Worst case wait time 20secs
+#define WAIT_FOR_TIMEOUT std::chrono::milliseconds(20000)
+
+class UsbClientCallbackArgs {
+   public:
+    // The last conveyed status of the USB ports.
+    // Stores information of currentt_data_role, power_role for all the USB ports
+    PortStatus_1_1 usb_last_port_status;
+
+    // Status of the last role switch operation.
+    Status usb_last_status;
+
+    // Identifier for the usb callback object.
+    // Stores the cookie of the last invoked usb callback object.
+    int last_usb_cookie;
+};
+
+// Callback class for the USB HIDL hal.
+// Usb Hal will call this object upon role switch or port query.
+class UsbCallback : public ::testing::VtsHalHidlTargetCallbackBase<UsbClientCallbackArgs>,
+                    public IUsbCallback {
+    int cookie;
+
+   public:
+    UsbCallback(int cookie) : cookie(cookie){};
+
+    virtual ~UsbCallback() = default;
+
+    // V1_0 Callback method for the port status.
+    // This should not be called so not signalling the Test here assuming that
+    // the test thread will timeout
+    Return<void> notifyPortStatusChange(const hidl_vec<PortStatus>& /* currentPortStatus */,
+                                        Status /*retval*/) override {
+        return Void();
+    };
+
+    // This callback methode should be used.
+    Return<void> notifyPortStatusChange_1_1(const hidl_vec<PortStatus_1_1>& currentPortStatus,
+                                            Status retval) override {
+        UsbClientCallbackArgs arg;
+        if (retval == Status::SUCCESS) {
+            arg.usb_last_port_status.status.supportedModes =
+                currentPortStatus[0].status.supportedModes;
+            arg.usb_last_port_status.status.currentMode = currentPortStatus[0].status.currentMode;
+        }
+        arg.usb_last_status = retval;
+        arg.last_usb_cookie = cookie;
+
+        NotifyFromCallback(kCallbackNameNotifyPortStatusChange_1_1, arg);
+        return Void();
+    }
+
+    // Callback method for the status of role switch operation.
+    // RoleSwitch operation has not changed since V1_0 so leaving
+    // the callback blank here.
+    Return<void> notifyRoleSwitchStatus(const hidl_string& /*portName*/,
+                                        const PortRole& /*newRole*/, Status /*retval*/) override {
+        return Void();
+    };
+};
+
+// The main test class for the USB hidl HAL
+class UsbHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        ALOGI(__FUNCTION__);
+        usb = ::testing::VtsHalHidlTargetTestBase::getService<IUsb>();
+        ASSERT_NE(usb, nullptr);
+
+        usb_cb_2 = new UsbCallback(2);
+        ASSERT_NE(usb_cb_2, nullptr);
+        usb_cb_2->SetWaitTimeout(kCallbackNameNotifyPortStatusChange_1_1, WAIT_FOR_TIMEOUT);
+        Return<void> ret = usb->setCallback(usb_cb_2);
+        ASSERT_TRUE(ret.isOk());
+    }
+
+    virtual void TearDown() override { ALOGI("Teardown"); }
+
+    // USB hidl hal Proxy
+    sp<IUsb> usb;
+
+    // Callback objects for usb hidl
+    // Methods of these objects are called to notify port status updates.
+    sp<UsbCallback> usb_cb_1;
+    sp<UsbCallback> usb_cb_2;
+};
+
+/*
+ * Test to see if setCallback on V1_1 callback object succeeds.
+ * Callback oject is created and registered.
+ * Check to see if the hidl transaction succeeded.
+ */
+TEST_F(UsbHidlTest, setCallback) {
+    usb_cb_1 = new UsbCallback(1);
+    ASSERT_NE(usb_cb_1, nullptr);
+    Return<void> ret = usb->setCallback(usb_cb_1);
+    ASSERT_TRUE(ret.isOk());
+}
+
+/*
+ * Check to see if querying type-c
+ * port status succeeds.
+ * HAL service should call notifyPortStatusChange_1_1
+ * instead of notifyPortStatusChange of V1_0 interface
+ */
+TEST_F(UsbHidlTest, queryPortStatus) {
+    Return<void> ret = usb->queryPortStatus();
+    ASSERT_TRUE(ret.isOk());
+    auto res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_1);
+    EXPECT_TRUE(res.no_timeout);
+    EXPECT_EQ(2, res.args->last_usb_cookie);
+    EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status.currentMode);
+    EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status.supportedModes);
+    EXPECT_EQ(Status::SUCCESS, res.args->usb_last_status);
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGI("Test result = %d", status);
+    return status;
+}
index ed19a37034cf68a33182e63e39bd7905d3e62731..a5415df348b207e6d5699e12bbff7abcc5844c6f 100644 (file)
@@ -3,4 +3,6 @@ subdirs = [
     "1.0",
     "1.0/default",
     "1.0/vts/functional",
+    "1.1",
+    "1.1/vts/functional",
 ]
diff --git a/vibrator/1.1/Android.bp b/vibrator/1.1/Android.bp
new file mode 100644 (file)
index 0000000..a47f37c
--- /dev/null
@@ -0,0 +1,68 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+    name: "android.hardware.vibrator@1.1_hal",
+    srcs: [
+        "types.hal",
+        "IVibrator.hal",
+    ],
+}
+
+genrule {
+    name: "android.hardware.vibrator@1.1_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.vibrator@1.1",
+    srcs: [
+        ":android.hardware.vibrator@1.1_hal",
+    ],
+    out: [
+        "android/hardware/vibrator/1.1/types.cpp",
+        "android/hardware/vibrator/1.1/VibratorAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.vibrator@1.1_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.vibrator@1.1",
+    srcs: [
+        ":android.hardware.vibrator@1.1_hal",
+    ],
+    out: [
+        "android/hardware/vibrator/1.1/types.h",
+        "android/hardware/vibrator/1.1/hwtypes.h",
+        "android/hardware/vibrator/1.1/IVibrator.h",
+        "android/hardware/vibrator/1.1/IHwVibrator.h",
+        "android/hardware/vibrator/1.1/BnHwVibrator.h",
+        "android/hardware/vibrator/1.1/BpHwVibrator.h",
+        "android/hardware/vibrator/1.1/BsVibrator.h",
+    ],
+}
+
+cc_library {
+    name: "android.hardware.vibrator@1.1",
+    defaults: ["hidl-module-defaults"],
+    generated_sources: ["android.hardware.vibrator@1.1_genc++"],
+    generated_headers: ["android.hardware.vibrator@1.1_genc++_headers"],
+    export_generated_headers: ["android.hardware.vibrator@1.1_genc++_headers"],
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hardware.vibrator@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.vibrator@1.0",
+    ],
+}
diff --git a/vibrator/1.1/Android.mk b/vibrator/1.1/Android.mk
new file mode 100644 (file)
index 0000000..d08f837
--- /dev/null
@@ -0,0 +1,99 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.vibrator-V1.1-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+    android.hardware.vibrator-V1.0-java \
+    android.hidl.base-V1.0-java \
+
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES += core-oj hwbinder
+
+#
+# Build types.hal (Effect_1_1)
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_1/Effect_1_1.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.vibrator@1.1::types.Effect_1_1
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IVibrator.hal
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_1/IVibrator.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IVibrator.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.vibrator@1.1::IVibrator
+
+$(GEN): $(LOCAL_PATH)/IVibrator.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.vibrator-V1.1-java-constants
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_1/Constants.java
+$(GEN): $(HIDL)
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/IVibrator.hal
+
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava-constants \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.vibrator@1.1
+
+$(GEN):
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+# Avoid dependency cycle of framework.jar -> this-library -> framework.jar
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core-oj
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/vibrator/1.1/IVibrator.hal b/vibrator/1.1/IVibrator.hal
new file mode 100644 (file)
index 0000000..9a2f465
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package android.hardware.vibrator@1.1;
+
+import @1.0::EffectStrength;
+import @1.0::IVibrator;
+import @1.0::Status;
+
+interface IVibrator extends @1.0::IVibrator {
+  /**
+   * Fire off a predefined haptic event.
+   *
+   * @param event The type of haptic event to trigger.
+   * @return status Whether the effect was successfully performed or not. Must
+   *                return Status::UNSUPPORTED_OPERATION is the effect is not
+   *                supported.
+   * @return lengthMs The length of time the event is expected to take in
+   *                  milliseconds. This doesn't need to be perfectly accurate,
+   *                  but should be a reasonable approximation. Should be a
+   *                  positive, non-zero value if the returned status is
+   *                  Status::OK, and set to 0 otherwise.
+   */
+  perform_1_1(Effect_1_1 effect, EffectStrength strength)
+          generates (Status status, uint32_t lengthMs);
+};
diff --git a/vibrator/1.1/types.hal b/vibrator/1.1/types.hal
new file mode 100644 (file)
index 0000000..f7a619a
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+package android.hardware.vibrator@1.1;
+
+import @1.0::Effect;
+
+@export
+enum Effect_1_1 : @1.0::Effect {
+    /**
+     * A tick effect.
+     *
+     * This effect should produce a soft, short sensation, like the tick of a clock.
+     */
+    TICK
+};
diff --git a/vibrator/1.1/vts/functional/Android.bp b/vibrator/1.1/vts/functional/Android.bp
new file mode 100644 (file)
index 0000000..5baa8ed
--- /dev/null
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "VtsHalVibratorV1_1TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalVibratorV1_1TargetTest.cpp"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+        "android.hardware.vibrator@1.1",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
+
diff --git a/vibrator/1.1/vts/functional/VtsHalVibratorV1_1TargetTest.cpp b/vibrator/1.1/vts/functional/VtsHalVibratorV1_1TargetTest.cpp
new file mode 100644 (file)
index 0000000..35000f8
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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 "vibrator_hidl_hal_test"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/logging.h>
+#include <android/hardware/vibrator/1.1/IVibrator.h>
+#include <android/hardware/vibrator/1.1/types.h>
+#include <unistd.h>
+
+using ::android::hardware::vibrator::V1_0::Effect;
+using ::android::hardware::vibrator::V1_0::EffectStrength;
+using ::android::hardware::vibrator::V1_0::Status;
+using ::android::hardware::vibrator::V1_1::Effect_1_1;
+using ::android::hardware::vibrator::V1_1::IVibrator;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+// The main test class for VIBRATOR HIDL HAL 1.1.
+class VibratorHidlTest_1_1 : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        vibrator = ::testing::VtsHalHidlTargetTestBase::getService<IVibrator>();
+        ASSERT_NE(vibrator, nullptr);
+    }
+
+    virtual void TearDown() override {}
+
+    sp<IVibrator> vibrator;
+};
+
+static void validatePerformEffect(Status status, uint32_t lengthMs) {
+    ASSERT_TRUE(status == Status::OK || status == Status::UNSUPPORTED_OPERATION);
+    if (status == Status::OK) {
+        ASSERT_GT(lengthMs, static_cast<uint32_t>(0))
+            << "Effects that return OK must return a non-zero duration";
+    } else {
+        ASSERT_EQ(lengthMs, static_cast<uint32_t>(0))
+            << "Effects that return UNSUPPORTED_OPERATION must have a duration of zero";
+    }
+}
+
+TEST_F(VibratorHidlTest_1_1, PerformEffect_1_1) {
+    vibrator->perform_1_1(Effect_1_1::CLICK, EffectStrength::MEDIUM, validatePerformEffect);
+    vibrator->perform_1_1(Effect_1_1::TICK, EffectStrength::STRONG, validatePerformEffect);
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    LOG(INFO) << "Test result = " << status;
+    return status;
+}
index ed19a37034cf68a33182e63e39bd7905d3e62731..a5415df348b207e6d5699e12bbff7abcc5844c6f 100644 (file)
@@ -3,4 +3,6 @@ subdirs = [
     "1.0",
     "1.0/default",
     "1.0/vts/functional",
+    "1.1",
+    "1.1/vts/functional",
 ]
diff --git a/weaver/1.0/Android.bp b/weaver/1.0/Android.bp
new file mode 100644 (file)
index 0000000..cdc59c9
--- /dev/null
@@ -0,0 +1,66 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+    name: "android.hardware.weaver@1.0_hal",
+    srcs: [
+        "types.hal",
+        "IWeaver.hal",
+    ],
+}
+
+genrule {
+    name: "android.hardware.weaver@1.0_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.weaver@1.0",
+    srcs: [
+        ":android.hardware.weaver@1.0_hal",
+    ],
+    out: [
+        "android/hardware/weaver/1.0/types.cpp",
+        "android/hardware/weaver/1.0/WeaverAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.weaver@1.0_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.weaver@1.0",
+    srcs: [
+        ":android.hardware.weaver@1.0_hal",
+    ],
+    out: [
+        "android/hardware/weaver/1.0/types.h",
+        "android/hardware/weaver/1.0/hwtypes.h",
+        "android/hardware/weaver/1.0/IWeaver.h",
+        "android/hardware/weaver/1.0/IHwWeaver.h",
+        "android/hardware/weaver/1.0/BnHwWeaver.h",
+        "android/hardware/weaver/1.0/BpHwWeaver.h",
+        "android/hardware/weaver/1.0/BsWeaver.h",
+    ],
+}
+
+cc_library {
+    name: "android.hardware.weaver@1.0",
+    defaults: ["hidl-module-defaults"],
+    generated_sources: ["android.hardware.weaver@1.0_genc++"],
+    generated_headers: ["android.hardware.weaver@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.weaver@1.0_genc++_headers"],
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+    ],
+}
diff --git a/weaver/1.0/Android.mk b/weaver/1.0/Android.mk
new file mode 100644 (file)
index 0000000..ab33a15
--- /dev/null
@@ -0,0 +1,121 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.weaver-V1.0-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+    android.hidl.base-V1.0-java \
+
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES += core-oj hwbinder
+
+#
+# Build types.hal (WeaverConfig)
+#
+GEN := $(intermediates)/android/hardware/weaver/V1_0/WeaverConfig.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.weaver@1.0::types.WeaverConfig
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (WeaverReadResponse)
+#
+GEN := $(intermediates)/android/hardware/weaver/V1_0/WeaverReadResponse.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.weaver@1.0::types.WeaverReadResponse
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (WeaverReadStatus)
+#
+GEN := $(intermediates)/android/hardware/weaver/V1_0/WeaverReadStatus.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.weaver@1.0::types.WeaverReadStatus
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (WeaverStatus)
+#
+GEN := $(intermediates)/android/hardware/weaver/V1_0/WeaverStatus.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.weaver@1.0::types.WeaverStatus
+
+$(GEN): $(LOCAL_PATH)/types.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IWeaver.hal
+#
+GEN := $(intermediates)/android/hardware/weaver/V1_0/IWeaver.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IWeaver.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.weaver@1.0::IWeaver
+
+$(GEN): $(LOCAL_PATH)/IWeaver.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/weaver/1.0/IWeaver.hal b/weaver/1.0/IWeaver.hal
new file mode 100644 (file)
index 0000000..e572123
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+package android.hardware.weaver@1.0;
+
+/**
+ * Weaver provides secure storage of secret values that may only be read if the
+ * corresponding key has been presented.
+ *
+ * The storage must be secure as the device's user authentication and encryption
+ * relies on the security of these values. The cardinality of the domains of the
+ * key and value must be suitably large such that they cannot be easily guessed.
+ *
+ * Weaver is structured as an array of slots, each containing a key-value pair.
+ * Slots are uniquely identified by an ID in the range [0, `getConfig().slots`).
+ */
+interface IWeaver {
+    /**
+     * Retrieves the config information for this implementation of Weaver.
+     *
+     * The config is static i.e. every invocation returns the same information.
+     *
+     * @return status is OK if the config was successfuly obtained.
+     * @return config data for this implementation of Weaver if status is OK,
+     *         otherwise undefined.
+     */
+    getConfig() generates (WeaverStatus status, WeaverConfig config);
+
+    /**
+     * Overwrites the identified slot with the provided key and value.
+     *
+     * The new values are written regardless of the current state of the slot in
+     * order to remain idempotent.
+     *
+     * @param slotId of the slot to write to.
+     * @param key to write to the slot.
+     * @param value to write to slot.
+     * @return status is OK if the write was successfully completed.
+     */
+    write(uint32_t slotId, vec<uint8_t> key, vec<uint8_t> value)
+                generates (WeaverStatus status);
+
+    /**
+     * Attempts to retrieve the value stored in the identified slot.
+     *
+     * The value is only returned if the provided key matches the key stored in
+     * the slot. The value is never returned if the wrong key is provided.
+     *
+     * Throttling must be used to limit the frequency of failed read attempts.
+     * The value is only returned when throttling is not active, even if the
+     * correct key is provided. If called when throttling is active, the time
+     * until the next attempt can be made is returned.
+     *
+     * @param slotId of the slot to read from.
+     * @param key that is stored in the slot.
+     * @return status is OK if the value was successfully read, INCORRECT_KEY if
+     *         the key does not match the key in the slot, THROTTLE if
+     *         throttling is active or FAILED if the read was unsuccessful for
+     *         another reason.
+     * @return readResponse contains the value read and the timeout to wait
+     *         before making the next request. If the status is OK, value is set
+     *         to the value in the slot and timeout is 0. Otherwise, value is
+     *         empty and timeout is set accordingly.
+     */
+    read(uint32_t slotId, vec<uint8_t> key)
+                generates (WeaverReadStatus status,
+                           WeaverReadResponse readResponse);
+};
diff --git a/weaver/1.0/types.hal b/weaver/1.0/types.hal
new file mode 100644 (file)
index 0000000..49e5c04
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+package android.hardware.weaver@1.0;
+
+enum WeaverStatus : uint32_t {
+    OK,
+    FAILED,
+};
+
+struct WeaverConfig {
+    /** The number of slots available. */
+    uint32_t slots;
+    /** The number of bytes used for a key. */
+    uint32_t keySize;
+    /** The number of bytes used for a value. */
+    uint32_t valueSize;
+};
+
+enum WeaverReadStatus : WeaverStatus {
+    INCORRECT_KEY,
+    THROTTLE,
+};
+
+struct WeaverReadResponse {
+    /** The time to wait, in milliseconds, before making the next request. */
+    uint32_t timeout;
+    /** The value read from the slot or empty if the value was not read. */
+    vec<uint8_t> value;
+};
diff --git a/weaver/1.0/vts/functional/Android.bp b/weaver/1.0/vts/functional/Android.bp
new file mode 100644 (file)
index 0000000..9b0ff6d
--- /dev/null
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "VtsHalWeaverV1_0TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalWeaverV1_0TargetTest.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.weaver@1.0",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/weaver/1.0/vts/functional/VtsHalWeaverV1_0TargetTest.cpp b/weaver/1.0/vts/functional/VtsHalWeaverV1_0TargetTest.cpp
new file mode 100644 (file)
index 0000000..372d787
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * 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.
+ */
+
+#include <android/hardware/weaver/1.0/IWeaver.h>
+
+#include <limits>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+using ::android::hardware::weaver::V1_0::IWeaver;
+using ::android::hardware::weaver::V1_0::WeaverConfig;
+using ::android::hardware::weaver::V1_0::WeaverReadStatus;
+using ::android::hardware::weaver::V1_0::WeaverReadResponse;
+using ::android::hardware::weaver::V1_0::WeaverStatus;
+using ::android::hardware::Return;
+using ::android::sp;
+
+const std::vector<uint8_t> KEY{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+const std::vector<uint8_t> WRONG_KEY{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const std::vector<uint8_t> VALUE{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
+const std::vector<uint8_t> OTHER_VALUE{0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 255, 255};
+
+struct WeaverHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+    virtual void SetUp() override {
+        weaver = ::testing::VtsHalHidlTargetTestBase::getService<IWeaver>();
+        ASSERT_NE(weaver, nullptr);
+    }
+
+    virtual void TearDown() override {}
+
+    sp<IWeaver> weaver;
+};
+
+/*
+ * Checks config values are suitably large
+ */
+TEST_F(WeaverHidlTest, GetConfig) {
+    WeaverStatus status;
+    WeaverConfig config;
+
+    bool callbackCalled = false;
+    auto ret = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
+        callbackCalled = true;
+        status = s;
+        config = c;
+    });
+    ASSERT_TRUE(ret.isOk());
+    ASSERT_TRUE(callbackCalled);
+    ASSERT_EQ(status, WeaverStatus::OK);
+
+    EXPECT_GE(config.slots, 16u);
+    EXPECT_GE(config.keySize, 16u);
+    EXPECT_GE(config.valueSize, 16u);
+}
+
+/*
+ * Gets the config twice and checks they are the same
+ */
+TEST_F(WeaverHidlTest, GettingConfigMultipleTimesGivesSameResult) {
+    WeaverConfig config1;
+    WeaverConfig config2;
+
+    WeaverStatus status;
+    bool callbackCalled = false;
+    auto ret = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
+        callbackCalled = true;
+        status = s;
+        config1 = c;
+    });
+    ASSERT_TRUE(ret.isOk());
+    ASSERT_TRUE(callbackCalled);
+    ASSERT_EQ(status, WeaverStatus::OK);
+
+    callbackCalled = false;
+    ret = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
+        callbackCalled = true;
+        status = s;
+        config2 = c;
+    });
+    ASSERT_TRUE(ret.isOk());
+    ASSERT_TRUE(callbackCalled);
+    ASSERT_EQ(status, WeaverStatus::OK);
+
+    EXPECT_EQ(config1, config2);
+}
+
+/*
+ * Gets the number of slots from the config and writes a key and value to the last one
+ */
+TEST_F(WeaverHidlTest, WriteToLastSlot) {
+    WeaverStatus status;
+    WeaverConfig config;
+    const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
+        status = s;
+        config = c;
+    });
+    ASSERT_TRUE(configRet.isOk());
+    ASSERT_EQ(status, WeaverStatus::OK);
+
+    const uint32_t lastSlot = config.slots - 1;
+    const auto writeRet = weaver->write(lastSlot, KEY, VALUE);
+    ASSERT_TRUE(writeRet.isOk());
+    ASSERT_EQ(writeRet, WeaverStatus::OK);
+}
+
+/*
+ * Writes a key and value to a slot
+ * Reads the slot with the same key and receives the value that was previously written
+ */
+TEST_F(WeaverHidlTest, WriteFollowedByReadGivesTheSameValue) {
+    constexpr uint32_t slotId = 0;
+    const auto ret = weaver->write(slotId, KEY, VALUE);
+    ASSERT_TRUE(ret.isOk());
+    ASSERT_EQ(ret, WeaverStatus::OK);
+
+    bool callbackCalled = false;
+    WeaverReadStatus status;
+    std::vector<uint8_t> readValue;
+    uint32_t timeout;
+    const auto readRet = weaver->read(slotId, KEY, [&](WeaverReadStatus s, WeaverReadResponse r) {
+        callbackCalled = true;
+        status = s;
+        readValue = r.value;
+        timeout = r.timeout;
+    });
+    ASSERT_TRUE(readRet.isOk());
+    ASSERT_TRUE(callbackCalled);
+    ASSERT_EQ(status, WeaverReadStatus::OK);
+    EXPECT_EQ(readValue, VALUE);
+    EXPECT_EQ(timeout, 0u);
+}
+
+/*
+ * Writes a key and value to a slot
+ * Overwrites the slot with a new key and value
+ * Reads the slot with the new key and receives the new value
+ */
+TEST_F(WeaverHidlTest, OverwritingSlotUpdatesTheValue) {
+    constexpr uint32_t slotId = 0;
+    const auto initialWriteRet = weaver->write(slotId, WRONG_KEY, VALUE);
+    ASSERT_TRUE(initialWriteRet.isOk());
+    ASSERT_EQ(initialWriteRet, WeaverStatus::OK);
+
+    const auto overwriteRet = weaver->write(slotId, KEY, OTHER_VALUE);
+    ASSERT_TRUE(overwriteRet.isOk());
+    ASSERT_EQ(overwriteRet, WeaverStatus::OK);
+
+    bool callbackCalled = false;
+    WeaverReadStatus status;
+    std::vector<uint8_t> readValue;
+    uint32_t timeout;
+    const auto readRet = weaver->read(slotId, KEY, [&](WeaverReadStatus s, WeaverReadResponse r) {
+        callbackCalled = true;
+        status = s;
+        readValue = r.value;
+        timeout = r.timeout;
+    });
+    ASSERT_TRUE(readRet.isOk());
+    ASSERT_TRUE(callbackCalled);
+    ASSERT_EQ(status, WeaverReadStatus::OK);
+    EXPECT_EQ(readValue, OTHER_VALUE);
+    EXPECT_EQ(timeout, 0u);
+}
+
+/*
+ * Writes a key and value to a slot
+ * Reads the slot with a different key so does not receive the value
+ */
+TEST_F(WeaverHidlTest, WriteFollowedByReadWithWrongKeyDoesNotGiveTheValue) {
+    constexpr uint32_t slotId = 0;
+    const auto ret = weaver->write(slotId, KEY, VALUE);
+    ASSERT_TRUE(ret.isOk());
+    ASSERT_EQ(ret, WeaverStatus::OK);
+
+    bool callbackCalled = false;
+    WeaverReadStatus status;
+    std::vector<uint8_t> readValue;
+    const auto readRet =
+        weaver->read(slotId, WRONG_KEY, [&](WeaverReadStatus s, WeaverReadResponse r) {
+            callbackCalled = true;
+            status = s;
+            readValue = r.value;
+        });
+    ASSERT_TRUE(callbackCalled);
+    ASSERT_TRUE(readRet.isOk());
+    ASSERT_EQ(status, WeaverReadStatus::INCORRECT_KEY);
+    EXPECT_TRUE(readValue.empty());
+}
+
+/*
+ * Writing to an invalid slot fails
+ */
+TEST_F(WeaverHidlTest, WritingToInvalidSlotFails) {
+    WeaverStatus status;
+    WeaverConfig config;
+    const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
+        status = s;
+        config = c;
+    });
+    ASSERT_TRUE(configRet.isOk());
+    ASSERT_EQ(status, WeaverStatus::OK);
+
+    if (config.slots == std::numeric_limits<uint32_t>::max()) {
+        // If there are no invalid slots then pass
+        return;
+    }
+
+    const auto writeRet = weaver->write(config.slots, KEY, VALUE);
+    ASSERT_TRUE(writeRet.isOk());
+    ASSERT_EQ(writeRet, WeaverStatus::FAILED);
+}
+
+/*
+ * Reading from an invalid slot fails rather than incorrect key
+ */
+TEST_F(WeaverHidlTest, ReadingFromInvalidSlotFails) {
+    WeaverStatus status;
+    WeaverConfig config;
+    const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
+        status = s;
+        config = c;
+    });
+    ASSERT_TRUE(configRet.isOk());
+    ASSERT_EQ(status, WeaverStatus::OK);
+
+    if (config.slots == std::numeric_limits<uint32_t>::max()) {
+        // If there are no invalid slots then pass
+        return;
+    }
+
+    bool callbackCalled = false;
+    WeaverReadStatus readStatus;
+    std::vector<uint8_t> readValue;
+    uint32_t timeout;
+    const auto readRet =
+        weaver->read(config.slots, KEY, [&](WeaverReadStatus s, WeaverReadResponse r) {
+            callbackCalled = true;
+            readStatus = s;
+            readValue = r.value;
+            timeout = r.timeout;
+        });
+    ASSERT_TRUE(callbackCalled);
+    ASSERT_TRUE(readRet.isOk());
+    ASSERT_EQ(readStatus, WeaverReadStatus::FAILED);
+    EXPECT_TRUE(readValue.empty());
+    EXPECT_EQ(timeout, 0u);
+}
+
+/*
+ * Writing a key that is too large fails
+ */
+TEST_F(WeaverHidlTest, WriteWithTooLargeKeyFails) {
+    WeaverStatus status;
+    WeaverConfig config;
+    const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
+        status = s;
+        config = c;
+    });
+    ASSERT_TRUE(configRet.isOk());
+    ASSERT_EQ(status, WeaverStatus::OK);
+
+    std::vector<uint8_t> bigKey(config.keySize + 1);
+
+    constexpr uint32_t slotId = 0;
+    const auto writeRet = weaver->write(slotId, bigKey, VALUE);
+    ASSERT_TRUE(writeRet.isOk());
+    ASSERT_EQ(writeRet, WeaverStatus::FAILED);
+}
+
+/*
+ * Writing a value that is too large fails
+ */
+TEST_F(WeaverHidlTest, WriteWithTooLargeValueFails) {
+    WeaverStatus status;
+    WeaverConfig config;
+    const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
+        status = s;
+        config = c;
+    });
+    ASSERT_TRUE(configRet.isOk());
+    ASSERT_EQ(status, WeaverStatus::OK);
+
+    std::vector<uint8_t> bigValue(config.valueSize + 1);
+
+    constexpr uint32_t slotId = 0;
+    const auto writeRet = weaver->write(slotId, KEY, bigValue);
+    ASSERT_TRUE(writeRet.isOk());
+    ASSERT_EQ(writeRet, WeaverStatus::FAILED);
+}
+
+/*
+ * Reading with a key that is loo large fails
+ */
+TEST_F(WeaverHidlTest, ReadWithTooLargeKeyFails) {
+    WeaverStatus status;
+    WeaverConfig config;
+    const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
+        status = s;
+        config = c;
+    });
+    ASSERT_TRUE(configRet.isOk());
+    ASSERT_EQ(status, WeaverStatus::OK);
+
+    std::vector<uint8_t> bigKey(config.keySize + 1);
+
+    constexpr uint32_t slotId = 0;
+    bool callbackCalled = false;
+    WeaverReadStatus readStatus;
+    std::vector<uint8_t> readValue;
+    uint32_t timeout;
+    const auto readRet =
+        weaver->read(slotId, bigKey, [&](WeaverReadStatus s, WeaverReadResponse r) {
+            callbackCalled = true;
+            readStatus = s;
+            readValue = r.value;
+            timeout = r.timeout;
+        });
+    ASSERT_TRUE(callbackCalled);
+    ASSERT_TRUE(readRet.isOk());
+    ASSERT_EQ(readStatus, WeaverReadStatus::FAILED);
+    EXPECT_TRUE(readValue.empty());
+    EXPECT_EQ(timeout, 0u);
+}
diff --git a/weaver/Android.bp b/weaver/Android.bp
new file mode 100644 (file)
index 0000000..33f70eb
--- /dev/null
@@ -0,0 +1,5 @@
+// This is an autogenerated file, do not edit.
+subdirs = [
+    "1.0",
+    "1.0/vts/functional",
+]
index 10f1987a06634b9073d5fdebeb4dfe83369b8d58..ea27f02d04dcfc226231c30603aef230d3c44b1a 100644 (file)
@@ -18,10 +18,12 @@ cc_library_static {
     name: "VtsHalWifiV1_0TargetTestUtil",
     defaults: ["hidl_defaults"],
     srcs: [
-
         "wifi_hidl_call_util_selftest.cpp",
         "wifi_hidl_test.cpp",
         "wifi_hidl_test_utils.cpp"],
+    export_include_dirs: [
+        "."
+    ],
     shared_libs: [
         "libbase",
         "liblog",
index 160fcd234625c04735ae149ecc1426c153b8d563..beac03988812a630bcfe074b23ad44893de1884c 100644 (file)
 
 #include "wifi_hidl_test_utils.h"
 
+WifiHidlEnvironment* gEnv;
+
 int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(new WifiHidlEnvironment);
+    gEnv = new WifiHidlEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
     ::testing::InitGoogleTest(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        LOG(INFO) << "Test result = " << status;
+    }
     return status;
 }
index 6c2372f80eb30a9369502e890e6b2e02d8a51828..3c23135927f085f770ed628da601401bea2d561b 100644 (file)
@@ -42,6 +42,8 @@ using ::android::hardware::wifi::V1_0::IWifiP2pIface;
 using ::android::hardware::wifi::V1_0::IWifiRttController;
 using ::android::hardware::wifi::V1_0::IWifiStaIface;
 
+extern WifiHidlEnvironment* gEnv;
+
 namespace {
 constexpr WifiDebugRingBufferVerboseLevel kDebugRingBufferVerboseLvl =
     WifiDebugRingBufferVerboseLevel::VERBOSE;
@@ -78,7 +80,8 @@ class WifiChipHidlTest : public ::testing::VtsHalHidlTargetTestBase {
     // to be first configured.
     ChipModeId configureChipForIfaceType(IfaceType type, bool expectSuccess) {
         ChipModeId mode_id;
-        EXPECT_EQ(expectSuccess, configureChipToSupportIfaceType(wifi_chip_, type, &mode_id));
+        EXPECT_EQ(expectSuccess,
+            configureChipToSupportIfaceType(wifi_chip_, type, &mode_id));
         return mode_id;
     }
 
@@ -179,6 +182,8 @@ TEST_F(WifiChipHidlTest, ConfigureChip) {
         EXPECT_EQ(WifiStatusCode::SUCCESS,
                   HIDL_INVOKE(wifi_chip_, configureChip, mode.id).code);
         stopWifi();
+        // Sleep for 5 milliseconds between each wifi state toggle.
+        usleep(5000);
     }
 }
 
@@ -436,10 +441,14 @@ TEST_F(WifiChipHidlTest, RemoveApIface) {
  * succeeds. The 2nd iface creation should be rejected.
  */
 TEST_F(WifiChipHidlTest, CreateNanIface) {
-    configureChipForIfaceType(IfaceType::NAN, false);
+    configureChipForIfaceType(IfaceType::NAN, gEnv->isNanOn);
+    if (!gEnv->isNanOn) return;
 
     sp<IWifiNanIface> iface;
-    ASSERT_EQ(WifiStatusCode::ERROR_NOT_AVAILABLE, createNanIface(&iface));
+    ASSERT_EQ(WifiStatusCode::SUCCESS, createNanIface(&iface));
+    EXPECT_NE(nullptr, iface.get());
+
+    EXPECT_EQ(WifiStatusCode::ERROR_NOT_AVAILABLE, createNanIface(&iface));
 }
 
 /*
@@ -449,12 +458,30 @@ TEST_F(WifiChipHidlTest, CreateNanIface) {
  * iface name is returned via the list.
  */
 TEST_F(WifiChipHidlTest, GetNanIfaceNames) {
-    configureChipForIfaceType(IfaceType::NAN, false);
+    configureChipForIfaceType(IfaceType::NAN, gEnv->isNanOn);
+    if (!gEnv->isNanOn) return;
 
     const auto& status_and_iface_names1 =
         HIDL_INVOKE(wifi_chip_, getNanIfaceNames);
     ASSERT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names1.first.code);
     EXPECT_EQ(0u, status_and_iface_names1.second.size());
+
+    sp<IWifiNanIface> iface;
+    EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&iface));
+    EXPECT_NE(nullptr, iface.get());
+
+    std::string iface_name = getIfaceName(iface);
+    const auto& status_and_iface_names2 =
+        HIDL_INVOKE(wifi_chip_, getNanIfaceNames);
+    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names2.first.code);
+    EXPECT_EQ(1u, status_and_iface_names2.second.size());
+    EXPECT_EQ(iface_name, status_and_iface_names2.second[0]);
+
+    EXPECT_EQ(WifiStatusCode::SUCCESS, removeNanIface(iface_name));
+    const auto& status_and_iface_names3 =
+        HIDL_INVOKE(wifi_chip_, getNanIfaceNames);
+    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names3.first.code);
+    EXPECT_EQ(0u, status_and_iface_names3.second.size());
 }
 
 /*
@@ -464,10 +491,24 @@ TEST_F(WifiChipHidlTest, GetNanIfaceNames) {
  * doesn't retrieve an iface object.
  */
 TEST_F(WifiChipHidlTest, GetNanIface) {
-    configureChipForIfaceType(IfaceType::NAN, false);
+    configureChipForIfaceType(IfaceType::NAN, gEnv->isNanOn);
+    if (!gEnv->isNanOn) return;
 
     sp<IWifiNanIface> nan_iface;
-    ASSERT_EQ(WifiStatusCode::ERROR_NOT_AVAILABLE, createNanIface(&nan_iface));
+    EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&nan_iface));
+    EXPECT_NE(nullptr, nan_iface.get());
+
+    std::string iface_name = getIfaceName(nan_iface);
+    const auto& status_and_iface1 =
+        HIDL_INVOKE(wifi_chip_, getNanIface, iface_name);
+    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface1.first.code);
+    EXPECT_NE(nullptr, status_and_iface1.second.get());
+
+    std::string invalid_name = iface_name + "0";
+    const auto& status_and_iface2 =
+        HIDL_INVOKE(wifi_chip_, getNanIface, invalid_name);
+    EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, status_and_iface2.first.code);
+    EXPECT_EQ(nullptr, status_and_iface2.second.get());
 }
 
 /*
@@ -477,10 +518,21 @@ TEST_F(WifiChipHidlTest, GetNanIface) {
  * doesn't remove the iface.
  */
 TEST_F(WifiChipHidlTest, RemoveNanIface) {
-    configureChipForIfaceType(IfaceType::NAN, false);
+    configureChipForIfaceType(IfaceType::NAN, gEnv->isNanOn);
+    if (!gEnv->isNanOn) return;
 
     sp<IWifiNanIface> nan_iface;
-    ASSERT_EQ(WifiStatusCode::ERROR_NOT_AVAILABLE, createNanIface(&nan_iface));
+    EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&nan_iface));
+    EXPECT_NE(nullptr, nan_iface.get());
+
+    std::string iface_name = getIfaceName(nan_iface);
+    std::string invalid_name = iface_name + "0";
+    EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeNanIface(invalid_name));
+
+    EXPECT_EQ(WifiStatusCode::SUCCESS, removeNanIface(iface_name));
+
+    // No such iface exists now. So, this should return failure.
+    EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeNanIface(iface_name));
 }
 
 /*
index e4382bce5d8583b68c47dd044f0348e8f4480414..0851cb2de595e50a5fafe12e277984f071508a11 100644 (file)
@@ -206,5 +206,7 @@ bool configureChipToSupportIfaceType(const sp<IWifiChip>& wifi_chip,
 void stopWifi() {
     sp<IWifi> wifi = getWifi();
     ASSERT_NE(wifi, nullptr);
-    ASSERT_EQ(HIDL_INVOKE(wifi, stop).code, WifiStatusCode::SUCCESS);
+    const auto status = HIDL_INVOKE(wifi, stop);
+    ASSERT_TRUE((status.code == WifiStatusCode::SUCCESS) ||
+                (status.code == WifiStatusCode::ERROR_NOT_AVAILABLE));
 }
index 39a0ebaff49778aa0011de15107ead0bb59d8a44..c4a19ddf2dc16fb70f00fabf2896e00eeece99d7 100644 (file)
@@ -24,6 +24,8 @@
 #include <android/hardware/wifi/1.0/IWifiRttController.h>
 #include <android/hardware/wifi/1.0/IWifiStaIface.h>
 
+#include <getopt.h>
+
 // Helper functions to obtain references to the various HIDL interface objects.
 // Note: We only have a single instance of each of these objects currently.
 // These helper functions should be modified to return vectors if we support
@@ -46,10 +48,46 @@ bool configureChipToSupportIfaceType(
 void stopWifi();
 
 class WifiHidlEnvironment : public ::testing::Environment {
- public:
-  virtual void SetUp() override {
-      stopWifi();
-      sleep(5);
-  }
-  virtual void TearDown() override {}
-};
\ No newline at end of file
+   protected:
+    virtual void SetUp() override {
+        stopWifi();
+        sleep(5);
+    }
+
+   public:
+    // Whether NaN feature is supported on the device.
+    bool isNanOn = false;
+
+    void usage(char* me, char* arg) {
+        fprintf(stderr,
+                "unrecognized option: %s\n\n"
+                "usage: %s <gtest options> <test options>\n\n"
+                "test options are:\n\n"
+                "-N, --nan_on: Whether NAN feature is supported\n",
+                arg, me);
+    }
+
+    int initFromOptions(int argc, char** argv) {
+        static struct option options[] = {{"nan_on", no_argument, 0, 'N'},
+                                          {0, 0, 0, 0}};
+
+        int c;
+        while ((c = getopt_long(argc, argv, "N", options, NULL)) >= 0) {
+            switch (c) {
+                case 'N':
+                    isNanOn = true;
+                    break;
+                default:
+                    usage(argv[0], argv[optind]);
+                    return 2;
+            }
+        }
+
+        if (optind < argc) {
+            usage(argv[0], argv[optind]);
+            return 2;
+        }
+
+        return 0;
+    }
+};
diff --git a/wifi/1.1/Android.bp b/wifi/1.1/Android.bp
new file mode 100644 (file)
index 0000000..aa6e937
--- /dev/null
@@ -0,0 +1,71 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+    name: "android.hardware.wifi@1.1_hal",
+    srcs: [
+        "IWifi.hal",
+        "IWifiChip.hal",
+    ],
+}
+
+genrule {
+    name: "android.hardware.wifi@1.1_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.wifi@1.1",
+    srcs: [
+        ":android.hardware.wifi@1.1_hal",
+    ],
+    out: [
+        "android/hardware/wifi/1.1/WifiAll.cpp",
+        "android/hardware/wifi/1.1/WifiChipAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.wifi@1.1_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.wifi@1.1",
+    srcs: [
+        ":android.hardware.wifi@1.1_hal",
+    ],
+    out: [
+        "android/hardware/wifi/1.1/IWifi.h",
+        "android/hardware/wifi/1.1/IHwWifi.h",
+        "android/hardware/wifi/1.1/BnHwWifi.h",
+        "android/hardware/wifi/1.1/BpHwWifi.h",
+        "android/hardware/wifi/1.1/BsWifi.h",
+        "android/hardware/wifi/1.1/IWifiChip.h",
+        "android/hardware/wifi/1.1/IHwWifiChip.h",
+        "android/hardware/wifi/1.1/BnHwWifiChip.h",
+        "android/hardware/wifi/1.1/BpHwWifiChip.h",
+        "android/hardware/wifi/1.1/BsWifiChip.h",
+    ],
+}
+
+cc_library {
+    name: "android.hardware.wifi@1.1",
+    defaults: ["hidl-module-defaults"],
+    generated_sources: ["android.hardware.wifi@1.1_genc++"],
+    generated_headers: ["android.hardware.wifi@1.1_genc++_headers"],
+    export_generated_headers: ["android.hardware.wifi@1.1_genc++_headers"],
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hardware.wifi@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.wifi@1.0",
+    ],
+}
diff --git a/wifi/1.1/Android.mk b/wifi/1.1/Android.mk
new file mode 100644 (file)
index 0000000..5f4bc6a
--- /dev/null
@@ -0,0 +1,63 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.wifi-V1.1-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+    android.hardware.wifi-V1.0-java \
+    android.hidl.base-V1.0-java \
+
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES += core-oj hwbinder
+
+#
+# Build IWifi.hal
+#
+GEN := $(intermediates)/android/hardware/wifi/V1_1/IWifi.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IWifi.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.wifi@1.1::IWifi
+
+$(GEN): $(LOCAL_PATH)/IWifi.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IWifiChip.hal
+#
+GEN := $(intermediates)/android/hardware/wifi/V1_1/IWifiChip.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IWifiChip.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.wifi@1.1::IWifiChip
+
+$(GEN): $(LOCAL_PATH)/IWifiChip.hal
+       $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/wifi/1.1/IWifi.hal b/wifi/1.1/IWifi.hal
new file mode 100644 (file)
index 0000000..bd48f57
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright 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.
+ */
+
+package android.hardware.wifi@1.1;
+
+import @1.0::IWifi;
+
+/**
+ * This is the root of the HAL module and is the interface returned when
+ * loading an implementation of the Wi-Fi HAL. There must be at most one
+ * module loaded in the system.
+ * IWifi.getChip() may return either a @1.0::IWifiChip or @1.1::IWifiChip.
+ */
+interface IWifi extends @1.0::IWifi {
+};
diff --git a/wifi/1.1/IWifiChip.hal b/wifi/1.1/IWifiChip.hal
new file mode 100644 (file)
index 0000000..1af1f71
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright 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.
+ */
+
+package android.hardware.wifi@1.1;
+
+import @1.0::IWifiChip;
+import @1.0::WifiStatus;
+
+/**
+ * Interface that represents a chip that must be configured as a single unit.
+ * The HAL/driver/firmware will be responsible for determining which phy is used
+ * to perform operations like NAN, RTT, etc.
+ */
+interface IWifiChip extends @1.0::IWifiChip {
+  /**
+   * Capabilities exposed by this chip.
+   */
+  enum ChipCapabilityMask : @1.0::IWifiChip.ChipCapabilityMask {
+    /**
+     * Set/Reset Tx Power limits.
+     */
+    SET_TX_POWER_LIMIT = 1 << 8,
+    /**
+     * Device to Device RTT.
+     */
+    D2D_RTT            = 1 << 9,
+    /**
+     * Device to AP RTT.
+     */
+    D2AP_RTT           = 1 << 10
+  };
+
+  /**
+   * List of preset wifi radio TX power levels for different scenarios.
+   * The actual power values (typically varies based on the channel,
+   * 802.11 connection type, number of MIMO streams, etc) for each scenario
+   * is defined by the OEM as a BDF file since it varies for each wifi chip
+   * vendor and device.
+   */
+  enum TxPowerScenario : uint32_t {
+    VOICE_CALL = 0,
+  };
+
+  /**
+   * API to select one of the preset TX power scenarios.
+   *
+   * The framework must invoke this method with the appropriate scenario to let
+   * the wifi chip change it's transmitting power levels.
+   * OEM's should define various power profiles for each of the scenarios
+   * above (defined in |TxPowerScenario|).
+   *
+   * @param scenario One of the preselected scenarios defined in
+   *        |TxPowerScenario|.
+   * @return status WifiStatus of the operation.
+   *         Possible status codes:
+   *         |WifiStatusCode.SUCCESS|,
+   *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+   *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+   *         |WifiStatusCode.NOT_AVAILABLE|,
+   *         |WifiStatusCode.UNKNOWN|
+   */
+  selectTxPowerScenario(TxPowerScenario scenario) generates (WifiStatus status);
+
+  /**
+   * API to reset TX power levels.
+   * This is used to indicate the end of the previously selected TX power
+   * scenario and let the wifi chip fall back to the default power values.
+   *
+   * @return status WifiStatus of the operation.
+   *         Possible status codes:
+   *         |WifiStatusCode.SUCCESS|,
+   *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+   *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+   *         |WifiStatusCode.NOT_AVAILABLE|,
+   *         |WifiStatusCode.UNKNOWN|
+   */
+  resetTxPowerScenario() generates (WifiStatus status);
+};
similarity index 96%
rename from wifi/1.0/default/Android.mk
rename to wifi/1.1/default/Android.mk
index 2564937cb7d864da4f04799dfc960743c0e06153..5758422303d20860a8bffdd29b900383b14585aa 100644 (file)
@@ -38,6 +38,7 @@ LOCAL_SRC_FILES := \
     wifi_status_util.cpp
 LOCAL_SHARED_LIBRARIES := \
     android.hardware.wifi@1.0 \
+    android.hardware.wifi@1.1 \
     libbase \
     libcutils \
     libhidlbase \
@@ -46,6 +47,6 @@ LOCAL_SHARED_LIBRARIES := \
     libnl \
     libutils \
     libwifi-hal \
-    libwifi-system
+    libwifi-system-iface
 LOCAL_INIT_RC := android.hardware.wifi@1.0-service.rc
 include $(BUILD_EXECUTABLE)
similarity index 98%
rename from wifi/1.0/default/hidl_callback_util.h
rename to wifi/1.1/default/hidl_callback_util.h
index b7100c8ac21f4d69eec0b03699e5d028d45f875b..fb136222530e15123e27c1ecf5c0806a6f5ae1b3 100644 (file)
@@ -51,7 +51,7 @@ class HidlDeathHandler : public android::hardware::hidl_death_recipient {
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace hidl_callback_util {
 template <typename CallbackType>
@@ -114,7 +114,7 @@ class HidlCallbackHandler {
 
 }  // namespace hidl_callback_util
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 97%
rename from wifi/1.0/default/hidl_return_util.h
rename to wifi/1.1/default/hidl_return_util.h
index 3f6364be3f8fa77b30b4b45557097f3bd55165cb..2f95c23d7e71d8cf6eede1b40279d7d9904b18f4 100644 (file)
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace hidl_return_util {
+using namespace android::hardware::wifi::V1_0;
 
 /**
  * These utility functions are used to invoke a method on the provided
@@ -106,7 +107,7 @@ Return<void> validateAndCall(
 
 }  // namespace hidl_util
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 96%
rename from wifi/1.0/default/hidl_struct_util.cpp
rename to wifi/1.1/default/hidl_struct_util.cpp
index d8adcf69e285e0b71bcfaa38c22a246cc0b38514..c53cdc596d18d91b881e2844bf8ea098efa94cf2 100644 (file)
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace hidl_struct_util {
 
+hidl_string safeConvertChar(const char* str, size_t max_len) {
+  const char* c = str;
+  size_t size = 0;
+  while (*c && (unsigned char)*c < 128 && size < max_len) {
+    ++size;
+    ++c;
+  }
+  return hidl_string(str, size);
+}
+
 IWifiChip::ChipCapabilityMask convertLegacyLoggerFeatureToHidlChipCapability(
     uint32_t feature) {
   using HidlChipCaps = IWifiChip::ChipCapabilityMask;
@@ -56,6 +66,21 @@ convertLegacyLoggerFeatureToHidlStaIfaceCapability(uint32_t feature) {
   return {};
 }
 
+V1_1::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability(
+    uint32_t feature) {
+  using HidlChipCaps = V1_1::IWifiChip::ChipCapabilityMask;
+  switch (feature) {
+    case WIFI_FEATURE_SET_TX_POWER_LIMIT:
+      return HidlChipCaps::SET_TX_POWER_LIMIT;
+    case WIFI_FEATURE_D2D_RTT:
+      return HidlChipCaps::D2D_RTT;
+    case WIFI_FEATURE_D2AP_RTT:
+      return HidlChipCaps::D2AP_RTT;
+  };
+  CHECK(false) << "Unknown legacy feature: " << feature;
+  return {};
+}
+
 IWifiStaIface::StaIfaceCapabilityMask
 convertLegacyFeatureToHidlStaIfaceCapability(uint32_t feature) {
   using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
@@ -92,7 +117,9 @@ convertLegacyFeatureToHidlStaIfaceCapability(uint32_t feature) {
 }
 
 bool convertLegacyFeaturesToHidlChipCapabilities(
-    uint32_t legacy_logger_feature_set, uint32_t* hidl_caps) {
+    uint32_t legacy_feature_set,
+    uint32_t legacy_logger_feature_set,
+    uint32_t* hidl_caps) {
   if (!hidl_caps) {
     return false;
   }
@@ -107,6 +134,13 @@ bool convertLegacyFeaturesToHidlChipCapabilities(
       *hidl_caps |= convertLegacyLoggerFeatureToHidlChipCapability(feature);
     }
   }
+  for (const auto feature : {WIFI_FEATURE_SET_TX_POWER_LIMIT,
+                             WIFI_FEATURE_D2D_RTT,
+                             WIFI_FEATURE_D2AP_RTT}) {
+    if (feature & legacy_feature_set) {
+      *hidl_caps |= convertLegacyFeatureToHidlChipCapability(feature);
+    }
+  }
   // There are no flags for these 3 in the legacy feature set. Adding them to
   // the set because all the current devices support it.
   *hidl_caps |= HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA;
@@ -134,7 +168,8 @@ bool convertLegacyDebugRingBufferStatusToHidl(
     return false;
   }
   *hidl_status = {};
-  hidl_status->ringName = reinterpret_cast<const char*>(legacy_status.name);
+  hidl_status->ringName = safeConvertChar(reinterpret_cast<const char*>(legacy_status.name),
+        sizeof(legacy_status.name));
   hidl_status->flags = 0;
   for (const auto flag : {WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES,
                           WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES}) {
@@ -222,6 +257,15 @@ bool convertLegacyWakeReasonStatsToHidl(
   return true;
 }
 
+legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy(
+    V1_1::IWifiChip::TxPowerScenario hidl_scenario) {
+  switch (hidl_scenario) {
+    case V1_1::IWifiChip::TxPowerScenario::VOICE_CALL:
+      return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL;
+  };
+  CHECK(false);
+}
+
 bool convertLegacyFeaturesToHidlStaCapabilities(
     uint32_t legacy_feature_set,
     uint32_t legacy_logger_feature_set,
@@ -230,7 +274,6 @@ bool convertLegacyFeaturesToHidlStaCapabilities(
     return false;
   }
   *hidl_caps = {};
-  *hidl_caps = 0;
   using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
   for (const auto feature : {legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED}) {
     if (feature & legacy_logger_feature_set) {
@@ -449,7 +492,8 @@ bool convertLegacyGscanResultToHidl(
   hidl_scan_result->timeStampInUs = legacy_scan_result.ts;
   hidl_scan_result->ssid = std::vector<uint8_t>(
       legacy_scan_result.ssid,
-      legacy_scan_result.ssid + strlen(legacy_scan_result.ssid));
+      legacy_scan_result.ssid + strnlen(legacy_scan_result.ssid,
+            sizeof(legacy_scan_result.ssid) - 1));
   memcpy(hidl_scan_result->bssid.data(),
          legacy_scan_result.bssid,
          hidl_scan_result->bssid.size());
@@ -882,6 +926,12 @@ NanStatusType convertLegacyNanStatusTypeToHidl(
   CHECK(false);
 }
 
+void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len,
+    WifiNanStatus* wifiNanStatus) {
+  wifiNanStatus->status = convertLegacyNanStatusTypeToHidl(type);
+  wifiNanStatus->description = safeConvertChar(str, max_len);
+}
+
 bool convertHidlNanEnableRequestToLegacy(
     const NanEnableRequest& hidl_request,
     legacy_hal::NanEnableRequest* legacy_request) {
@@ -914,7 +964,14 @@ bool convertHidlNanEnableRequestToLegacy(
   legacy_request->sid_beacon_val =
         (hidl_request.configParams.includePublishServiceIdsInBeacon ? 0x1 : 0x0)
             | (hidl_request.configParams.numberOfPublishServiceIdsInBeacon << 1);
-  // TODO: b/35195516 connect SubscribeServiceIds to legacy HAL once implemented
+  legacy_request->config_subscribe_sid_beacon = 1;
+  if (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon > 127) {
+    LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: numberOfSubscribeServiceIdsInBeacon > 127";
+    return false;
+  }
+  legacy_request->subscribe_sid_beacon_val =
+        (hidl_request.configParams.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0)
+            | (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon << 1);
   legacy_request->config_rssi_window_size = 1;
   legacy_request->rssi_window_size_val = hidl_request.configParams.rssiWindowSize;
   legacy_request->config_disc_mac_addr_randomization = 1;
@@ -1100,7 +1157,7 @@ bool convertHidlNanPublishRequestToLegacy(
       return false;
     }
     if (legacy_request->key_info.body.passphrase_info.passphrase_len
-            > NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+            > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
       LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: passphrase_len too large";
       return false;
     }
@@ -1216,7 +1273,7 @@ bool convertHidlNanSubscribeRequestToLegacy(
       return false;
     }
     if (legacy_request->key_info.body.passphrase_info.passphrase_len
-            > NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+            > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
       LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: passphrase_len too large";
       return false;
     }
@@ -1321,7 +1378,14 @@ bool convertHidlNanConfigRequestToLegacy(
   }
   legacy_request->sid_beacon = (hidl_request.includePublishServiceIdsInBeacon ? 0x1 : 0x0)
         | (hidl_request.numberOfPublishServiceIdsInBeacon << 1);
-  // TODO: b/35195516 connect SubscribeServiceIds to legacy HAL once implemented
+  legacy_request->config_subscribe_sid_beacon = 1;
+  if (hidl_request.numberOfSubscribeServiceIdsInBeacon > 127) {
+    LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: numberOfSubscribeServiceIdsInBeacon > 127";
+    return false;
+  }
+  legacy_request->subscribe_sid_beacon_val =
+        (hidl_request.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0)
+            | (hidl_request.numberOfSubscribeServiceIdsInBeacon << 1);
   legacy_request->config_rssi_window_size = 1;
   legacy_request->rssi_window_size_val = hidl_request.rssiWindowSize;
   legacy_request->config_disc_mac_addr_randomization = 1;
@@ -1433,7 +1497,7 @@ bool convertHidlNanDataPathInitiatorRequestToLegacy(
       return false;
     }
     if (legacy_request->key_info.body.passphrase_info.passphrase_len
-            > NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+            > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
       LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: passphrase_len too large";
       return false;
     }
@@ -1497,7 +1561,7 @@ bool convertHidlNanDataPathIndicationResponseToLegacy(
       return false;
     }
     if (legacy_request->key_info.body.passphrase_info.passphrase_len
-            > NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+            > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
       LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: passphrase_len too large";
       return false;
     }
@@ -1525,8 +1589,8 @@ bool convertLegacyNanResponseHeaderToHidl(
   }
   *wifiNanStatus = {};
 
-  wifiNanStatus->status = convertLegacyNanStatusTypeToHidl(legacy_response.status);
-  wifiNanStatus->description = legacy_response.nan_error;
+  convertToWifiNanStatus(legacy_response.status, legacy_response.nan_error,
+        sizeof(legacy_response.nan_error), wifiNanStatus);
   return true;
 }
 
@@ -2145,7 +2209,7 @@ bool convertLegacyVectorOfRttResultToHidl(
 }
 }  // namespace hidl_struct_util
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 92%
rename from wifi/1.0/default/hidl_struct_util.h
rename to wifi/1.1/default/hidl_struct_util.h
index 41e97b35904055bb6197ddeccaa7290eb153b451..747fd2f4abe7fd032b71b7f49688b431e4d01abc 100644 (file)
@@ -19,7 +19,9 @@
 
 #include <vector>
 
-#include <android/hardware/wifi/1.0/IWifi.h>
+#include <android/hardware/wifi/1.0/types.h>
+#include <android/hardware/wifi/1.0/IWifiChip.h>
+#include <android/hardware/wifi/1.1/IWifiChip.h>
 
 #include "wifi_legacy_hal.h"
 
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace hidl_struct_util {
+using namespace android::hardware::wifi::V1_0;
 
 // Chip conversion methods.
 bool convertLegacyFeaturesToHidlChipCapabilities(
-    uint32_t legacy_logger_feature_set, uint32_t* hidl_caps);
+    uint32_t legacy_feature_set,
+    uint32_t legacy_logger_feature_set,
+    uint32_t* hidl_caps);
 bool convertLegacyDebugRingBufferStatusToHidl(
     const legacy_hal::wifi_ring_buffer_status& legacy_status,
     WifiDebugRingBufferStatus* hidl_status);
@@ -48,6 +53,8 @@ bool convertLegacyVectorOfDebugRingBufferStatusToHidl(
 bool convertLegacyWakeReasonStatsToHidl(
     const legacy_hal::WakeReasonStats& legacy_stats,
     WifiDebugHostWakeReasonStats* hidl_stats);
+legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy(
+    V1_1::IWifiChip::TxPowerScenario hidl_scenario);
 
 // STA iface conversion methods.
 bool convertLegacyFeaturesToHidlStaCapabilities(
@@ -94,7 +101,8 @@ bool convertLegacyVectorOfDebugRxPacketFateToHidl(
     std::vector<WifiDebugRxPacketFateReport>* hidl_fates);
 
 // NAN iface conversion methods.
-NanStatusType convertLegacyNanStatusTypeToHidl(legacy_hal::NanStatusType type);
+void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len,
+    WifiNanStatus* wifiNanStatus);
 bool convertHidlNanEnableRequestToLegacy(
     const NanEnableRequest& hidl_request,
     legacy_hal::NanEnableRequest* legacy_request);
@@ -160,7 +168,7 @@ bool convertLegacyVectorOfRttResultToHidl(
     std::vector<RttResult>* hidl_results);
 }  // namespace hidl_struct_util
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 96%
rename from wifi/1.0/default/hidl_sync_util.cpp
rename to wifi/1.1/default/hidl_sync_util.cpp
index 7d47f2f7bd713692b0fa46e7db4eee01600a335c..ba18e344aa6add54d8831c2a2e3767a76475d067 100644 (file)
@@ -23,7 +23,7 @@ std::recursive_mutex g_mutex;
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace hidl_sync_util {
 
@@ -33,7 +33,7 @@ std::unique_lock<std::recursive_mutex> acquireGlobalLock() {
 
 }  // namespace hidl_sync_util
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 96%
rename from wifi/1.0/default/hidl_sync_util.h
rename to wifi/1.1/default/hidl_sync_util.h
index 6631e55bca522cdd45b431499077a13b3bfc5edf..0e882df50b936cbedd25f4c67b202d7b76f0f3dc 100644 (file)
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace hidl_sync_util {
 std::unique_lock<std::recursive_mutex> acquireGlobalLock();
 }  // namespace hidl_sync_util
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 88%
rename from wifi/1.0/default/service.cpp
rename to wifi/1.1/default/service.cpp
index 059304e3356114f24553e52c7f3bd01b613798e3..b4aed6c199d45f67c58ea50aaa6b9ad162615cbc 100644 (file)
@@ -27,13 +27,13 @@ using android::hardware::joinRpcThreadpool;
 int main(int /*argc*/, char** argv) {
   android::base::InitLogging(argv,
                              android::base::LogdLogger(android::base::SYSTEM));
-  LOG(INFO) << "Wifi Hal is starting up...";
+  LOG(INFO) << "Wifi Hal is booting up...";
 
   configureRpcThreadpool(1, true /* callerWillJoin */);
 
   // Setup hwbinder service
-  android::sp<android::hardware::wifi::V1_0::IWifi> service =
-      new android::hardware::wifi::V1_0::implementation::Wifi();
+  android::sp<android::hardware::wifi::V1_1::IWifi> service =
+      new android::hardware::wifi::V1_1::implementation::Wifi();
   CHECK_EQ(service->registerAsService(), android::NO_ERROR)
       << "Failed to register wifi HAL";
 
similarity index 97%
rename from wifi/1.0/default/wifi.cpp
rename to wifi/1.1/default/wifi.cpp
index b48844ef2a0fe4a3a820e0161cedc29dd7c80eae..8456b90e9f05dcc20e8aff010b7f0fc307023171 100644 (file)
@@ -28,7 +28,7 @@ static constexpr android::hardware::wifi::V1_0::ChipId kChipId = 0;
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
@@ -108,14 +108,15 @@ WifiStatus Wifi::startInternal() {
         LOG(ERROR) << "Failed to invoke onStart callback";
       };
     }
+    LOG(INFO) << "Wifi HAL started";
   } else {
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
       if (!callback->onFailure(wifi_status).isOk()) {
         LOG(ERROR) << "Failed to invoke onFailure callback";
       }
     }
+    LOG(ERROR) << "Wifi HAL start failed";
   }
-  LOG(INFO) << "Wifi HAL started";
   return wifi_status;
 }
 
@@ -126,6 +127,12 @@ WifiStatus Wifi::stopInternal() {
     return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,
                             "HAL is stopping");
   }
+  // Clear the chip object and its child objects since the HAL is now
+  // stopped.
+  if (chip_.get()) {
+    chip_->invalidate();
+    chip_.clear();
+  }
   WifiStatus wifi_status = stopLegacyHalAndDeinitializeModeController();
   if (wifi_status.code == WifiStatusCode::SUCCESS) {
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
@@ -133,20 +140,15 @@ WifiStatus Wifi::stopInternal() {
         LOG(ERROR) << "Failed to invoke onStop callback";
       };
     }
+    LOG(INFO) << "Wifi HAL stopped";
   } else {
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
       if (!callback->onFailure(wifi_status).isOk()) {
         LOG(ERROR) << "Failed to invoke onFailure callback";
       }
     }
+    LOG(ERROR) << "Wifi HAL stop failed";
   }
-  // Clear the chip object and its child objects since the HAL is now
-  // stopped.
-  if (chip_.get()) {
-    chip_->invalidate();
-    chip_.clear();
-  }
-  LOG(INFO) << "Wifi HAL stopped";
   return wifi_status;
 }
 
@@ -195,7 +197,7 @@ WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController() {
   return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 94%
rename from wifi/1.0/default/wifi.h
rename to wifi/1.1/default/wifi.h
index c6fa84cb37609360fbee3ac5ecf61fa99c8f778e..1ade2d8b9bc7bda3594800741ee13d29757b156c 100644 (file)
@@ -20,7 +20,7 @@
 #include <functional>
 
 #include <android-base/macros.h>
-#include <android/hardware/wifi/1.0/IWifi.h>
+#include <android/hardware/wifi/1.1/IWifi.h>
 #include <utils/Looper.h>
 
 #include "hidl_callback_util.h"
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
+using namespace android::hardware::wifi::V1_0;
 
 /**
  * Root HIDL interface object used to control the Wifi HAL.
  */
-class Wifi : public IWifi {
+class Wifi : public V1_1::IWifi {
  public:
   Wifi();
 
@@ -79,7 +80,7 @@ class Wifi : public IWifi {
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 98%
rename from wifi/1.0/default/wifi_ap_iface.cpp
rename to wifi/1.1/default/wifi_ap_iface.cpp
index e2beec2c6268fe4a133a6d3d82278314c6d7a948..150a6cc06f7b386907ed6e6d64230e89edf95cf7 100644 (file)
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
@@ -100,7 +100,7 @@ WifiApIface::getValidFrequenciesForBandInternal(WifiBand band) {
   return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies};
 }
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 94%
rename from wifi/1.0/default/wifi_ap_iface.h
rename to wifi/1.1/default/wifi_ap_iface.h
index efc168a08a0f1ae1d1c0a3b83e521d5fa0960837..608fe6b5ac32dc27271f9c09718121ce4876a791 100644 (file)
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
+using namespace android::hardware::wifi::V1_0;
 
 /**
  * HIDL interface object used to control a AP Iface instance.
  */
-class WifiApIface : public IWifiApIface {
+class WifiApIface : public V1_0::IWifiApIface {
  public:
   WifiApIface(const std::string& ifname,
               const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
@@ -63,7 +64,7 @@ class WifiApIface : public IWifiApIface {
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 95%
rename from wifi/1.0/default/wifi_chip.cpp
rename to wifi/1.1/default/wifi_chip.cpp
index 770c83f181d5600a7df33e0884b8a1ec9905a477..2f4023405f8eeebf7ddfb70e3fdded53c27918c3 100644 (file)
@@ -46,7 +46,7 @@ void invalidateAndClear(sp<Iface>& iface) {
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
@@ -343,6 +343,23 @@ Return<void> WifiChip::enableDebugErrorAlerts(
                          enable);
 }
 
+Return<void> WifiChip::selectTxPowerScenario(
+    TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) {
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::selectTxPowerScenarioInternal,
+                         hidl_status_cb,
+                         scenario);
+}
+
+Return<void> WifiChip::resetTxPowerScenario(
+    resetTxPowerScenario_cb hidl_status_cb) {
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::resetTxPowerScenarioInternal,
+                         hidl_status_cb);
+}
+
 void WifiChip::invalidateAndRemoveAllIfaces() {
   invalidateAndClear(ap_iface_);
   invalidateAndClear(nan_iface_);
@@ -370,7 +387,13 @@ WifiStatus WifiChip::registerEventCallbackInternal(
 
 std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
   legacy_hal::wifi_error legacy_status;
+  uint32_t legacy_feature_set;
   uint32_t legacy_logger_feature_set;
+  std::tie(legacy_status, legacy_feature_set) =
+      legacy_hal_.lock()->getSupportedFeatureSet();
+  if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+    return {createWifiStatusFromLegacyError(legacy_status), 0};
+  }
   std::tie(legacy_status, legacy_logger_feature_set) =
       legacy_hal_.lock()->getLoggerSupportedFeatureSet();
   if (legacy_status != legacy_hal::WIFI_SUCCESS) {
@@ -378,7 +401,7 @@ std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
   }
   uint32_t hidl_caps;
   if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
-          legacy_logger_feature_set, &hidl_caps)) {
+          legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
     return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
   }
   return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
@@ -801,6 +824,17 @@ WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
   return createWifiStatusFromLegacyError(legacy_status);
 }
 
+WifiStatus WifiChip::selectTxPowerScenarioInternal(TxPowerScenario scenario) {
+  auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
+      hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
+  return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiChip::resetTxPowerScenarioInternal() {
+  auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario();
+  return createWifiStatusFromLegacyError(legacy_status);
+}
+
 WifiStatus WifiChip::handleChipConfiguration(ChipModeId mode_id) {
   // If the chip is already configured in a different mode, stop
   // the legacy HAL and then start it after firmware mode change.
@@ -869,7 +903,7 @@ WifiStatus WifiChip::registerDebugRingBufferCallback() {
 }
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 94%
rename from wifi/1.0/default/wifi_chip.h
rename to wifi/1.1/default/wifi_chip.h
index 406938c361417666a4b120dea1e712c8c37daf85..e88100bd23d6764182461b9ad935439cba0f27c9 100644 (file)
@@ -20,7 +20,7 @@
 #include <map>
 
 #include <android-base/macros.h>
-#include <android/hardware/wifi/1.0/IWifiChip.h>
+#include <android/hardware/wifi/1.1/IWifiChip.h>
 
 #include "hidl_callback_util.h"
 #include "wifi_ap_iface.h"
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
+using namespace android::hardware::wifi::V1_0;
 
 /**
  * HIDL interface object used to control a Wifi HAL chip instance.
  * Since there is only a single chip instance used today, there is no
  * identifying handle information stored here.
  */
-class WifiChip : public IWifiChip {
+class WifiChip : public V1_1::IWifiChip {
  public:
   WifiChip(
       ChipId chip_id,
@@ -125,6 +126,11 @@ class WifiChip : public IWifiChip {
       getDebugHostWakeReasonStats_cb hidl_status_cb) override;
   Return<void> enableDebugErrorAlerts(
       bool enable, enableDebugErrorAlerts_cb hidl_status_cb) override;
+  Return<void> selectTxPowerScenario(
+      TxPowerScenario scenario,
+      selectTxPowerScenario_cb hidl_status_cb) override;
+  Return<void> resetTxPowerScenario(
+      resetTxPowerScenario_cb hidl_status_cb) override;
 
  private:
   void invalidateAndRemoveAllIfaces();
@@ -176,6 +182,8 @@ class WifiChip : public IWifiChip {
   std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
   getDebugHostWakeReasonStatsInternal();
   WifiStatus enableDebugErrorAlertsInternal(bool enable);
+  WifiStatus selectTxPowerScenarioInternal(TxPowerScenario scenario);
+  WifiStatus resetTxPowerScenarioInternal();
 
   WifiStatus handleChipConfiguration(ChipModeId mode_id);
   WifiStatus registerDebugRingBufferCallback();
@@ -201,7 +209,7 @@ class WifiChip : public IWifiChip {
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 96%
rename from wifi/1.0/default/wifi_feature_flags.h
rename to wifi/1.1/default/wifi_feature_flags.h
index 3502fbdeb27c86f809f78c7fbc789f94ce246b4a..5939ffbefb875f2766809f7f59b65267aca0dc33 100644 (file)
@@ -20,7 +20,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 
 class WifiFeatureFlags {
@@ -33,7 +33,7 @@ class WifiFeatureFlags {
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 98%
rename from wifi/1.0/default/wifi_legacy_hal.cpp
rename to wifi/1.1/default/wifi_legacy_hal.cpp
index b6a7550b39eed026e9367f92451d518d096613ea..7d683d3fe9a83a9efab5cb85742a8b1e83ea6f3b 100644 (file)
@@ -47,7 +47,7 @@ std::vector<char> makeCharVec(const std::string& str) {
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace legacy_hal {
 // Legacy HAL functions accept "C" style function pointers, so use global
@@ -752,6 +752,15 @@ wifi_error WifiLegacyHal::setScanningMacOui(const std::array<uint8_t, 3>& oui) {
                                                       oui_internal.data());
 }
 
+wifi_error WifiLegacyHal::selectTxPowerScenario(wifi_power_scenario scenario) {
+  return global_func_table_.wifi_select_tx_power_scenario(
+      wlan_interface_handle_, scenario);
+}
+
+wifi_error WifiLegacyHal::resetTxPowerScenario() {
+  return global_func_table_.wifi_reset_tx_power_scenario(wlan_interface_handle_);
+}
+
 std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet() {
   uint32_t supported_features;
   wifi_error status = global_func_table_.wifi_get_logger_supported_feature_set(
@@ -1197,11 +1206,19 @@ wifi_error WifiLegacyHal::nanDataIndicationResponse(
       id, wlan_interface_handle_, &msg_internal);
 }
 
+typedef struct {
+    u8 num_ndp_instances;
+    NanDataPathId ndp_instance_id;
+} NanDataPathEndSingleNdpIdRequest;
+
 wifi_error WifiLegacyHal::nanDataEnd(transaction_id id,
-                                     const NanDataPathEndRequest& msg) {
-  NanDataPathEndRequest msg_internal(msg);
-  return global_func_table_.wifi_nan_data_end(
-      id, wlan_interface_handle_, &msg_internal);
+                                     uint32_t ndpInstanceId) {
+  NanDataPathEndSingleNdpIdRequest msg;
+  msg.num_ndp_instances = 1;
+  msg.ndp_instance_id = ndpInstanceId;
+  wifi_error status = global_func_table_.wifi_nan_data_end(
+      id, wlan_interface_handle_, (NanDataPathEndRequest*)&msg);
+  return status;
 }
 
 wifi_error WifiLegacyHal::setCountryCode(std::array<int8_t, 2> code) {
@@ -1308,7 +1325,7 @@ void WifiLegacyHal::invalidate() {
 
 }  // namespace legacy_hal
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 98%
rename from wifi/1.0/default/wifi_legacy_hal.h
rename to wifi/1.1/default/wifi_legacy_hal.h
index 1656f682ae41cee6b27667f335df75c2ddffa900..caa1bd50fc09b6596bdc93c831da8cce221062a3 100644 (file)
@@ -26,7 +26,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 // This is in a separate namespace to prevent typename conflicts between
 // the legacy HAL types and the HIDL interface types.
@@ -205,6 +205,8 @@ class WifiLegacyHal {
       uint32_t period_in_ms);
   wifi_error stopSendingOffloadedPacket(uint32_t cmd_id);
   wifi_error setScanningMacOui(const std::array<uint8_t, 3>& oui);
+  wifi_error selectTxPowerScenario(wifi_power_scenario scenario);
+  wifi_error resetTxPowerScenario();
   // Logger/debug functions.
   std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet();
   wifi_error startPktFateMonitoring();
@@ -268,7 +270,7 @@ class WifiLegacyHal {
                                      const NanDataPathInitiatorRequest& msg);
   wifi_error nanDataIndicationResponse(
       transaction_id id, const NanDataPathIndicationResponse& msg);
-  wifi_error nanDataEnd(transaction_id id, const NanDataPathEndRequest& msg);
+  wifi_error nanDataEnd(transaction_id id, uint32_t ndpInstanceId);
   // AP functions.
   wifi_error setCountryCode(std::array<int8_t, 2> code);
 
@@ -298,7 +300,7 @@ class WifiLegacyHal {
 
 }  // namespace legacy_hal
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 97%
rename from wifi/1.0/default/wifi_legacy_hal_stubs.cpp
rename to wifi/1.1/default/wifi_legacy_hal_stubs.cpp
index 2973430dbd3fdc2c44b2e74e6c6198347573d88f..c02e3ba2928b3a7a453b20b1224d53f36319e92c 100644 (file)
@@ -20,7 +20,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace legacy_hal {
 template <typename>
@@ -132,11 +132,13 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) {
   populateStubFor(&hal_fn->wifi_get_roaming_capabilities);
   populateStubFor(&hal_fn->wifi_enable_firmware_roaming);
   populateStubFor(&hal_fn->wifi_configure_roaming);
+  populateStubFor(&hal_fn->wifi_select_tx_power_scenario);
+  populateStubFor(&hal_fn->wifi_reset_tx_power_scenario);
   return true;
 }
 }  // namespace legacy_hal
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 96%
rename from wifi/1.0/default/wifi_legacy_hal_stubs.h
rename to wifi/1.1/default/wifi_legacy_hal_stubs.h
index 1cb5f9d5219ff91c7a541a160987537097975299..bfc4c9b864d8d40d7b83eae6453d5564b71128a3 100644 (file)
@@ -20,7 +20,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace legacy_hal {
 #include <hardware_legacy/wifi_hal.h>
@@ -28,7 +28,7 @@ namespace legacy_hal {
 bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn);
 }  // namespace legacy_hal
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 98%
rename from wifi/1.0/default/wifi_mode_controller.cpp
rename to wifi/1.1/default/wifi_mode_controller.cpp
index 7e82d4caf9596eb760ea1822b94aa3cb8d09ee09..b8a44c2531c6aab66b5bfbd158348286c4850f4a 100644 (file)
@@ -48,7 +48,7 @@ int convertIfaceTypeToFirmwareMode(IfaceType type) {
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace mode_controller {
 
@@ -80,7 +80,7 @@ bool WifiModeController::deinitialize() {
 }
 }  // namespace mode_controller
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 95%
rename from wifi/1.0/default/wifi_mode_controller.h
rename to wifi/1.1/default/wifi_mode_controller.h
index a4147a905df66e9926a325155cd2b9d245ac215b..69845095bcb1db5cd94588ca246180afb8cd9523 100644 (file)
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace mode_controller {
+using namespace android::hardware::wifi::V1_0;
+
 /**
  * Class that encapsulates all firmware mode configuration.
  * This class will perform the necessary firmware reloads to put the chip in the
@@ -51,7 +53,7 @@ class WifiModeController {
 
 }  // namespace mode_controller
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 97%
rename from wifi/1.0/default/wifi_nan_iface.cpp
rename to wifi/1.1/default/wifi_nan_iface.cpp
index 6977fc02e94895e8cb5be75fd2da6341f4afccfb..a111d0610ab3d18bd24aebe9a8d6c746f7046c92 100644 (file)
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
@@ -217,8 +217,8 @@ WifiNanIface::WifiNanIface(
         return;
       }
       WifiNanStatus status;
-      status.status = hidl_struct_util::convertLegacyNanStatusTypeToHidl(msg.reason);
-      status.description = msg.nan_reason;
+      hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, sizeof(msg.nan_reason),
+            &status);
 
       for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
         if (!callback->eventDisabled(status).isOk()) {
@@ -235,8 +235,8 @@ WifiNanIface::WifiNanIface(
         return;
       }
       WifiNanStatus status;
-      status.status = hidl_struct_util::convertLegacyNanStatusTypeToHidl(msg.reason);
-      status.description = msg.nan_reason;
+      hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, sizeof(msg.nan_reason),
+            &status);
 
       for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
         if (!callback->eventPublishTerminated(msg.publish_id, status).isOk()) {
@@ -253,8 +253,8 @@ WifiNanIface::WifiNanIface(
         return;
       }
       WifiNanStatus status;
-      status.status = hidl_struct_util::convertLegacyNanStatusTypeToHidl(msg.reason);
-      status.description = msg.nan_reason;
+      hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, sizeof(msg.nan_reason),
+            &status);
 
       for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
         if (!callback->eventSubscribeTerminated(msg.subscribe_id, status).isOk()) {
@@ -328,8 +328,8 @@ WifiNanIface::WifiNanIface(
         return;
       }
       WifiNanStatus status;
-      status.status = hidl_struct_util::convertLegacyNanStatusTypeToHidl(msg.reason);
-      status.description = msg.nan_reason;
+      hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, sizeof(msg.nan_reason),
+            &status);
 
       for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
         if (!callback->eventTransmitFollowup(msg.id, status).isOk()) {
@@ -420,6 +420,11 @@ WifiNanIface::WifiNanIface(
 }
 
 void WifiNanIface::invalidate() {
+  // send commands to HAL to actually disable and destroy interfaces
+  legacy_hal_.lock()->nanDisableRequest(0xFFFF);
+  legacy_hal_.lock()->nanDataInterfaceDelete(0xFFFE, "aware_data0");
+  legacy_hal_.lock()->nanDataInterfaceDelete(0xFFFD, "aware_data1");
+
   legacy_hal_.reset();
   event_cb_handler_.invalidate();
   is_valid_ = false;
@@ -752,19 +757,13 @@ WifiStatus WifiNanIface::respondToDataPathIndicationRequestInternal(
 }
 WifiStatus WifiNanIface::terminateDataPathRequestInternal(
     uint16_t cmd_id, uint32_t ndpInstanceId) {
-  legacy_hal::NanDataPathEndRequest* legacy_msg = (legacy_hal::NanDataPathEndRequest*)malloc(
-      sizeof(legacy_hal::NanDataPathEndRequest) + sizeof(uint32_t));
-  legacy_msg->num_ndp_instances = 1;
-  legacy_msg->ndp_instance_id[0] = ndpInstanceId;
-
   legacy_hal::wifi_error legacy_status =
-      legacy_hal_.lock()->nanDataEnd(cmd_id, *legacy_msg);
-  free(legacy_msg);
+      legacy_hal_.lock()->nanDataEnd(cmd_id, ndpInstanceId);
   return createWifiStatusFromLegacyError(legacy_status);
 }
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 97%
rename from wifi/1.0/default/wifi_nan_iface.h
rename to wifi/1.1/default/wifi_nan_iface.h
index e1edd2924376a51ba96b65d2b520c9f1e4f1e5ae..260d8ab4ef6cb92ed991ce5215ce9f04ec3cc5c2 100644 (file)
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
+using namespace android::hardware::wifi::V1_0;
 
 /**
  * HIDL interface object used to control a NAN Iface instance.
  */
-class WifiNanIface : public IWifiNanIface {
+class WifiNanIface : public V1_0::IWifiNanIface {
  public:
   WifiNanIface(const std::string& ifname,
                const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
@@ -132,7 +133,7 @@ class WifiNanIface : public IWifiNanIface {
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 98%
rename from wifi/1.0/default/wifi_p2p_iface.cpp
rename to wifi/1.1/default/wifi_p2p_iface.cpp
index 0d055f131919877bc47e719e00f726f293d51020..78e08db9701755d1fccf79d7fb239d7bc578f5f2 100644 (file)
@@ -23,7 +23,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
@@ -64,7 +64,7 @@ std::pair<WifiStatus, IfaceType> WifiP2pIface::getTypeInternal() {
 }
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 92%
rename from wifi/1.0/default/wifi_p2p_iface.h
rename to wifi/1.1/default/wifi_p2p_iface.h
index d2982db8c5a8a789aa5991c2b2b5ece865778522..f563a3d3144d0cb69ef94348a13a823dc8d03bdb 100644 (file)
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
+using namespace android::hardware::wifi::V1_0;
 
 /**
  * HIDL interface object used to control a P2P Iface instance.
  */
-class WifiP2pIface : public IWifiP2pIface {
+class WifiP2pIface : public V1_0::IWifiP2pIface {
  public:
   WifiP2pIface(const std::string& ifname,
                const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
@@ -56,7 +57,7 @@ class WifiP2pIface : public IWifiP2pIface {
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 99%
rename from wifi/1.0/default/wifi_rtt_controller.cpp
rename to wifi/1.1/default/wifi_rtt_controller.cpp
index f18feaea3e64eccecedee0b87b7db86b6bc8a7ff..9ef702da143147ec255b1b4cf84a03bab5265f1f 100644 (file)
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
@@ -291,7 +291,7 @@ WifiStatus WifiRttController::disableResponderInternal(uint32_t cmd_id) {
   return createWifiStatusFromLegacyError(legacy_status);
 }
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 97%
rename from wifi/1.0/default/wifi_rtt_controller.h
rename to wifi/1.1/default/wifi_rtt_controller.h
index 7c0abcaf87a4c84538fa2d6cb83bbccd3d97d182..543788574a547a5cc763f49e8ed5164c7651eb2f 100644 (file)
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 
 /**
  * HIDL interface object used to control all RTT operations.
  */
-class WifiRttController : public IWifiRttController {
+class WifiRttController : public V1_0::IWifiRttController {
  public:
   WifiRttController(const sp<IWifiIface>& bound_iface,
                     const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
@@ -97,7 +97,7 @@ class WifiRttController : public IWifiRttController {
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 99%
rename from wifi/1.0/default/wifi_sta_iface.cpp
rename to wifi/1.1/default/wifi_sta_iface.cpp
index 3c5204808c7f6b3ec1777848866e810e0d7c4758..28f3f02a2a0daad4b22ab67671f9c7b3be38a643 100644 (file)
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
@@ -623,7 +623,7 @@ WifiStaIface::getDebugRxPacketFatesInternal() {
 }
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 98%
rename from wifi/1.0/default/wifi_sta_iface.h
rename to wifi/1.1/default/wifi_sta_iface.h
index 08faa2f1bbdf7bf34ae9a469b494352d2896532b..587a5de7ba8782fe7e09490e6ce46d8f4866602d 100644 (file)
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
+using namespace android::hardware::wifi::V1_0;
 
 /**
  * HIDL interface object used to control a STA Iface instance.
  */
-class WifiStaIface : public IWifiStaIface {
+class WifiStaIface : public V1_0::IWifiStaIface {
  public:
   WifiStaIface(const std::string& ifname,
                const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
@@ -159,7 +160,7 @@ class WifiStaIface : public IWifiStaIface {
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 98%
rename from wifi/1.0/default/wifi_status_util.cpp
rename to wifi/1.1/default/wifi_status_util.cpp
index c2d0758cbbf03e22b63690f12ba6468168ef1674..3a85e0998901b4aca8a2a56f24c3e62ea59e7c66 100644 (file)
@@ -19,7 +19,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 
 std::string legacyErrorToString(legacy_hal::wifi_error error) {
@@ -100,7 +100,7 @@ WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error) {
 }
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
similarity index 94%
rename from wifi/1.0/default/wifi_status_util.h
rename to wifi/1.1/default/wifi_status_util.h
index 7f557e0127f445ff443ccb0d0fd371f2691cefaa..cc93d66ca07d2151666ef95cb99ad255caff2bdd 100644 (file)
@@ -24,8 +24,9 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
+using namespace android::hardware::wifi::V1_0;
 
 std::string legacyErrorToString(legacy_hal::wifi_error error);
 WifiStatus createWifiStatus(WifiStatusCode code,
@@ -36,7 +37,7 @@ WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error,
 WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error);
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.1/vts/functional/Android.bp b/wifi/1.1/vts/functional/Android.bp
new file mode 100644 (file)
index 0000000..6b0baf7
--- /dev/null
@@ -0,0 +1,39 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "VtsHalWifiV1_1TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: [
+        "VtsHalWifiV1_1TargetTest.cpp",
+        "wifi_chip_hidl_test.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.wifi@1.0",
+        "android.hardware.wifi@1.1",
+    ],
+    static_libs: ["VtsHalWifiV1_0TargetTestUtil", "VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/wifi/1.1/vts/functional/VtsHalWifiV1_1TargetTest.cpp b/wifi/1.1/vts/functional/VtsHalWifiV1_1TargetTest.cpp
new file mode 100644 (file)
index 0000000..9b92b57
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+#include "wifi_hidl_test_utils.h"
+
+WifiHidlEnvironment* gEnv;
+
+int main(int argc, char** argv) {
+    gEnv = new WifiHidlEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        int status = RUN_ALL_TESTS();
+        LOG(INFO) << "Test result = " << status;
+    }
+    return status;
+}
diff --git a/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp
new file mode 100644 (file)
index 0000000..d3a983c
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.1/IWifi.h>
+#include <android/hardware/wifi/1.1/IWifiChip.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::ChipId;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::WifiStatus;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::hardware::wifi::V1_1::IWifi;
+using ::android::hardware::wifi::V1_1::IWifiChip;
+using ::android::hardware::wifi::V1_0::IWifiStaIface;
+
+namespace {
+constexpr IWifiChip::TxPowerScenario kFakePowerScenario =
+    IWifiChip::TxPowerScenario::VOICE_CALL;
+}; //namespace
+
+/**
+ * Fixture to use for all Wifi chip HIDL interface tests.
+ */
+class WifiChipHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        wifi_chip_ = IWifiChip::castFrom(getWifiChip());
+        ASSERT_NE(nullptr, wifi_chip_.get());
+    }
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+    uint32_t configureChipForStaIfaceAndGetCapabilities() {
+        ChipModeId mode_id;
+        EXPECT_TRUE(configureChipToSupportIfaceType(
+            wifi_chip_, IfaceType::STA, &mode_id));
+        const auto& status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities);
+        EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
+        return status_and_caps.second;
+    }
+
+    sp<IWifiChip> wifi_chip_;
+};
+
+/*
+ * SelectTxPowerScenario
+ */
+TEST_F(WifiChipHidlTest, SelectTxPowerScenario) {
+    uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
+    const auto& status =
+        HIDL_INVOKE(wifi_chip_, selectTxPowerScenario, kFakePowerScenario);
+    if (caps & IWifiChip::ChipCapabilityMask::SET_TX_POWER_LIMIT) {
+        EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
+    } else {
+        EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code);
+    }
+}
+
+/*
+ * ResetTxPowerScenario
+ */
+TEST_F(WifiChipHidlTest, ResetTxPowerScenario) {
+    uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
+    const auto& status =
+        HIDL_INVOKE(wifi_chip_, resetTxPowerScenario);
+    if (caps & IWifiChip::ChipCapabilityMask::SET_TX_POWER_LIMIT) {
+        EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
+    } else {
+        EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code);
+    }
+}
index d4e0fda2c1255ab88fbde7cb3301ab6450306dd0..b4ab98ffef61d89d640a83ac505ff564d58b671e 100644 (file)
@@ -2,5 +2,9 @@
 subdirs = [
     "1.0",
     "1.0/vts/functional",
+    "1.1",
+    "1.1/vts/functional",
+    "offload/1.0",
+    "offload/1.0/vts/functional",
     "supplicant/1.0",
 ]
diff --git a/wifi/offload/1.0/Android.bp b/wifi/offload/1.0/Android.bp
new file mode 100644 (file)
index 0000000..5b7fcad
--- /dev/null
@@ -0,0 +1,73 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+    name: "android.hardware.wifi.offload@1.0_hal",
+    srcs: [
+        "types.hal",
+        "IOffload.hal",
+        "IOffloadCallback.hal",
+    ],
+}
+
+genrule {
+    name: "android.hardware.wifi.offload@1.0_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.wifi.offload@1.0",
+    srcs: [
+        ":android.hardware.wifi.offload@1.0_hal",
+    ],
+    out: [
+        "android/hardware/wifi/offload/1.0/types.cpp",
+        "android/hardware/wifi/offload/1.0/OffloadAll.cpp",
+        "android/hardware/wifi/offload/1.0/OffloadCallbackAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.wifi.offload@1.0_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.wifi.offload@1.0",
+    srcs: [
+        ":android.hardware.wifi.offload@1.0_hal",
+    ],
+    out: [
+        "android/hardware/wifi/offload/1.0/types.h",
+        "android/hardware/wifi/offload/1.0/hwtypes.h",
+        "android/hardware/wifi/offload/1.0/IOffload.h",
+        "android/hardware/wifi/offload/1.0/IHwOffload.h",
+        "android/hardware/wifi/offload/1.0/BnHwOffload.h",
+        "android/hardware/wifi/offload/1.0/BpHwOffload.h",
+        "android/hardware/wifi/offload/1.0/BsOffload.h",
+        "android/hardware/wifi/offload/1.0/IOffloadCallback.h",
+        "android/hardware/wifi/offload/1.0/IHwOffloadCallback.h",
+        "android/hardware/wifi/offload/1.0/BnHwOffloadCallback.h",
+        "android/hardware/wifi/offload/1.0/BpHwOffloadCallback.h",
+        "android/hardware/wifi/offload/1.0/BsOffloadCallback.h",
+    ],
+}
+
+cc_library {
+    name: "android.hardware.wifi.offload@1.0",
+    defaults: ["hidl-module-defaults"],
+    generated_sources: ["android.hardware.wifi.offload@1.0_genc++"],
+    generated_headers: ["android.hardware.wifi.offload@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.wifi.offload@1.0_genc++_headers"],
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+    ],
+}
diff --git a/wifi/offload/1.0/IOffload.hal b/wifi/offload/1.0/IOffload.hal
new file mode 100644 (file)
index 0000000..4819519
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright 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.
+ */
+
+package android.hardware.wifi.offload@1.0;
+
+import IOffloadCallback;
+
+interface IOffload {
+    /**
+     * Configure the offload module to perform scans and filter results
+     * Scans must not be triggered due to configuration of the module.
+     *
+     * @param ScanParam paramters for scanning
+     * @param ScanFilter settings to filter scan result
+     * @return OffloadStatus indicating status of operation provided by this API
+     * If OffloadStatusCode::OK is returned, the operation was successful
+     * If OffloadStatusCode::NO_CONNECTION is returned, connection to the hardware is lost
+     * If OffloadStatusCode::ERROR is returned, requested operation could not be completed
+     */
+    @entry
+    @callflow(next={"setEventCallback", "subscribeScanResults"})
+    configureScans(ScanParam param, ScanFilter filter) generates (OffloadStatus status);
+
+    /**
+     * Get scan statistics
+     *
+     * @return OffloadStatus indicating status of operation provided by this API
+     * @return ScanStats statistics of scans performed
+     * If OffloadStatusCode::OK is returned, the operation was successful
+     * If OffloadStatusCode::NO_CONNECTION is returned, connection to the hardware is lost
+     * If OffloadStatusCode::ERROR is returned, requested operation could not be completed
+     * If OffloadStatusCode::TIMEOUT is returned, time out waiting for the requested data
+     */
+    @exit
+    @callflow(next={"subscribeScanResults", "unsubscribeScanResults", "getScanStats"})
+    getScanStats() generates (OffloadStatus status, ScanStats scanStats);
+
+    /**
+     * Subscribe to asynchronous scan events sent by offload module. This enables
+     * offload scans to be performed as per scan parameters, filtering the scan
+     * results based on configured scan filter and delivering the results after
+     * at least delayMs milliseconds from this call. If the client is already
+     * subscribed to the scan results, a call to this API must be a no-op.
+     *
+     * @param delayMs an integer expressing the minimum delay in mS after
+     *        subscribing when scan results must be delivered to the client
+     * @return OffloadStatus indicating status of operation provided by this API
+     * If OffloadStatusCode::OK is returned, the operation was successful
+     * If OffloadStatusCode::NO_CONNECTION is returned, connection to the hardware is lost
+     * If OffloadStatusCode::ERROR is returned, requested operation could not be completed
+     */
+    @callflow(next={"unsubscribeScanResults", "getScanStats"})
+    subscribeScanResults(uint32_t delayMs) generates (OffloadStatus status);
+
+    /**
+     * Unsubscribe to scan events sent by the offload module, hence disabling scans.
+     * If the client is already unsubscribed, a call to this API will be a no-op.
+     */
+    @exit
+    @callflow(next={"*"})
+    unsubscribeScanResults();
+
+    /**
+     * Setup the HIDL interface for reporting asynchronous scan events. A maximum
+     * of one callback interface is supported. Only one callback must be registered
+     * at any given time. If two consecutive calls are made with different callback
+     * interface objects, the latest one must be used to deliver events to client.
+     *
+     * @param cb An instance of the |IOffloadCallback| HIDL interface object
+     */
+    @entry
+    @callflow(next={"subscribeScanStats", "configureScans"})
+    setEventCallback(IOffloadCallback cb);
+};
diff --git a/wifi/offload/1.0/IOffloadCallback.hal b/wifi/offload/1.0/IOffloadCallback.hal
new file mode 100644 (file)
index 0000000..4888125
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright 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.
+ */
+package android.hardware.wifi.offload@1.0;
+
+interface IOffloadCallback {
+    /**
+     * Interface for the Offload HAL to return scan events to the client
+     *
+     * @param scanResult a vector of scan result objects
+     */
+    oneway onScanResult(vec<ScanResult> scanResult);
+    /**
+     * Interface for the Offload HAL to inform the client of error conditions
+     * see OffloadStatus for the error conditions to be reported
+     *
+     * @param status OffloadStatus
+     */
+    oneway onError(OffloadStatus status);
+};
diff --git a/wifi/offload/1.0/types.hal b/wifi/offload/1.0/types.hal
new file mode 100644 (file)
index 0000000..234f3fc
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Copyright 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.
+ */
+package android.hardware.wifi.offload@1.0;
+
+/**
+ * Defines a bitmap of security modes
+ */
+enum SecurityMode : uint8_t {
+    OPEN                    = 0x1 << 1,
+    WEP                     = 0x1 << 2,
+    PSK                     = 0x1 << 3,
+    EAP                     = 0x1 << 4,
+};
+
+/**
+ * SSID of the Access Point, maximum 32 characters
+ */
+typedef vec<uint8_t> Ssid;
+
+/**
+ * Preferred network information
+ * SSID and associated security mode(s)
+ */
+struct NetworkInfo {
+    Ssid ssid;
+    /* SecurityMode flags that are associated with this SSID
+     * More than one security mode can be supported, see SecurityMode */
+    bitfield<SecurityMode> flags;
+};
+
+/**
+ * This is a bit mask describing the capabilities of a BSS.
+ * See IEEE Std 802.11: 8.4.1.4
+ */
+enum Capability : uint16_t {
+    ESS                     = 1 << 0,
+    IBSS                    = 1 << 1,
+    CF_POLLABLE             = 1 << 2,
+    CF_PLL_REQ              = 1 << 3,
+    PRIVACY                 = 1 << 4,
+    SHORT_PREAMBLE          = 1 << 5,
+    PBCC                    = 1 << 6,
+    CHANNEL_AGILITY         = 1 << 7,
+    SPECTURM_MGMT           = 1 << 8,
+    QOS                     = 1 << 9,
+    SHORT_SLOT_TIME         = 1 << 10,
+    APSD                    = 1 << 11,
+    RADIO_MEASUREMENT       = 1 << 12,
+    DSSS_OFDM               = 1 << 13,
+    DELAYED_BLOCK_ACK       = 1 << 14,
+    IMMEDIATE_BLOCK_ACK     = 1 << 15,
+};
+
+/**
+ * Scan Results returned by the offload Hal
+ */
+struct ScanResult {
+    /* Information about this BSS
+     * SSID and security modes supported */
+    NetworkInfo networkInfo;
+    /* BSSID of the BSS */
+    uint8_t[6] bssid;
+    /* Can have multiple bits set, see Capability */
+    bitfield<Capability> capability;
+    /* Frequency scanned, in mHz */
+    uint32_t frequency;
+    /* Signal strength in dBm */
+    int8_t rssi;
+    /* TSF found in beacon/probe response */
+    uint64_t tsf;
+};
+
+
+/**
+ * Parameters for performing offload scans
+ */
+struct ScanParam {
+    /* Specify a list of SSIDs to scan, an empty list implies no preferred
+     * networks to scan */
+    vec<Ssid> ssidList;
+    /* Frequencies to scan, in mHz, an empty frequency list implies a full scan */
+    vec<uint32_t> frequencyList;
+    /* Periodicity of the scans to be performed by the offload module
+     * A value of zero indicates disable periodic scans. For this revision,
+     * where offload module is performing scans in disconnected mode, this value
+     * should not be zero. In future versions, periodic scans can be eliminated */
+    uint32_t disconnectedModeScanIntervalMs;
+};
+
+/**
+ * Instruction on how to filter the scan result before performing network
+ * selection and waking up the AP to connect
+ */
+struct ScanFilter {
+    /* Preferred network List of SSIDs and their security mode of interest
+     * The filter will drop the remaining scan results in the scan event.
+     * An empty list implies no filtering of scan result based on SSID and
+     * security mode. */
+    vec<NetworkInfo> preferredNetworkInfoList;
+    /* Minimum qualifying RSSI to be considered for network selection (dBm) */
+    int8_t rssiThreshold;
+};
+
+struct ScanRecord {
+    /* Amount of time spent scanning */
+    uint64_t durationMs;
+    /* Number of channels scanned */
+    uint32_t numChannelsScanned;
+    /* Number of entries aggregated into this record */
+    uint32_t numEntriesAggregated;
+};
+
+/**
+ * Enumerates the type of log that is recorded
+ */
+enum RecordName : uint32_t {
+    CMD_BASE                        = 0x00001000,
+    /* Record name corresponding to initialization */
+    CMD_INT                         = CMD_BASE + 0,
+   /* Record name corresponding to configureScans() API */
+    CMD_CONFIG_SCANS                = CMD_BASE + 1,
+    /* Record name corresponding to subscribeScanResults() API */
+    CMD_SUBSCRIBE_SCAN_RESULTS      = CMD_BASE + 2,
+    /* Record name corresponding to unsubscribeScanResults() API */
+    CMD_UNSUBSCRIBE_SCAN_RESULTS    = CMD_BASE + 3,
+    /* Record name corresponding to getScanStats() API */
+    CMD_GET_SCAN_STATS              = CMD_BASE + 4,
+    /* Record name corresponding to a reset*/
+    CMD_RESET                       = CMD_BASE + 5,
+    /* Add new commands here */
+    EVENT_RECVD_BASE                = 0x00002000,
+    /* Record name corresponding to scan monitor event*/
+    EVENT_RECVD_SCAN_RESULT_ASYNC   = EVENT_RECVD_BASE + 0,
+    /* Record name corresponding to scan response event */
+    EVENT_RECVD_SCAN_RESULT         = EVENT_RECVD_BASE + 1,
+    /* Add new events received here */
+    EVENT_SENT_BASE                 = 0x00003000,
+    /* Record name corresponding to scan event sent */
+    EVENT_SENT_SCAN_RESULT          = EVENT_SENT_BASE + 0,
+    /* Record name corresponding to abort event sent */
+    EVENT_SENT_ABORT                = EVENT_SENT_BASE + 1,
+    /* Record name corresponding to error event sent */
+    EVENT_SENT_ERROR                = EVENT_SENT_BASE + 2,
+    /* Add new events sent here */
+    REQ_BASE                        = 0x00004000,
+    /* Record name corresponding to scan request sent*/
+    REQ_SCAN                        = REQ_BASE + 0,
+    /* Add new requests here */
+};
+
+/**
+ * Defines the structure of each log record
+ */
+struct LogRecord {
+    /* Indicates the log recorded */
+    RecordName recordName;
+    /* Platform reference time in milliseconds when the log is recorded */
+    uint64_t logTimeMs;
+};
+
+/**
+ * Defines the scan statistics to be returned to the framework
+ */
+struct ScanStats {
+    /* Incremented everytime a new scan is requested */
+    uint32_t numScansRequestedByWifi;
+    /* Incremented everytime the scan is serviced by performing a scan*/
+    uint32_t numScansServicedByWifi;
+    /* Incremented everytime the scan is serviced by the scan cache */
+    uint32_t numScansServicedbyCache;
+    /* The last (CHRE reference) time this data structure is updated */
+    uint64_t lastUpdated;
+    /* The last (CHRE reference) time this data structure is read */
+    uint64_t lastRead;
+    /* The total time when the Offload module could be performing scans (T2 - T1)
+     * T1 - time when the framework subscribes for scan result (includes delayMs)
+     * T2 - min (time when the framework unsubscribes for scan result,
+     * currentTime) */
+    uint64_t subscriptionDurationMs;
+    /* Histograms of the channels scanned, 802.11 and with an 8 bit
+     * representation, only 256 channels are available */
+    uint8_t[256] histogramChannelsScanned;
+    /* Scan Record for this subscribe duration */
+    vec<ScanRecord> scanRecord;
+    /* Vector of the logRecord entries */
+    vec<LogRecord> logRecord;
+};
+
+/**
+ * Defines a list of return codes to indicate status of Offload HAL
+ */
+enum OffloadStatusCode : uint32_t {
+    /* No error */
+    OK,
+    /* No Connection to underlying implementation */
+    NO_CONNECTION,
+    /* Operation timeout */
+    TIMEOUT,
+    /* Other errors */
+    ERROR
+};
+
+/**
+ * Generic structures to return the status of an operation
+ */
+struct OffloadStatus {
+  OffloadStatusCode code;
+  /* Error message */
+  string description;
+};
+
+
+
diff --git a/wifi/offload/1.0/vts/functional/Android.bp b/wifi/offload/1.0/vts/functional/Android.bp
new file mode 100644 (file)
index 0000000..f907a89
--- /dev/null
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "VtsHalWifiOffloadV1_0TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalWifiOffloadV1_0TargetTest.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.wifi.offload@1.0",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
new file mode 100644 (file)
index 0000000..90c36dd
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * 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 "wifi_offload_hidl_hal_test"
+
+#include <android-base/logging.h>
+#include <android/hardware/wifi/offload/1.0/IOffload.h>
+#include <android/hardware/wifi/offload/1.0/IOffloadCallback.h>
+#include <android/hardware/wifi/offload/1.0/types.h>
+
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <VtsHalHidlTargetTestBase.h>
+
+#include <vector>
+
+#include "hidl_call_util.h"
+
+using ::android::hardware::wifi::offload::V1_0::IOffload;
+using ::android::hardware::wifi::offload::V1_0::IOffloadCallback;
+using ::android::hardware::wifi::offload::V1_0::ScanResult;
+using ::android::hardware::wifi::offload::V1_0::ScanParam;
+using ::android::hardware::wifi::offload::V1_0::Ssid;
+using ::android::hardware::wifi::offload::V1_0::NetworkInfo;
+using ::android::hardware::wifi::offload::V1_0::ScanFilter;
+using ::android::hardware::wifi::offload::V1_0::ScanStats;
+using ::android::hardware::wifi::offload::V1_0::OffloadStatus;
+using ::android::hardware::wifi::offload::V1_0::OffloadStatusCode;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::sp;
+
+constexpr char kOffloadCallbackSendScanResult[] = "onScanResult";
+constexpr char kOffloadCallbackSendError[] = "onError";
+
+namespace {
+const uint8_t kSsid1[] = {'G', 'o', 'o', 'g', 'l', 'e'};
+const uint8_t kSsid2[] = {'X', 'f', 'i', 'n', 'i', 't', 'y'};
+const uint8_t kBssid[6] = {0x12, 0xef, 0xa1, 0x2c, 0x97, 0x8b};
+const int16_t kRssi = -60;
+const uint32_t kFrequency = 2412;
+const uint8_t kBssidSize = 6;
+const uint64_t kTsf = 0;
+const uint16_t kCapability = 0;
+const uint8_t kNetworkFlags = 0;
+const uint32_t kFrequency1 = 2412;
+const uint32_t kFrequency2 = 2437;
+const uint32_t kDisconnectedModeScanIntervalMs = 5000;
+const int16_t kRssiThreshold = -76;
+}
+
+class OffloadCallbackArgs {
+   public:
+    hidl_vec<ScanResult> scan_results_;
+    OffloadStatus error_code_;
+};
+
+// The main test class for WifiOffload HIDL HAL.
+class WifiOffloadHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        wifi_offload_ =
+            ::testing::VtsHalHidlTargetTestBase::getService<IOffload>();
+        ASSERT_NE(wifi_offload_, nullptr);
+
+        wifi_offload_cb_ = new OffloadCallback();
+        ASSERT_NE(wifi_offload_cb_, nullptr);
+    }
+
+    virtual void TearDown() override {}
+
+    /* Callback class for Offload HAL. */
+    class OffloadCallback
+        : public ::testing::VtsHalHidlTargetCallbackBase<OffloadCallbackArgs>,
+          public IOffloadCallback {
+       public:
+        OffloadCallback(){};
+
+        virtual ~OffloadCallback() = default;
+
+        Return<void> onScanResult(
+            const hidl_vec<ScanResult>& scan_result) override {
+            OffloadCallbackArgs args;
+            args.scan_results_ = scan_result;
+            NotifyFromCallback(kOffloadCallbackSendScanResult, args);
+            return Void();
+        };
+
+        Return<void> onError(const OffloadStatus& status) override {
+            OffloadCallbackArgs args;
+            args.error_code_ = status;
+            NotifyFromCallback(kOffloadCallbackSendError, args);
+            return Void();
+        }
+    };
+
+    sp<IOffload> wifi_offload_;
+    sp<OffloadCallback> wifi_offload_cb_;
+};
+
+/*
+ * Verify that setEventCallback method returns without errors
+ */
+TEST_F(WifiOffloadHidlTest, setEventCallback) {
+    auto returnObject = wifi_offload_->setEventCallback(wifi_offload_cb_);
+    ASSERT_EQ(true, returnObject.isOk());
+}
+
+/*
+ * Verify that subscribeScanResults method returns without errors
+ */
+TEST_F(WifiOffloadHidlTest, subscribeScanResults) {
+    const auto& result = HIDL_INVOKE(wifi_offload_, subscribeScanResults, 0);
+    ASSERT_EQ(OffloadStatusCode::OK, result.code);
+}
+
+/*
+ * Verify that unsubscribeScanResults method returns without errors
+ */
+TEST_F(WifiOffloadHidlTest, unsubscribeScanResults) {
+    auto returnObject = wifi_offload_->unsubscribeScanResults();
+    ASSERT_EQ(true, returnObject.isOk());
+}
+
+/*
+ * Verify that configureScans method returns without errors
+ */
+TEST_F(WifiOffloadHidlTest, configureScans) {
+    ScanParam* pScanParam = new ScanParam();
+    std::vector<uint32_t> frequencyList = {kFrequency1, kFrequency2};
+    pScanParam->disconnectedModeScanIntervalMs =
+        kDisconnectedModeScanIntervalMs;
+    pScanParam->frequencyList = frequencyList;
+    std::vector<Ssid> ssidList;
+    std::vector<std::vector<uint8_t>> ssids{kSsid1, kSsid2};
+    for (const auto& ssid : ssids) {
+        Ssid tmp = ssid;
+        ssidList.push_back(tmp);
+    }
+    pScanParam->ssidList = ssidList;
+    ScanFilter* pScanFilter = new ScanFilter();
+    pScanFilter->rssiThreshold = kRssiThreshold;
+    std::vector<std::vector<uint8_t>> match_ssids{kSsid1, kSsid2};
+    std::vector<uint8_t> security_flags{kNetworkFlags, kNetworkFlags};
+    std::vector<NetworkInfo> preferredNetworksList;
+    for (size_t i = 0; i < security_flags.size(); i++) {
+        NetworkInfo nwInfo;
+        nwInfo.ssid = match_ssids[i];
+        nwInfo.flags = security_flags[i];
+        preferredNetworksList.push_back(nwInfo);
+    }
+    const auto& result =
+        HIDL_INVOKE(wifi_offload_, configureScans, *pScanParam, *pScanFilter);
+    ASSERT_EQ(OffloadStatusCode::OK, result.code);
+}
+
+/*
+ * Verify that getScanStats returns without any errors
+ */
+TEST_F(WifiOffloadHidlTest, getScanStats) {
+    const auto& result = HIDL_INVOKE(wifi_offload_, getScanStats);
+    OffloadStatus status = result.first;
+    ASSERT_EQ(OffloadStatusCode::OK, status.code);
+}
+
+/*
+ * Verify that onScanResult callback is invoked
+ */
+TEST_F(WifiOffloadHidlTest, getScanResults) {
+    wifi_offload_->setEventCallback(wifi_offload_cb_);
+    std::vector<ScanResult> scan_results;
+    std::vector<uint8_t> ssid(kSsid1, kSsid1 + sizeof(kSsid1));
+    ScanResult scan_result;
+    scan_result.tsf = kTsf;
+    scan_result.rssi = kRssi;
+    scan_result.frequency = kFrequency;
+    scan_result.capability = kCapability;
+    memcpy(&scan_result.bssid[0], &kBssid[0], kBssidSize);
+    scan_result.networkInfo.ssid = ssid;
+    scan_result.networkInfo.flags = kNetworkFlags;
+    scan_results.push_back(scan_result);
+    wifi_offload_cb_->onScanResult(scan_results);
+    auto res =
+        wifi_offload_cb_->WaitForCallback(kOffloadCallbackSendScanResult);
+    ASSERT_EQ(true, res.no_timeout);
+}
+
+/*
+ * Verify that onError callback is invoked
+ */
+TEST_F(WifiOffloadHidlTest, getError) {
+    wifi_offload_->setEventCallback(wifi_offload_cb_);
+    OffloadStatus status = {OffloadStatusCode::ERROR, ""};
+    wifi_offload_cb_->onError(status);
+    auto res = wifi_offload_cb_->WaitForCallback(kOffloadCallbackSendError);
+    ASSERT_EQ(true, res.no_timeout);
+}
+
+// A class for test environment setup
+class WifiOffloadHalHidlEnvironment : public ::testing::Environment {
+   public:
+    virtual void SetUp() {}
+    virtual void TearDown() {}
+};
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(new WifiOffloadHalHidlEnvironment);
+    ::testing::InitGoogleTest(&argc, argv);
+
+    int status = RUN_ALL_TESTS();
+    LOG(INFO) << "Test result = " << status;
+
+    return status;
+}
diff --git a/wifi/offload/1.0/vts/functional/hidl_call_util.h b/wifi/offload/1.0/vts/functional/hidl_call_util.h
new file mode 100644 (file)
index 0000000..f3ca517
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <functional>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+namespace {
+namespace detail {
+template <typename>
+struct functionArgSaver;
+
+// Provides a std::function that takes one argument, and a buffer
+// wherein the function will store its argument. The buffer has
+// the same type as the argument, but with const and reference
+// modifiers removed.
+template <typename ArgT>
+struct functionArgSaver<std::function<void(ArgT)>> final {
+    using StorageT = typename std::remove_const<
+        typename std::remove_reference<ArgT>::type>::type;
+
+    std::function<void(ArgT)> saveArgs = [this](ArgT arg) {
+        this->saved_values = arg;
+    };
+
+    StorageT saved_values;
+};
+
+// Provides a std::function that takes two arguments, and a buffer
+// wherein the function will store its arguments. The buffer is a
+// std::pair, whose elements have the same types as the arguments
+// (but with const and reference modifiers removed).
+template <typename Arg1T, typename Arg2T>
+struct functionArgSaver<std::function<void(Arg1T, Arg2T)>> final {
+    using StorageT =
+        std::pair<typename std::remove_const<
+                      typename std::remove_reference<Arg1T>::type>::type,
+                  typename std::remove_const<
+                      typename std::remove_reference<Arg2T>::type>::type>;
+
+    std::function<void(Arg1T, Arg2T)> saveArgs = [this](Arg1T arg1,
+                                                        Arg2T arg2) {
+        this->saved_values = {arg1, arg2};
+    };
+
+    StorageT saved_values;
+};
+
+// Provides a std::function that takes three or more arguments, and a
+// buffer wherein the function will store its arguments. The buffer is a
+// std::tuple whose elements have the same types as the arguments (but
+// with const and reference modifiers removed).
+template <typename... ArgT>
+struct functionArgSaver<std::function<void(ArgT...)>> final {
+    using StorageT = std::tuple<typename std::remove_const<
+        typename std::remove_reference<ArgT>::type>::type...>;
+
+    std::function<void(ArgT...)> saveArgs = [this](ArgT... arg) {
+        this->saved_values = {arg...};
+    };
+
+    StorageT saved_values;
+};
+
+// Invokes |method| on |object|, providing |method| a CallbackT as the
+// final argument. Returns a copy of the parameters that |method| provided
+// to CallbackT. (The parameters are returned by value.)
+template <typename CallbackT, typename MethodT, typename ObjectT,
+          typename... ArgT>
+typename functionArgSaver<CallbackT>::StorageT invokeMethod(
+    MethodT method, ObjectT object, ArgT&&... methodArg) {
+    functionArgSaver<CallbackT> result_buffer;
+    const auto& res = ((*object).*method)(std::forward<ArgT>(methodArg)...,
+                                          result_buffer.saveArgs);
+    EXPECT_TRUE(res.isOk());
+    return result_buffer.saved_values;
+}
+}  // namespace detail
+}  // namespace
+
+// Invokes |method| on |strong_pointer|, passing provided arguments through to
+// |method|.
+//
+// Returns either:
+// - A copy of the result callback parameter (for callbacks with a single
+//   parameter), OR
+// - A pair containing a copy of the result callback parameters (for callbacks
+//   with two parameters), OR
+// - A tuple containing a copy of the result callback paramters (for callbacks
+//   with three or more parameters).
+//
+// Example usage:
+//   EXPECT_EQ(WifiStatusCode::SUCCESS,
+//       HIDL_INVOKE(strong_pointer, methodReturningWifiStatus).code);
+//   EXPECT_EQ(WifiStatusCode::SUCCESS,
+//       HIDL_INVOKE(strong_pointer, methodReturningWifiStatusAndOneMore)
+//         .first.code);
+//   EXPECT_EQ(WifiStatusCode::SUCCESS, std::get<0>(
+//       HIDL_INVOKE(strong_pointer, methodReturningWifiStatusAndTwoMore))
+//         .code);
+#define HIDL_INVOKE(strong_pointer, method, ...)                              \
+    (detail::invokeMethod<                                                    \
+        std::remove_reference<decltype(*strong_pointer)>::type::method##_cb>( \
+        &std::remove_reference<decltype(*strong_pointer)>::type::method,      \
+        strong_pointer, ##__VA_ARGS__))
index cfcd4f8005fbcca58798491e6724f6e6f6687cc8..c6e39503d40067387a0539d6f2ecf5bab28f744f 100644 (file)
@@ -27,16 +27,18 @@ LOCAL_SRC_FILES := \
     supplicant_sta_network_hidl_test.cpp
 LOCAL_SHARED_LIBRARIES := \
     android.hardware.wifi.supplicant@1.0 \
+    android.hardware.wifi@1.0 \
     libbase \
     libcutils \
     libhidlbase \
     libhidltransport \
     liblog \
     libutils \
-    libwifi-hal \
-    libwifi-system
+    libwifi-system \
+    libwifi-system-iface
 LOCAL_STATIC_LIBRARIES := \
     libgmock \
-    VtsHalHidlTargetTestBase
+    VtsHalHidlTargetTestBase \
+    VtsHalWifiV1_0TargetTestUtil
 include $(BUILD_NATIVE_TEST)
 
index a69d14d1f01cb65ca742be68058f0b7c314c4306..33f30496d238ebb5061d6157aa051324945be414 100644 (file)
 class SupplicantHidlEnvironment : public ::testing::Environment {
    public:
     virtual void SetUp() override {
-        stopWifiFramework();
         stopSupplicant();
     }
     virtual void TearDown() override {
-        startWifiFramework();
-        // Framework will start wpa_supplicant.
     }
 };
 
index df4bfa95ca5ee34bc60e30057edcea22d96f09db..3b7550867a213db8fe17f61f7688231db7a9d229 100644 (file)
 #include <android/hidl/manager/1.0/IServiceNotification.h>
 #include <hidl/HidlTransportSupport.h>
 
-#include <wifi_hal/driver_tool.h>
 #include <wifi_system/interface_tool.h>
 #include <wifi_system/supplicant_manager.h>
 
 #include "supplicant_hidl_test_utils.h"
+#include "wifi_hidl_test_utils.h"
 
 using ::android::sp;
 using ::android::hardware::configureRpcThreadpool;
@@ -34,6 +34,8 @@ using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::IWifiChip;
 using ::android::hardware::wifi::supplicant::V1_0::ISupplicant;
 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantIface;
 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantNetwork;
@@ -44,22 +46,25 @@ using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
 using ::android::hidl::manager::V1_0::IServiceNotification;
-using ::android::wifi_hal::DriverTool;
 using ::android::wifi_system::InterfaceTool;
 using ::android::wifi_system::SupplicantManager;
 
 namespace {
 const char kSupplicantServiceName[] = "default";
 
-// Helper function to initialize the driver and firmware to STA mode.
+// Helper function to initialize the driver and firmware to STA mode
+// using the vendor HAL HIDL interface.
 void initilializeDriverAndFirmware() {
-    DriverTool driver_tool;
-    InterfaceTool iface_tool;
-    EXPECT_TRUE(driver_tool.LoadDriver());
-    EXPECT_TRUE(driver_tool.ChangeFirmwareMode(DriverTool::kFirmwareModeSta));
-    EXPECT_TRUE(iface_tool.SetWifiUpState(true));
+    sp<IWifiChip> wifi_chip = getWifiChip();
+    ChipModeId mode_id;
+    EXPECT_TRUE(configureChipToSupportIfaceType(
+        wifi_chip, ::android::hardware::wifi::V1_0::IfaceType::STA, &mode_id));
 }
 
+// Helper function to deinitialize the driver and firmware
+// using the vendor HAL HIDL interface.
+void deInitilializeDriverAndFirmware() { stopWifi(); }
+
 // Helper function to find any iface of the desired type exposed.
 bool findIfaceOfType(sp<ISupplicant> supplicant, IfaceType desired_type,
                      ISupplicant::IfaceInfo* out_info) {
@@ -135,25 +140,11 @@ class ServiceNotificationListener : public IServiceNotification {
     std::condition_variable condition_;
 };
 
-void stopWifiFramework() {
-    ASSERT_EQ(std::system("stop"), 0);
-    // TODO: Use some other mechanism to wait for the framework to
-    // finish disabling.
-    sleep(5);
-}
-
-void startWifiFramework() {
-    ASSERT_EQ(std::system("start"), 0);
-    // These tests don't care whether the framework
-    // finished enabling or not.
-}
-
 void stopSupplicant() {
-    DriverTool driver_tool;
     SupplicantManager supplicant_manager;
 
     ASSERT_TRUE(supplicant_manager.StopSupplicant());
-    ASSERT_TRUE(driver_tool.UnloadDriver());
+    deInitilializeDriverAndFirmware();
     ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
 }