Merge "BT: Aptx-Adaptive AIDL changes"
diff --git a/audio/7.1/Android.bp b/audio/7.1/Android.bp
new file mode 100644
index 0000000..52980e2
--- /dev/null
+++ b/audio/7.1/Android.bp
@@ -0,0 +1,32 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+hidl_interface {
+ name: "android.hardware.audio@7.1",
+ root: "android.hardware",
+ srcs: [
+ "types.hal",
+ "IDevice.hal",
+ "IDevicesFactory.hal",
+ "IPrimaryDevice.hal",
+ "IStreamIn.hal",
+ "IStreamOut.hal",
+ "IStreamOutLatencyModeCallback.hal",
+ ],
+ interfaces: [
+ "android.hardware.audio@7.0",
+ "android.hardware.audio.common@7.0",
+ "android.hidl.base@1.0",
+ "android.hidl.safe_union@1.0",
+ ],
+ gen_java: false,
+ gen_java_constants: false,
+}
diff --git a/audio/7.1/IDevice.hal b/audio/7.1/IDevice.hal
new file mode 100644
index 0000000..373d17f
--- /dev/null
+++ b/audio/7.1/IDevice.hal
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio@7.1;
+
+import android.hardware.audio.common@7.0;
+import @7.0::AudioInOutFlag;
+import @7.0::IDevice;
+import @7.0::Result;
+import IStreamIn;
+import IStreamOut;
+
+interface IDevice extends @7.0::IDevice {
+ /**
+ * This method creates and opens the audio hardware output stream.
+ * If the stream can not be opened with the proposed audio config,
+ * HAL must provide suggested values for the audio config.
+ *
+ * Note: INVALID_ARGUMENTS is returned both in the case when the
+ * HAL can not use the provided config and in the case when
+ * the value of any argument is invalid. In the latter case the
+ * HAL must provide a default initialized suggested config.
+ *
+ * @param ioHandle handle assigned by AudioFlinger.
+ * @param device device type and (if needed) address.
+ * @param config stream configuration.
+ * @param flags additional flags.
+ * @param sourceMetadata Description of the audio that will be played.
+ May be used by implementations to configure hardware effects.
+ * @return retval operation completion status.
+ * @return outStream created output stream.
+ * @return suggestedConfig in the case of rejection of the proposed config,
+ * a config suggested by the HAL.
+ */
+ openOutputStream_7_1(
+ AudioIoHandle ioHandle,
+ DeviceAddress device,
+ AudioConfig config,
+ vec<AudioInOutFlag> flags,
+ SourceMetadata sourceMetadata) generates (
+ Result retval,
+ IStreamOut outStream,
+ AudioConfig suggestedConfig);
+
+ /**
+ * This method creates and opens the audio hardware input stream.
+ * If the stream can not be opened with the proposed audio config,
+ * HAL must provide suggested values for the audio config.
+ *
+ * Note: INVALID_ARGUMENTS is returned both in the case when the
+ * HAL can not use the provided config and in the case when
+ * the value of any argument is invalid. In the latter case the
+ * HAL must provide a default initialized suggested config.
+ *
+ * @param ioHandle handle assigned by AudioFlinger.
+ * @param device device type and (if needed) address.
+ * @param config stream configuration.
+ * @param flags additional flags.
+ * @param sinkMetadata Description of the audio that is suggested by the client.
+ * May be used by implementations to configure processing effects.
+ * @return retval operation completion status.
+ * @return inStream in case of success, created input stream.
+ * @return suggestedConfig in the case of rejection of the proposed config,
+ * a config suggested by the HAL.
+ */
+ openInputStream_7_1(
+ AudioIoHandle ioHandle,
+ DeviceAddress device,
+ AudioConfig config,
+ vec<AudioInOutFlag> flags,
+ SinkMetadata sinkMetadata) generates (
+ Result retval,
+ IStreamIn inStream,
+ AudioConfig suggestedConfig);
+};
diff --git a/audio/7.1/IDevicesFactory.hal b/audio/7.1/IDevicesFactory.hal
new file mode 100644
index 0000000..7669614
--- /dev/null
+++ b/audio/7.1/IDevicesFactory.hal
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio@7.1;
+
+import @7.0::IDevicesFactory;
+import @7.0::Result;
+import IDevice;
+import IPrimaryDevice;
+
+/**
+ * This factory allows a HAL implementation to be split in multiple independent
+ * devices (called module in the pre-treble API). Note that this division is
+ * arbitrary and implementation are free to only have a Primary. The framework
+ * will query the devices according to audio_policy_configuration.xml
+ *
+ * Each device name is arbitrary, provided by the vendor's audio_policy_configuration.xml
+ * and only used to identify a device in this factory.
+ * The framework must not interpret the name, treating it as a vendor opaque data
+ * with the following exception:
+ * - the "r_submix" device that must be present to support policyMixes (Eg: Android projected).
+ * Note that this Device is included by default in a build derived from AOSP.
+ */
+interface IDevicesFactory extends @7.0::IDevicesFactory {
+
+ /**
+ * Opens an audio device. To close the device, it is necessary to call
+ * 'close' method on the returned device object.
+ *
+ * Important note: due to rules of HIDL, @7.1::IPrimaryDevice extends
+ * @7.0::IPrimaryDevice, rather than @7.1::IDevice. Thus the returned
+ * IDevice interface can not be up-casted to @7.1::IPrimaryDevice for the
+ * primary device. The client needs to use IPrimaryDevice instead of this
+ * method if it needs full functionality of the IPrimaryDevice interface.
+ *
+ * @param device device name.
+ * @return retval operation completion status. Returns INVALID_ARGUMENTS
+ * if there is no corresponding hardware module found,
+ * NOT_INITIALIZED if an error occurred while opening the hardware
+ * module.
+ * @return result the interface for the created device.
+ */
+ openDevice_7_1(string device) generates (Result retval, IDevice result);
+
+ /**
+ * Opens the Primary audio device that must be present.
+ * This function is not optional and must return successfully the primary device.
+ *
+ * This device must have the name "primary".
+ *
+ * The telephony stack uses this device to control the audio during a voice call.
+ *
+ * @return retval operation completion status. Must be SUCCESS.
+ * For debugging, return INVALID_ARGUMENTS if there is no corresponding
+ * hardware module found, NOT_INITIALIZED if an error occurred
+ * while opening the hardware module.
+ * @return result the interface for the created device.
+ */
+ openPrimaryDevice_7_1() generates (Result retval, IPrimaryDevice result);
+};
diff --git a/audio/7.1/IPrimaryDevice.hal b/audio/7.1/IPrimaryDevice.hal
new file mode 100644
index 0000000..1659671
--- /dev/null
+++ b/audio/7.1/IPrimaryDevice.hal
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio@7.1;
+
+import android.hardware.audio.common@7.0;
+import @7.0::IPrimaryDevice;
+import IDevice;
+
+interface IPrimaryDevice extends @7.0::IPrimaryDevice {
+ /**
+ * Retrieve the generic @7.1::IDevice interface.
+ *
+ * Since @7.1::IPrimaryDevice extends @7.0::IPrimaryDevice, the interface
+ * reference can not be downcasted to @7.1::IDevice using standard methods.
+ * For this reason a dedicated interface method is provided.
+ *
+ * @return result the generic part of the interface.
+ */
+ getDevice() generates (IDevice result);
+};
diff --git a/audio/7.1/IStreamIn.hal b/audio/7.1/IStreamIn.hal
new file mode 100644
index 0000000..abebe6a
--- /dev/null
+++ b/audio/7.1/IStreamIn.hal
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio@7.1;
+
+import @7.0::IStreamIn;
+
+interface IStreamIn extends @7.0::IStreamIn {
+};
diff --git a/audio/7.1/IStreamOut.hal b/audio/7.1/IStreamOut.hal
new file mode 100644
index 0000000..b2013cf
--- /dev/null
+++ b/audio/7.1/IStreamOut.hal
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio@7.1;
+
+import @7.0::Result;
+import @7.0::IStreamOut;
+
+import IStreamOutLatencyModeCallback;
+
+interface IStreamOut extends @7.0::IStreamOut {
+ /**
+ * Indicates the requested latency mode for this output stream.
+ *
+ * The requested mode can be one of the modes returned by
+ * getRecommendedLatencyModes() API.
+ *
+ * Optional method.
+ * Mandated only on specific spatial audio streams indicated by
+ * AUDIO_OUTPUT_FLAG_SPATIALIZER flag if they can be routed to a BT classic sink.
+ *
+ * @return retval operation completion status.
+ */
+ setLatencyMode(LatencyMode mode) generates (Result retval);
+
+ /**
+ * Indicates which latency modes are currently supported on this output stream.
+ * If the transport protocol (e.g Bluetooth A2DP) used by this output stream to reach
+ * the output device supports variable latency modes, the HAL indicates which
+ * modes are currently supported.
+ * The framework can then call setLatencyMode() with one of the supported modes to select
+ * the desired operation mode.
+ *
+ * Optional method.
+ * Mandated only on specific spatial audio streams indicated by
+ * AUDIO_OUTPUT_FLAG_SPATIALIZER flag if they can be routed to a BT classic sink.
+ *
+ * @return retval operation completion status.
+ * @return modes currrently supported latency modes.
+ */
+ getRecommendedLatencyModes() generates (Result retval, vec<LatencyMode> modes);
+
+ /**
+ * Set the callback interface for notifying changes in supported latency modes.
+ *
+ * Calling this method with a null pointer will result in releasing
+ * the callback.
+ *
+ * Optional method.
+ * Mandated only on specific spatial audio streams indicated by
+ * AUDIO_OUTPUT_FLAG_SPATIALIZER flag if they can be routed to a BT classic sink.
+ *
+ * @return retval operation completion status.
+ */
+ setLatencyModeCallback(IStreamOutLatencyModeCallback callback) generates (Result retval);
+};
diff --git a/audio/7.1/IStreamOutLatencyModeCallback.hal b/audio/7.1/IStreamOutLatencyModeCallback.hal
new file mode 100644
index 0000000..45b453f
--- /dev/null
+++ b/audio/7.1/IStreamOutLatencyModeCallback.hal
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.hardware.audio@7.1;
+
+/**
+ * Callback interface for output stream variable latency mode feature.
+ */
+interface IStreamOutLatencyModeCallback {
+ /**
+ * Called with the new list of supported latency modes when a change occurs.
+ */
+ oneway onRecommendedLatencyModeChanged(vec<LatencyMode> modes);
+};
diff --git a/audio/7.1/config/Android.bp b/audio/7.1/config/Android.bp
new file mode 100644
index 0000000..70c8fd4
--- /dev/null
+++ b/audio/7.1/config/Android.bp
@@ -0,0 +1,31 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+xsd_config {
+ name: "audio_policy_configuration_V7_1",
+ srcs: ["audio_policy_configuration.xsd"],
+ package_name: "android.audio.policy.configuration.V7_1",
+ nullability: true,
+}
+
+xsd_config {
+ name: "audio_policy_configuration_V7_1_enums",
+ srcs: ["audio_policy_configuration.xsd"],
+ package_name: "android.audio.policy.configuration.V7_1",
+ nullability: true,
+ enums_only: true,
+}
+
+xsd_config {
+ name: "audio_policy_configuration_V7_1_parser",
+ srcs: ["audio_policy_configuration.xsd"],
+ package_name: "android.audio.policy.configuration.V7_1",
+ nullability: true,
+ parser_only: true,
+}
diff --git a/audio/7.1/config/api/current.txt b/audio/7.1/config/api/current.txt
new file mode 100644
index 0000000..0a0eb02
--- /dev/null
+++ b/audio/7.1/config/api/current.txt
@@ -0,0 +1,596 @@
+// Signature format: 2.0
+package android.audio.policy.configuration.V7_1 {
+
+ public class AttachedDevices {
+ ctor public AttachedDevices();
+ method @Nullable public java.util.List<java.lang.String> getItem();
+ }
+
+ public enum AudioChannelMask {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_1;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_10;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_11;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_12;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_13;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_14;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_15;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_16;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_17;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_18;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_19;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_20;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_21;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_22;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_23;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_24;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_3;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_4;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_5;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_6;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_7;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_8;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_9;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_2POINT0POINT2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_2POINT1POINT2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_3POINT0POINT2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_3POINT1POINT2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_5POINT1;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_6;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_FRONT_BACK;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_MONO;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_STEREO;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_CALL_MONO;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_NONE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_13POINT_360RA;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_22POINT2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT0POINT2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1POINT2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT0POINT2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1POINT2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT4;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1_BACK;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1_SIDE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_6POINT1;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1POINT2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1POINT4;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_9POINT1POINT4;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_9POINT1POINT6;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_HAPTIC_AB;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_MONO;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_MONO_HAPTIC_A;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_PENTA;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD_BACK;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD_SIDE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_SURROUND;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_TRI;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_TRI_BACK;
+ }
+
+ public enum AudioContentType {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_MOVIE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_MUSIC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_SONIFICATION;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_SPEECH;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_UNKNOWN;
+ }
+
+ public enum AudioDevice {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_AMBIENT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_AUX_DIGITAL;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_BACK_MIC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_BLE_HEADSET;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_BLE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_BUILTIN_MIC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_BUS;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_COMMUNICATION;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_DEFAULT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_ECHO_REFERENCE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_FM_TUNER;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_HDMI;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_HDMI_ARC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_HDMI_EARC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_IP;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_LINE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_LOOPBACK;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_PROXY;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_REMOTE_SUBMIX;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_SPDIF;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_STUB;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_TELEPHONY_RX;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_TV_TUNER;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_USB_ACCESSORY;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_USB_DEVICE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_USB_HEADSET;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_VOICE_CALL;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_WIRED_HEADSET;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_NONE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_AUX_DIGITAL;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_AUX_LINE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLE_BROADCAST;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLE_HEADSET;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLE_SPEAKER;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BUS;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_DEFAULT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_EARPIECE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_ECHO_CANCELLER;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_FM;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_HDMI;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_HDMI_ARC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_HDMI_EARC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_HEARING_AID;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_IP;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_LINE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_PROXY;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_SPDIF;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_SPEAKER;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_SPEAKER_SAFE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_STUB;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_TELEPHONY_TX;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_USB_ACCESSORY;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_USB_DEVICE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_USB_HEADSET;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADSET;
+ }
+
+ public enum AudioEncapsulationType {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_IEC61937;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_NONE;
+ }
+
+ public enum AudioFormat {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADIF;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_ELD;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_ERLC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_HE_V1;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_HE_V2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_LC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_LD;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_LTP;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_MAIN;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_SCALABLE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_SSR;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_XHE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ELD;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ERLC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_HE_V1;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_HE_V2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_LATM;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_LATM_HE_V1;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_LATM_HE_V2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_LATM_LC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_LC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_LD;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_LTP;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_MAIN;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_SCALABLE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_SSR;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_XHE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AC3;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AC4;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_ALAC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AMR_NB;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AMR_WB;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AMR_WB_PLUS;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_APE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_APTX;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_APTX_ADAPTIVE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_APTX_HD;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_APTX_TWSP;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_CELT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_DEFAULT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_DRA;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_DSD;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_DTS;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_DTS_HD;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_DTS_UHD;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_EVRC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_EVRCB;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_EVRCNW;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_EVRCWB;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_E_AC3;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_E_AC3_JOC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_FLAC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_HE_AAC_V1;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_HE_AAC_V2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_IEC60958;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_IEC61937;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_LC3;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_LDAC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_LHDC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_LHDC_LL;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MAT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MAT_1_0;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MAT_2_0;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MAT_2_1;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MP2;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MP3;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MPEGH_BL_L3;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MPEGH_BL_L4;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MPEGH_LC_L3;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MPEGH_LC_L4;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_OPUS;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_PCM_16_BIT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_PCM_32_BIT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_PCM_8_24_BIT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_PCM_8_BIT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_PCM_FLOAT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_QCELP;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_SBC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_VORBIS;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_WMA;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_WMA_PRO;
+ }
+
+ public enum AudioGainMode {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioGainMode AUDIO_GAIN_MODE_CHANNELS;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioGainMode AUDIO_GAIN_MODE_JOINT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioGainMode AUDIO_GAIN_MODE_RAMP;
+ }
+
+ public enum AudioInOutFlag {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_DIRECT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_FAST;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_RAW;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT_PCM;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_FAST;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_HW_AV_SYNC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_SPATIALIZER;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_SYNC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_TTS;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_VOIP_RX;
+ }
+
+ public class AudioPolicyConfiguration {
+ ctor public AudioPolicyConfiguration();
+ method @Nullable public android.audio.policy.configuration.V7_1.GlobalConfiguration getGlobalConfiguration();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Modules> getModules();
+ method @Nullable public android.audio.policy.configuration.V7_1.SurroundSound getSurroundSound();
+ method @Nullable public android.audio.policy.configuration.V7_1.Version getVersion();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Volumes> getVolumes();
+ method public void setGlobalConfiguration(@Nullable android.audio.policy.configuration.V7_1.GlobalConfiguration);
+ method public void setSurroundSound(@Nullable android.audio.policy.configuration.V7_1.SurroundSound);
+ method public void setVersion(@Nullable android.audio.policy.configuration.V7_1.Version);
+ }
+
+ public enum AudioSource {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_CAMCORDER;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_DEFAULT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_ECHO_REFERENCE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_FM_TUNER;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_HOTWORD;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_MIC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_REMOTE_SUBMIX;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_UNPROCESSED;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_VOICE_CALL;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_VOICE_COMMUNICATION;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_VOICE_DOWNLINK;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_VOICE_PERFORMANCE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_VOICE_RECOGNITION;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_VOICE_UPLINK;
+ }
+
+ public enum AudioStreamType {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_ACCESSIBILITY;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_ALARM;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_ASSISTANT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_BLUETOOTH_SCO;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_CALL_ASSISTANT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_DTMF;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_ENFORCED_AUDIBLE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_MUSIC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_NOTIFICATION;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_PATCH;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_REROUTING;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_RING;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_SYSTEM;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_TTS;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_VOICE_CALL;
+ }
+
+ public enum AudioUsage {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_ALARM;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_ANNOUNCEMENT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_ASSISTANT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_CALL_ASSISTANT;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_EMERGENCY;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_GAME;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_MEDIA;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_NOTIFICATION;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_SAFETY;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_UNKNOWN;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_VEHICLE_STATUS;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_VIRTUAL_SOURCE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+ }
+
+ public enum DeviceCategory {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.DeviceCategory DEVICE_CATEGORY_EARPIECE;
+ enum_constant public static final android.audio.policy.configuration.V7_1.DeviceCategory DEVICE_CATEGORY_EXT_MEDIA;
+ enum_constant public static final android.audio.policy.configuration.V7_1.DeviceCategory DEVICE_CATEGORY_HEADSET;
+ enum_constant public static final android.audio.policy.configuration.V7_1.DeviceCategory DEVICE_CATEGORY_HEARING_AID;
+ enum_constant public static final android.audio.policy.configuration.V7_1.DeviceCategory DEVICE_CATEGORY_SPEAKER;
+ }
+
+ public class DevicePorts {
+ ctor public DevicePorts();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.DevicePorts.DevicePort> getDevicePort();
+ }
+
+ public static class DevicePorts.DevicePort {
+ ctor public DevicePorts.DevicePort();
+ method @Nullable public String getAddress();
+ method @Nullable public java.util.List<java.lang.String> getEncodedFormats();
+ method @Nullable public android.audio.policy.configuration.V7_1.Gains getGains();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Profile> getProfile();
+ method @Nullable public android.audio.policy.configuration.V7_1.Role getRole();
+ method @Nullable public String getTagName();
+ method @Nullable public String getType();
+ method @Nullable public boolean get_default();
+ method public void setAddress(@Nullable String);
+ method public void setEncodedFormats(@Nullable java.util.List<java.lang.String>);
+ method public void setGains(@Nullable android.audio.policy.configuration.V7_1.Gains);
+ method public void setRole(@Nullable android.audio.policy.configuration.V7_1.Role);
+ method public void setTagName(@Nullable String);
+ method public void setType(@Nullable String);
+ method public void set_default(@Nullable boolean);
+ }
+
+ public enum EngineSuffix {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.EngineSuffix _default;
+ enum_constant public static final android.audio.policy.configuration.V7_1.EngineSuffix configurable;
+ }
+
+ public class Gains {
+ ctor public Gains();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Gains.Gain> getGain();
+ }
+
+ public static class Gains.Gain {
+ ctor public Gains.Gain();
+ method @Nullable public android.audio.policy.configuration.V7_1.AudioChannelMask getChannel_mask();
+ method @Nullable public int getDefaultValueMB();
+ method @Nullable public int getMaxRampMs();
+ method @Nullable public int getMaxValueMB();
+ method @Nullable public int getMinRampMs();
+ method @Nullable public int getMinValueMB();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.AudioGainMode> getMode();
+ method @Nullable public String getName();
+ method @Nullable public int getStepValueMB();
+ method @Nullable public boolean getUseForVolume();
+ method public void setChannel_mask(@Nullable android.audio.policy.configuration.V7_1.AudioChannelMask);
+ method public void setDefaultValueMB(@Nullable int);
+ method public void setMaxRampMs(@Nullable int);
+ method public void setMaxValueMB(@Nullable int);
+ method public void setMinRampMs(@Nullable int);
+ method public void setMinValueMB(@Nullable int);
+ method public void setMode(@Nullable java.util.List<android.audio.policy.configuration.V7_1.AudioGainMode>);
+ method public void setName(@Nullable String);
+ method public void setStepValueMB(@Nullable int);
+ method public void setUseForVolume(@Nullable boolean);
+ }
+
+ public class GlobalConfiguration {
+ ctor public GlobalConfiguration();
+ method @Nullable public boolean getCall_screen_mode_supported();
+ method @Nullable public android.audio.policy.configuration.V7_1.EngineSuffix getEngine_library();
+ method @Nullable public boolean getSpeaker_drc_enabled();
+ method public void setCall_screen_mode_supported(@Nullable boolean);
+ method public void setEngine_library(@Nullable android.audio.policy.configuration.V7_1.EngineSuffix);
+ method public void setSpeaker_drc_enabled(@Nullable boolean);
+ }
+
+ public enum HalVersion {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.HalVersion _2_0;
+ enum_constant public static final android.audio.policy.configuration.V7_1.HalVersion _3_0;
+ }
+
+ public class MixPorts {
+ ctor public MixPorts();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.MixPorts.MixPort> getMixPort();
+ }
+
+ public static class MixPorts.MixPort {
+ ctor public MixPorts.MixPort();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.AudioInOutFlag> getFlags();
+ method @Nullable public android.audio.policy.configuration.V7_1.Gains getGains();
+ method @Nullable public long getMaxActiveCount();
+ method @Nullable public long getMaxOpenCount();
+ method @Nullable public String getName();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.AudioUsage> getPreferredUsage();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Profile> getProfile();
+ method @Nullable public android.audio.policy.configuration.V7_1.Role getRole();
+ method public void setFlags(@Nullable java.util.List<android.audio.policy.configuration.V7_1.AudioInOutFlag>);
+ method public void setGains(@Nullable android.audio.policy.configuration.V7_1.Gains);
+ method public void setMaxActiveCount(@Nullable long);
+ method public void setMaxOpenCount(@Nullable long);
+ method public void setName(@Nullable String);
+ method public void setPreferredUsage(@Nullable java.util.List<android.audio.policy.configuration.V7_1.AudioUsage>);
+ method public void setRole(@Nullable android.audio.policy.configuration.V7_1.Role);
+ }
+
+ public enum MixType {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.MixType mix;
+ enum_constant public static final android.audio.policy.configuration.V7_1.MixType mux;
+ }
+
+ public class Modules {
+ ctor public Modules();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Modules.Module> getModule();
+ }
+
+ public static class Modules.Module {
+ ctor public Modules.Module();
+ method @Nullable public android.audio.policy.configuration.V7_1.AttachedDevices getAttachedDevices();
+ method @Nullable public String getDefaultOutputDevice();
+ method @Nullable public android.audio.policy.configuration.V7_1.DevicePorts getDevicePorts();
+ method @Nullable public android.audio.policy.configuration.V7_1.HalVersion getHalVersion();
+ method @Nullable public android.audio.policy.configuration.V7_1.MixPorts getMixPorts();
+ method @Nullable public String getName();
+ method @Nullable public android.audio.policy.configuration.V7_1.Routes getRoutes();
+ method public void setAttachedDevices(@Nullable android.audio.policy.configuration.V7_1.AttachedDevices);
+ method public void setDefaultOutputDevice(@Nullable String);
+ method public void setDevicePorts(@Nullable android.audio.policy.configuration.V7_1.DevicePorts);
+ method public void setHalVersion(@Nullable android.audio.policy.configuration.V7_1.HalVersion);
+ method public void setMixPorts(@Nullable android.audio.policy.configuration.V7_1.MixPorts);
+ method public void setName(@Nullable String);
+ method public void setRoutes(@Nullable android.audio.policy.configuration.V7_1.Routes);
+ }
+
+ public class Profile {
+ ctor public Profile();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.AudioChannelMask> getChannelMasks();
+ method @Nullable public android.audio.policy.configuration.V7_1.AudioEncapsulationType getEncapsulationType();
+ method @Nullable public String getFormat();
+ method @Nullable public String getName();
+ method @Nullable public java.util.List<java.math.BigInteger> getSamplingRates();
+ method public void setChannelMasks(@Nullable java.util.List<android.audio.policy.configuration.V7_1.AudioChannelMask>);
+ method public void setEncapsulationType(@Nullable android.audio.policy.configuration.V7_1.AudioEncapsulationType);
+ method public void setFormat(@Nullable String);
+ method public void setName(@Nullable String);
+ method public void setSamplingRates(@Nullable java.util.List<java.math.BigInteger>);
+ }
+
+ public class Reference {
+ ctor public Reference();
+ method @Nullable public String getName();
+ method @Nullable public java.util.List<java.lang.String> getPoint();
+ method public void setName(@Nullable String);
+ }
+
+ public enum Role {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.Role sink;
+ enum_constant public static final android.audio.policy.configuration.V7_1.Role source;
+ }
+
+ public class Routes {
+ ctor public Routes();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Routes.Route> getRoute();
+ }
+
+ public static class Routes.Route {
+ ctor public Routes.Route();
+ method @Nullable public String getSink();
+ method @Nullable public String getSources();
+ method @Nullable public android.audio.policy.configuration.V7_1.MixType getType();
+ method public void setSink(@Nullable String);
+ method public void setSources(@Nullable String);
+ method public void setType(@Nullable android.audio.policy.configuration.V7_1.MixType);
+ }
+
+ public class SurroundFormats {
+ ctor public SurroundFormats();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.SurroundFormats.Format> getFormat();
+ }
+
+ public static class SurroundFormats.Format {
+ ctor public SurroundFormats.Format();
+ method @Nullable public String getName();
+ method @Nullable public java.util.List<java.lang.String> getSubformats();
+ method public void setName(@Nullable String);
+ method public void setSubformats(@Nullable java.util.List<java.lang.String>);
+ }
+
+ public class SurroundSound {
+ ctor public SurroundSound();
+ method @Nullable public android.audio.policy.configuration.V7_1.SurroundFormats getFormats();
+ method public void setFormats(@Nullable android.audio.policy.configuration.V7_1.SurroundFormats);
+ }
+
+ public enum Version {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.configuration.V7_1.Version _7_0;
+ enum_constant public static final android.audio.policy.configuration.V7_1.Version _7_1;
+ }
+
+ public class Volume {
+ ctor public Volume();
+ method @Nullable public android.audio.policy.configuration.V7_1.DeviceCategory getDeviceCategory();
+ method @Nullable public java.util.List<java.lang.String> getPoint();
+ method @Nullable public String getRef();
+ method @Nullable public android.audio.policy.configuration.V7_1.AudioStreamType getStream();
+ method public void setDeviceCategory(@Nullable android.audio.policy.configuration.V7_1.DeviceCategory);
+ method public void setRef(@Nullable String);
+ method public void setStream(@Nullable android.audio.policy.configuration.V7_1.AudioStreamType);
+ }
+
+ public class Volumes {
+ ctor public Volumes();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Reference> getReference();
+ method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Volume> getVolume();
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method @Nullable public static android.audio.policy.configuration.V7_1.AudioPolicyConfiguration read(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/audio/7.1/config/api/last_current.txt b/audio/7.1/config/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/7.1/config/api/last_current.txt
diff --git a/audio/7.1/config/api/last_removed.txt b/audio/7.1/config/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/7.1/config/api/last_removed.txt
diff --git a/audio/7.1/config/api/removed.txt b/audio/7.1/config/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/audio/7.1/config/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/audio/7.1/config/audio_policy_configuration.xsd b/audio/7.1/config/audio_policy_configuration.xsd
new file mode 100644
index 0000000..defb506
--- /dev/null
+++ b/audio/7.1/config/audio_policy_configuration.xsd
@@ -0,0 +1,819 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xs:schema version="2.0"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <!-- List the config versions supported by audio policy. -->
+ <xs:simpleType name="version">
+ <xs:restriction base="xs:decimal">
+ <xs:enumeration value="7.0"/>
+ <xs:enumeration value="7.1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="halVersion">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Version of the interface the hal implements. Note that this
+ relates to legacy HAL API versions since HIDL APIs are versioned
+ using other mechanisms.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:decimal">
+ <!-- List of HAL versions supported by the framework. -->
+ <xs:enumeration value="2.0"/>
+ <xs:enumeration value="3.0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="audioPolicyConfiguration">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="globalConfiguration" type="globalConfiguration"/>
+ <xs:element name="modules" type="modules" maxOccurs="unbounded"/>
+ <xs:element name="volumes" type="volumes" maxOccurs="unbounded"/>
+ <xs:element name="surroundSound" type="surroundSound" minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute name="version" type="version"/>
+ </xs:complexType>
+ <xs:key name="moduleNameKey">
+ <xs:selector xpath="modules/module"/>
+ <xs:field xpath="@name"/>
+ </xs:key>
+ <xs:unique name="volumeTargetUniqueness">
+ <xs:selector xpath="volumes/volume"/>
+ <xs:field xpath="@stream"/>
+ <xs:field xpath="@deviceCategory"/>
+ </xs:unique>
+ <xs:key name="volumeCurveNameKey">
+ <xs:selector xpath="volumes/reference"/>
+ <xs:field xpath="@name"/>
+ </xs:key>
+ <xs:keyref name="volumeCurveRef" refer="volumeCurveNameKey">
+ <xs:selector xpath="volumes/volume"/>
+ <xs:field xpath="@ref"/>
+ </xs:keyref>
+ </xs:element>
+ <xs:complexType name="globalConfiguration">
+ <xs:attribute name="speaker_drc_enabled" type="xs:boolean" use="required"/>
+ <xs:attribute name="call_screen_mode_supported" type="xs:boolean" use="optional"/>
+ <xs:attribute name="engine_library" type="engineSuffix" use="optional"/>
+ </xs:complexType>
+ <xs:complexType name="modules">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ There should be one section per audio HW module present on the platform.
+ Each <module/> contains two mandatory tags: “halVersion” and “name”.
+ The module "name" is the same as in previous .conf file.
+ Each module must contain the following sections:
+ - <devicePorts/>: a list of device descriptors for all
+ input and output devices accessible via this module.
+ This contains both permanently attached devices and removable devices.
+ - <mixPorts/>: listing all output and input streams exposed by the audio HAL
+ - <routes/>: list of possible connections between input
+ and output devices or between stream and devices.
+ A <route/> is defined by a set of 3 attributes:
+ -"type": mux|mix means all sources are mutual exclusive (mux) or can be mixed (mix)
+ -"sink": the sink involved in this route
+ -"sources": all the sources than can be connected to the sink via this route
+ - <attachedDevices/>: permanently attached devices.
+ The attachedDevices section is a list of devices names.
+ Their names correspond to device names defined in "devicePorts" section.
+ - <defaultOutputDevice/> is the device to be used when no policy rule applies
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="module" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="attachedDevices" type="attachedDevices" minOccurs="0">
+ <xs:unique name="attachedDevicesUniqueness">
+ <xs:selector xpath="item"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ </xs:element>
+ <xs:element name="defaultOutputDevice" type="xs:token" minOccurs="0"/>
+ <xs:element name="mixPorts" type="mixPorts" minOccurs="0"/>
+ <xs:element name="devicePorts" type="devicePorts" minOccurs="0"/>
+ <xs:element name="routes" type="routes" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="halVersion" type="halVersion" use="required"/>
+ </xs:complexType>
+ <xs:unique name="mixPortNameUniqueness">
+ <xs:selector xpath="mixPorts/mixPort"/>
+ <xs:field xpath="@name"/>
+ </xs:unique>
+ <xs:key name="devicePortNameKey">
+ <xs:selector xpath="devicePorts/devicePort"/>
+ <xs:field xpath="@tagName"/>
+ </xs:key>
+ <xs:unique name="devicePortUniqueness">
+ <xs:selector xpath="devicePorts/devicePort"/>
+ <xs:field xpath="@type"/>
+ <xs:field xpath="@address"/>
+ </xs:unique>
+ <xs:keyref name="defaultOutputDeviceRef" refer="devicePortNameKey">
+ <xs:selector xpath="defaultOutputDevice"/>
+ <xs:field xpath="."/>
+ </xs:keyref>
+ <xs:keyref name="attachedDeviceRef" refer="devicePortNameKey">
+ <xs:selector xpath="attachedDevices/item"/>
+ <xs:field xpath="."/>
+ </xs:keyref>
+ <!-- The following 3 constraints try to make sure each sink port
+ is reference in one an only one route. -->
+ <xs:key name="routeSinkKey">
+ <!-- predicate [@type='sink'] does not work in xsd 1.0 -->
+ <xs:selector xpath="devicePorts/devicePort|mixPorts/mixPort"/>
+ <xs:field xpath="@tagName|@name"/>
+ </xs:key>
+ <xs:keyref name="routeSinkRef" refer="routeSinkKey">
+ <xs:selector xpath="routes/route"/>
+ <xs:field xpath="@sink"/>
+ </xs:keyref>
+ <xs:unique name="routeUniqueness">
+ <xs:selector xpath="routes/route"/>
+ <xs:field xpath="@sink"/>
+ </xs:unique>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="attachedDevices">
+ <xs:sequence>
+ <xs:element name="item" type="xs:token" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:simpleType name="audioInOutFlag">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ The flags indicate suggested stream attributes supported by the profile.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_DIRECT" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_PRIMARY" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_FAST" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_DEEP_BUFFER" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_NON_BLOCKING" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_HW_AV_SYNC" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_TTS" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_RAW" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_SYNC" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_DIRECT_PCM" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_MMAP_NOIRQ" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_VOIP_RX" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_INCALL_MUSIC" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_SPATIALIZER" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_FAST" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_HW_HOTWORD" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_RAW" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_SYNC" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_MMAP_NOIRQ" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_VOIP_TX" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_HW_AV_SYNC" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_DIRECT" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="audioInOutFlags">
+ <xs:list itemType="audioInOutFlag" />
+ </xs:simpleType>
+ <xs:simpleType name="role">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="sink"/>
+ <xs:enumeration value="source"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="mixPorts">
+ <xs:sequence>
+ <xs:element name="mixPort" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="gains" type="gains" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:token" use="required"/>
+ <xs:attribute name="role" type="role" use="required"/>
+ <xs:attribute name="flags" type="audioInOutFlags"/>
+ <xs:attribute name="maxOpenCount" type="xs:unsignedInt"/>
+ <xs:attribute name="maxActiveCount" type="xs:unsignedInt"/>
+ <xs:attribute name="preferredUsage" type="audioUsageList">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ When choosing the mixPort of an audio track, the audioPolicy
+ first considers the mixPorts with a preferredUsage including
+ the track AudioUsage preferred .
+ If non support the track format, the other mixPorts are considered.
+ Eg: a <mixPort preferredUsage="AUDIO_USAGE_MEDIA" /> will receive
+ the audio of all apps playing with a MEDIA usage.
+ It may receive audio from ALARM if there are no audio compatible
+ <mixPort preferredUsage="AUDIO_USAGE_ALARM" />.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ <xs:unique name="mixPortProfileUniqueness">
+ <xs:selector xpath="profile"/>
+ <xs:field xpath="format"/>
+ <xs:field xpath="samplingRate"/>
+ <xs:field xpath="channelMasks"/>
+ </xs:unique>
+ <xs:unique name="mixPortGainUniqueness">
+ <xs:selector xpath="gains/gain"/>
+ <xs:field xpath="@name"/>
+ </xs:unique>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:simpleType name="audioDevice">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_DEVICE_NONE"/>
+
+ <xs:enumeration value="AUDIO_DEVICE_OUT_EARPIECE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_WIRED_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_WIRED_HEADPHONE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI_EARC"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_DIGITAL"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_USB_ACCESSORY"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_USB_DEVICE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_REMOTE_SUBMIX"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_TELEPHONY_TX"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_LINE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI_ARC"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_SPDIF"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_FM"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_LINE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER_SAFE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_IP"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BUS"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_PROXY"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_USB_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_HEARING_AID"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_ECHO_CANCELLER"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_SPEAKER"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_BROADCAST"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_DEFAULT"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_STUB"/>
+
+ <xs:enumeration value="AUDIO_DEVICE_IN_COMMUNICATION"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_AMBIENT"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BUILTIN_MIC"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_WIRED_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_HDMI"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_AUX_DIGITAL"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_VOICE_CALL"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_TELEPHONY_RX"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BACK_MIC"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_REMOTE_SUBMIX"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_USB_ACCESSORY"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_USB_DEVICE"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_FM_TUNER"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_TV_TUNER"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_LINE"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_SPDIF"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_A2DP"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_LOOPBACK"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_IP"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BUS"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_PROXY"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_USB_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_BLE"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_HDMI_ARC"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_HDMI_EARC"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_ECHO_REFERENCE"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BLE_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_DEFAULT"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_STUB"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="vendorExtension">
+ <!-- Vendor extension names must be prefixed by "VX_" to distinguish them from
+ AOSP values. Vendors must namespace their names to avoid conflicts. The
+ namespace part must only use capital latin characters and decimal digits and
+ consist of at least 3 characters. The part of the extension name after the
+ namespace may in addition include underscores. Example for a hypothetical
+ Google virtual reality device:
+
+ <devicePort tagName="VR" type="VX_GOOGLE_VR" role="sink" />
+ -->
+ <xs:restriction base="xs:string">
+ <xs:pattern value="VX_[A-Z0-9]{3,}_[_A-Z0-9]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="extendableAudioDevice">
+ <xs:union memberTypes="audioDevice vendorExtension"/>
+ </xs:simpleType>
+ <xs:simpleType name="audioFormat">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_FORMAT_DEFAULT" />
+ <xs:enumeration value="AUDIO_FORMAT_PCM_16_BIT" />
+ <xs:enumeration value="AUDIO_FORMAT_PCM_8_BIT"/>
+ <xs:enumeration value="AUDIO_FORMAT_PCM_32_BIT"/>
+ <xs:enumeration value="AUDIO_FORMAT_PCM_8_24_BIT"/>
+ <xs:enumeration value="AUDIO_FORMAT_PCM_FLOAT"/>
+ <xs:enumeration value="AUDIO_FORMAT_PCM_24_BIT_PACKED"/>
+ <xs:enumeration value="AUDIO_FORMAT_MP3"/>
+ <xs:enumeration value="AUDIO_FORMAT_AMR_NB"/>
+ <xs:enumeration value="AUDIO_FORMAT_AMR_WB"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_MAIN"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_LC"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_SSR"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_LTP"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_HE_V1"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_SCALABLE"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ERLC"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_LD"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_HE_V2"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ELD"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_XHE"/>
+ <xs:enumeration value="AUDIO_FORMAT_HE_AAC_V1"/>
+ <xs:enumeration value="AUDIO_FORMAT_HE_AAC_V2"/>
+ <xs:enumeration value="AUDIO_FORMAT_VORBIS"/>
+ <xs:enumeration value="AUDIO_FORMAT_OPUS"/>
+ <xs:enumeration value="AUDIO_FORMAT_AC3"/>
+ <xs:enumeration value="AUDIO_FORMAT_E_AC3"/>
+ <xs:enumeration value="AUDIO_FORMAT_E_AC3_JOC"/>
+ <xs:enumeration value="AUDIO_FORMAT_DTS"/>
+ <xs:enumeration value="AUDIO_FORMAT_DTS_HD"/>
+ <xs:enumeration value="AUDIO_FORMAT_IEC61937"/>
+ <xs:enumeration value="AUDIO_FORMAT_DOLBY_TRUEHD"/>
+ <xs:enumeration value="AUDIO_FORMAT_EVRC"/>
+ <xs:enumeration value="AUDIO_FORMAT_EVRCB"/>
+ <xs:enumeration value="AUDIO_FORMAT_EVRCWB"/>
+ <xs:enumeration value="AUDIO_FORMAT_EVRCNW"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADIF"/>
+ <xs:enumeration value="AUDIO_FORMAT_WMA"/>
+ <xs:enumeration value="AUDIO_FORMAT_WMA_PRO"/>
+ <xs:enumeration value="AUDIO_FORMAT_AMR_WB_PLUS"/>
+ <xs:enumeration value="AUDIO_FORMAT_MP2"/>
+ <xs:enumeration value="AUDIO_FORMAT_QCELP"/>
+ <xs:enumeration value="AUDIO_FORMAT_DSD"/>
+ <xs:enumeration value="AUDIO_FORMAT_FLAC"/>
+ <xs:enumeration value="AUDIO_FORMAT_ALAC"/>
+ <xs:enumeration value="AUDIO_FORMAT_APE"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_MAIN"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LC"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_SSR"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LTP"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_HE_V1"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_SCALABLE"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_ERLC"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LD"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_HE_V2"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_ELD"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_XHE"/>
+ <xs:enumeration value="AUDIO_FORMAT_SBC"/>
+ <xs:enumeration value="AUDIO_FORMAT_APTX"/>
+ <xs:enumeration value="AUDIO_FORMAT_APTX_HD"/>
+ <xs:enumeration value="AUDIO_FORMAT_AC4"/>
+ <xs:enumeration value="AUDIO_FORMAT_LDAC"/>
+ <xs:enumeration value="AUDIO_FORMAT_MAT"/>
+ <xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/>
+ <xs:enumeration value="AUDIO_FORMAT_MAT_2_0"/>
+ <xs:enumeration value="AUDIO_FORMAT_MAT_2_1"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_LATM"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_LATM_LC"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_LATM_HE_V1"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_LATM_HE_V2"/>
+ <xs:enumeration value="AUDIO_FORMAT_CELT"/>
+ <xs:enumeration value="AUDIO_FORMAT_APTX_ADAPTIVE"/>
+ <xs:enumeration value="AUDIO_FORMAT_LHDC"/>
+ <xs:enumeration value="AUDIO_FORMAT_LHDC_LL"/>
+ <xs:enumeration value="AUDIO_FORMAT_APTX_TWSP"/>
+ <xs:enumeration value="AUDIO_FORMAT_LC3"/>
+ <xs:enumeration value="AUDIO_FORMAT_MPEGH_BL_L3"/>
+ <xs:enumeration value="AUDIO_FORMAT_MPEGH_BL_L4"/>
+ <xs:enumeration value="AUDIO_FORMAT_MPEGH_LC_L3"/>
+ <xs:enumeration value="AUDIO_FORMAT_MPEGH_LC_L4"/>
+ <xs:enumeration value="AUDIO_FORMAT_IEC60958"/>
+ <xs:enumeration value="AUDIO_FORMAT_DTS_UHD"/>
+ <xs:enumeration value="AUDIO_FORMAT_DRA"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="extendableAudioFormat">
+ <xs:union memberTypes="audioFormat vendorExtension"/>
+ </xs:simpleType>
+ <xs:simpleType name="audioUsage">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Audio usage specifies the intended use case for the sound being played.
+ Please consult frameworks/base/media/java/android/media/AudioAttributes.java
+ for the description of each value.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_USAGE_UNKNOWN" />
+ <xs:enumeration value="AUDIO_USAGE_MEDIA" />
+ <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+ <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+ <xs:enumeration value="AUDIO_USAGE_ALARM" />
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION" />
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <xs:enumeration value="AUDIO_USAGE_GAME" />
+ <xs:enumeration value="AUDIO_USAGE_VIRTUAL_SOURCE" />
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANT" />
+ <xs:enumeration value="AUDIO_USAGE_CALL_ASSISTANT" />
+ <xs:enumeration value="AUDIO_USAGE_EMERGENCY" />
+ <xs:enumeration value="AUDIO_USAGE_SAFETY" />
+ <xs:enumeration value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <xs:enumeration value="AUDIO_USAGE_ANNOUNCEMENT" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="audioUsageList">
+ <xs:list itemType="audioUsage"/>
+ </xs:simpleType>
+ <xs:simpleType name="audioContentType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Audio content type expresses the general category of the content.
+ Please consult frameworks/base/media/java/android/media/AudioAttributes.java
+ for the description of each value.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_UNKNOWN"/>
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_SPEECH"/>
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_MUSIC"/>
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_MOVIE"/>
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="samplingRates">
+ <xs:list itemType="xs:nonNegativeInteger" />
+ </xs:simpleType>
+ <xs:simpleType name="audioChannelMask">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Audio channel mask specifies presence of particular channels.
+ There are two representations:
+ - representation position (traditional discrete channel specification,
+ e.g. "left", "right");
+ - indexed (this is similar to "tracks" in audio mixing, channels
+ are represented using numbers).
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_CHANNEL_NONE"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_MONO"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_STEREO"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_2POINT1"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_TRI"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_TRI_BACK"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_3POINT1"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_2POINT0POINT2"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_2POINT1POINT2"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_3POINT0POINT2"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_3POINT1POINT2"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_QUAD"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_QUAD_BACK"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_QUAD_SIDE"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_SURROUND"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_PENTA"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1_BACK"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1_SIDE"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1POINT2"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1POINT4"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_6POINT1"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_7POINT1"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_7POINT1POINT2"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_7POINT1POINT4"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_9POINT1POINT4"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_9POINT1POINT6"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_13POINT_360RA"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_22POINT2"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_MONO_HAPTIC_A"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_HAPTIC_AB"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB"/>
+ <xs:enumeration value="AUDIO_CHANNEL_IN_MONO"/>
+ <xs:enumeration value="AUDIO_CHANNEL_IN_STEREO"/>
+ <xs:enumeration value="AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ <xs:enumeration value="AUDIO_CHANNEL_IN_6"/>
+ <xs:enumeration value="AUDIO_CHANNEL_IN_2POINT0POINT2"/>
+ <xs:enumeration value="AUDIO_CHANNEL_IN_2POINT1POINT2"/>
+ <xs:enumeration value="AUDIO_CHANNEL_IN_3POINT0POINT2"/>
+ <xs:enumeration value="AUDIO_CHANNEL_IN_3POINT1POINT2"/>
+ <xs:enumeration value="AUDIO_CHANNEL_IN_5POINT1"/>
+ <xs:enumeration value="AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO"/>
+ <xs:enumeration value="AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO"/>
+ <xs:enumeration value="AUDIO_CHANNEL_IN_VOICE_CALL_MONO"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_1"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_2"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_3"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_4"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_5"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_6"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_7"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_8"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_9"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_10"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_11"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_12"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_13"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_14"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_15"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_16"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_17"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_18"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_19"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_20"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_21"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_22"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_23"/>
+ <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_24"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="channelMasks">
+ <xs:list itemType="audioChannelMask" />
+ </xs:simpleType>
+ <xs:simpleType name="audioEncapsulationType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_ENCAPSULATION_TYPE_NONE"/>
+ <xs:enumeration value="AUDIO_ENCAPSULATION_TYPE_IEC61937"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="profile">
+ <xs:attribute name="name" type="xs:token" use="optional"/>
+ <xs:attribute name="format" type="extendableAudioFormat" use="optional"/>
+ <xs:attribute name="samplingRates" type="samplingRates" use="optional"/>
+ <xs:attribute name="channelMasks" type="channelMasks" use="optional"/>
+ <xs:attribute name="encapsulationType" type="audioEncapsulationType" use="optional"/>
+ </xs:complexType>
+ <xs:simpleType name="audioGainMode">
+ <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:simpleType name="audioGainModeMaskUnrestricted">
+ <xs:list itemType="audioGainMode" />
+ </xs:simpleType>
+ <xs:simpleType name='audioGainModeMask'>
+ <xs:restriction base='audioGainModeMaskUnrestricted'>
+ <xs:minLength value='1' />
+ </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="audioGainModeMask" use="required"/>
+ <xs:attribute name="channel_mask" type="audioChannelMask" 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:attribute name="useForVolume" type="xs:boolean" 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="extendableAudioDevice" use="required"/>
+ <xs:attribute name="role" type="role" use="required"/>
+ <xs:attribute name="address" type="xs:string" use="optional" default=""/>
+ <!-- Note that XSD 1.0 can not check that a type only has one default. -->
+ <xs:attribute name="default" type="xs:boolean" use="optional">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ The default device will be used if multiple have the same type
+ and no explicit route request exists for a specific device of
+ that type.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="encodedFormats" type="audioFormatsList" use="optional"
+ default="" />
+ </xs:complexType>
+ <xs:unique name="devicePortProfileUniqueness">
+ <xs:selector xpath="profile"/>
+ <xs:field xpath="format"/>
+ <xs:field xpath="samplingRate"/>
+ <xs:field xpath="channelMasks"/>
+ </xs:unique>
+ <xs:unique name="devicePortGainUniqueness">
+ <xs:selector xpath="gains/gain"/>
+ <xs:field xpath="@name"/>
+ </xs:unique>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:simpleType name="mixType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="mix"/>
+ <xs:enumeration value="mux"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="routes">
+ <xs:sequence>
+ <xs:element name="route" minOccurs="0" maxOccurs="unbounded">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ List all available sources for a given sink.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:attribute name="type" type="mixType" use="required"/>
+ <xs:attribute name="sink" type="xs:string" use="required"/>
+ <xs:attribute name="sources" type="xs:string" use="required"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="volumes">
+ <xs:sequence>
+ <xs:element name="volume" type="volume" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="reference" type="reference" minOccurs="0" maxOccurs="unbounded">
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <!-- TODO: Always require a ref for better xsd validations.
+ Currently a volume could have no points nor ref
+ as it can not be forbidden by xsd 1.0.-->
+ <xs:simpleType name="volumePoint">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Comma separated pair of number.
+ The fist one is the framework level (between 0 and 100).
+ The second one is the volume to send to the HAL.
+ The framework will interpolate volumes not specified.
+ Their MUST be at least 2 points specified.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:pattern value="([0-9]{1,2}|100),-?[0-9]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="audioStreamType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Audio stream type describing the intended use case of a stream.
+ Please consult frameworks/base/media/java/android/media/AudioSystem.java
+ for the description of each value.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_STREAM_VOICE_CALL"/>
+ <xs:enumeration value="AUDIO_STREAM_SYSTEM"/>
+ <xs:enumeration value="AUDIO_STREAM_RING"/>
+ <xs:enumeration value="AUDIO_STREAM_MUSIC"/>
+ <xs:enumeration value="AUDIO_STREAM_ALARM"/>
+ <xs:enumeration value="AUDIO_STREAM_NOTIFICATION"/>
+ <xs:enumeration value="AUDIO_STREAM_BLUETOOTH_SCO"/>
+ <xs:enumeration value="AUDIO_STREAM_ENFORCED_AUDIBLE"/>
+ <xs:enumeration value="AUDIO_STREAM_DTMF"/>
+ <xs:enumeration value="AUDIO_STREAM_TTS"/>
+ <xs:enumeration value="AUDIO_STREAM_ACCESSIBILITY"/>
+ <xs:enumeration value="AUDIO_STREAM_ASSISTANT"/>
+ <xs:enumeration value="AUDIO_STREAM_REROUTING"/>
+ <xs:enumeration value="AUDIO_STREAM_PATCH"/>
+ <xs:enumeration value="AUDIO_STREAM_CALL_ASSISTANT"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="audioSource">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ An audio source defines the intended use case for the sound being recorded.
+ Please consult frameworks/base/media/java/android/media/MediaRecorder.java
+ for the description of each value.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_SOURCE_DEFAULT"/>
+ <xs:enumeration value="AUDIO_SOURCE_MIC"/>
+ <xs:enumeration value="AUDIO_SOURCE_VOICE_UPLINK"/>
+ <xs:enumeration value="AUDIO_SOURCE_VOICE_DOWNLINK"/>
+ <xs:enumeration value="AUDIO_SOURCE_VOICE_CALL"/>
+ <xs:enumeration value="AUDIO_SOURCE_CAMCORDER"/>
+ <xs:enumeration value="AUDIO_SOURCE_VOICE_RECOGNITION"/>
+ <xs:enumeration value="AUDIO_SOURCE_VOICE_COMMUNICATION"/>
+ <xs:enumeration value="AUDIO_SOURCE_REMOTE_SUBMIX"/>
+ <xs:enumeration value="AUDIO_SOURCE_UNPROCESSED"/>
+ <xs:enumeration value="AUDIO_SOURCE_VOICE_PERFORMANCE"/>
+ <xs:enumeration value="AUDIO_SOURCE_ECHO_REFERENCE"/>
+ <xs:enumeration value="AUDIO_SOURCE_FM_TUNER"/>
+ <xs:enumeration value="AUDIO_SOURCE_HOTWORD"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <!-- Enum values of device_category from Volume.h. -->
+ <xs:simpleType name="deviceCategory">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="DEVICE_CATEGORY_HEADSET"/>
+ <xs:enumeration value="DEVICE_CATEGORY_SPEAKER"/>
+ <xs:enumeration value="DEVICE_CATEGORY_EARPIECE"/>
+ <xs:enumeration value="DEVICE_CATEGORY_EXT_MEDIA"/>
+ <xs:enumeration value="DEVICE_CATEGORY_HEARING_AID"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="volume">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Volume section defines a volume curve for a given use case and device category.
+ It contains a list of points of this curve expressing the attenuation in Millibels
+ for a given volume index from 0 to 100.
+ <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-9600</point>
+ <point>100,0</point>
+ </volume>
+
+ It may also reference a reference/@name to avoid duplicating curves.
+ <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER"
+ ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+ <reference name="DEFAULT_MEDIA_VOLUME_CURVE">
+ <point>0,-9600</point>
+ <point>100,0</point>
+ </reference>
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="point" type="volumePoint" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="stream" type="audioStreamType"/>
+ <xs:attribute name="deviceCategory" type="deviceCategory"/>
+ <xs:attribute name="ref" type="xs:token" use="optional"/>
+ </xs:complexType>
+ <xs:complexType name="reference">
+ <xs:sequence>
+ <xs:element name="point" type="volumePoint" minOccurs="2" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:token" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="surroundSound">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Surround Sound section provides configuration related to handling of
+ multi-channel formats.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="formats" type="surroundFormats"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:simpleType name="audioFormatsList">
+ <xs:list itemType="extendableAudioFormat" />
+ </xs:simpleType>
+ <xs:complexType name="surroundFormats">
+ <xs:sequence>
+ <xs:element name="format" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="extendableAudioFormat" use="required"/>
+ <xs:attribute name="subformats" type="audioFormatsList" />
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:simpleType name="engineSuffix">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="configurable"/>
+ </xs:restriction>
+ </xs:simpleType>
+</xs:schema>
diff --git a/audio/7.1/types.hal b/audio/7.1/types.hal
new file mode 100644
index 0000000..9d8ee4d
--- /dev/null
+++ b/audio/7.1/types.hal
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio@7.1;
+
+/**
+ * Latency modes used for the variable latency feature on output streams.
+ * Used by setLatencyMode() and getRecommendedLatencyModes() methods.
+ */
+
+@export(name="audio_latency_mode_t", value_prefix="AUDIO_LATENCY_MODE_")
+enum LatencyMode : int32_t {
+ /** No specific constraint on the latency */
+ FREE = 0,
+ /** A relatively low latency compatible with head tracking operation (e.g less than 100ms) */
+ LOW = 1,
+};
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index c172674..6a0cfa5 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -47,6 +47,11 @@
vndk: {
enabled: true,
},
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.bluetooth",
+ ],
+ min_sdk_version: "31",
},
},
versions: [
diff --git a/audio/common/7.1/Android.bp b/audio/common/7.1/Android.bp
new file mode 100644
index 0000000..a257510
--- /dev/null
+++ b/audio/common/7.1/Android.bp
@@ -0,0 +1,23 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library {
+ name: "android.hardware.audio.common@7.1-enums",
+ vendor_available: true,
+ generated_headers: ["audio_policy_configuration_V7_1_enums"],
+ generated_sources: ["audio_policy_configuration_V7_1_enums"],
+ header_libs: ["libxsdc-utils"],
+ export_generated_headers: ["audio_policy_configuration_V7_1_enums"],
+ export_header_lib_headers: ["libxsdc-utils"],
+ export_include_dirs: ["enums/include"],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ ],
+}
diff --git a/audio/common/7.1/enums/OWNERS b/audio/common/7.1/enums/OWNERS
new file mode 100644
index 0000000..24071af
--- /dev/null
+++ b/audio/common/7.1/enums/OWNERS
@@ -0,0 +1,2 @@
+elaurent@google.com
+mnaganov@google.com
diff --git a/audio/common/7.1/enums/include/android_audio_policy_configuration_V7_1-enums.h b/audio/common/7.1/enums/include/android_audio_policy_configuration_V7_1-enums.h
new file mode 100644
index 0000000..6f6a0ca
--- /dev/null
+++ b/audio/common/7.1/enums/include/android_audio_policy_configuration_V7_1-enums.h
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIO_POLICY_CONFIGURATION_V7_1__ENUMS_H
+#define ANDROID_AUDIO_POLICY_CONFIGURATION_V7_1__ENUMS_H
+
+#include <sys/types.h>
+#include <regex>
+#include <string>
+
+#include <android_audio_policy_configuration_V7_1_enums.h>
+
+namespace android::audio::policy::configuration::V7_1 {
+
+static inline size_t getChannelCount(AudioChannelMask mask) {
+ switch (mask) {
+ case AudioChannelMask::AUDIO_CHANNEL_NONE:
+ return 0;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_MONO:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_1:
+ return 1;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_A:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_HAPTIC_AB:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_STEREO:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_FRONT_BACK:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_CALL_MONO:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_2:
+ return 2;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_TRI:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_TRI_BACK:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_3:
+ return 3;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT0POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT1:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_BACK:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_SIDE:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_SURROUND:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_2POINT0POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_4:
+ return 4;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT0POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_PENTA:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_2POINT1POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_3POINT0POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_5:
+ return 5;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT1POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1_BACK:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1_SIDE:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_6:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_3POINT1POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_5POINT1:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_6:
+ return 6;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_6POINT1:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_7:
+ return 7;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_8:
+ return 8;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_9:
+ return 9;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1POINT4:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_10:
+ return 10;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_11:
+ return 11;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT4:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_12:
+ return 12;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_13POINT_360RA:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_13:
+ return 13;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_9POINT1POINT4:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_14:
+ return 14;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_15:
+ return 15;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_9POINT1POINT6:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_16:
+ return 16;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_17:
+ return 17;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_18:
+ return 18;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_19:
+ return 19;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_20:
+ return 20;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_21:
+ return 21;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_22:
+ return 22;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_23:
+ return 23;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_22POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_24:
+ return 24;
+ case AudioChannelMask::UNKNOWN:
+ return 0;
+ // No default to make sure all cases are covered.
+ }
+ // This is to avoid undefined behavior if 'mask' isn't a valid enum value.
+ return 0;
+}
+
+static inline ssize_t getChannelCount(const std::string& mask) {
+ return getChannelCount(stringToAudioChannelMask(mask));
+}
+
+static inline bool isOutputDevice(AudioDevice device) {
+ switch (device) {
+ case AudioDevice::UNKNOWN:
+ case AudioDevice::AUDIO_DEVICE_NONE:
+ return false;
+ case AudioDevice::AUDIO_DEVICE_OUT_EARPIECE:
+ case AudioDevice::AUDIO_DEVICE_OUT_SPEAKER:
+ case AudioDevice::AUDIO_DEVICE_OUT_WIRED_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
+ case AudioDevice::AUDIO_DEVICE_OUT_AUX_DIGITAL:
+ case AudioDevice::AUDIO_DEVICE_OUT_HDMI:
+ case AudioDevice::AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_OUT_USB_ACCESSORY:
+ case AudioDevice::AUDIO_DEVICE_OUT_USB_DEVICE:
+ case AudioDevice::AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
+ case AudioDevice::AUDIO_DEVICE_OUT_TELEPHONY_TX:
+ case AudioDevice::AUDIO_DEVICE_OUT_LINE:
+ case AudioDevice::AUDIO_DEVICE_OUT_HDMI_ARC:
+ case AudioDevice::AUDIO_DEVICE_OUT_HDMI_EARC:
+ case AudioDevice::AUDIO_DEVICE_OUT_SPDIF:
+ case AudioDevice::AUDIO_DEVICE_OUT_FM:
+ case AudioDevice::AUDIO_DEVICE_OUT_AUX_LINE:
+ case AudioDevice::AUDIO_DEVICE_OUT_SPEAKER_SAFE:
+ case AudioDevice::AUDIO_DEVICE_OUT_IP:
+ case AudioDevice::AUDIO_DEVICE_OUT_BUS:
+ case AudioDevice::AUDIO_DEVICE_OUT_PROXY:
+ case AudioDevice::AUDIO_DEVICE_OUT_USB_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_OUT_HEARING_AID:
+ case AudioDevice::AUDIO_DEVICE_OUT_ECHO_CANCELLER:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLE_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLE_SPEAKER:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLE_BROADCAST:
+ case AudioDevice::AUDIO_DEVICE_OUT_DEFAULT:
+ case AudioDevice::AUDIO_DEVICE_OUT_STUB:
+ return true;
+ case AudioDevice::AUDIO_DEVICE_IN_COMMUNICATION:
+ case AudioDevice::AUDIO_DEVICE_IN_AMBIENT:
+ case AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC:
+ case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_IN_WIRED_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_IN_AUX_DIGITAL:
+ case AudioDevice::AUDIO_DEVICE_IN_HDMI:
+ case AudioDevice::AUDIO_DEVICE_IN_VOICE_CALL:
+ case AudioDevice::AUDIO_DEVICE_IN_TELEPHONY_RX:
+ case AudioDevice::AUDIO_DEVICE_IN_BACK_MIC:
+ case AudioDevice::AUDIO_DEVICE_IN_REMOTE_SUBMIX:
+ case AudioDevice::AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_IN_USB_ACCESSORY:
+ case AudioDevice::AUDIO_DEVICE_IN_USB_DEVICE:
+ case AudioDevice::AUDIO_DEVICE_IN_FM_TUNER:
+ case AudioDevice::AUDIO_DEVICE_IN_TV_TUNER:
+ case AudioDevice::AUDIO_DEVICE_IN_LINE:
+ case AudioDevice::AUDIO_DEVICE_IN_SPDIF:
+ case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_A2DP:
+ case AudioDevice::AUDIO_DEVICE_IN_LOOPBACK:
+ case AudioDevice::AUDIO_DEVICE_IN_IP:
+ case AudioDevice::AUDIO_DEVICE_IN_BUS:
+ case AudioDevice::AUDIO_DEVICE_IN_PROXY:
+ case AudioDevice::AUDIO_DEVICE_IN_USB_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_BLE:
+ case AudioDevice::AUDIO_DEVICE_IN_HDMI_ARC:
+ case AudioDevice::AUDIO_DEVICE_IN_HDMI_EARC:
+ case AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE:
+ case AudioDevice::AUDIO_DEVICE_IN_BLE_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_IN_DEFAULT:
+ case AudioDevice::AUDIO_DEVICE_IN_STUB:
+ return false;
+ // No default to make sure all cases are covered.
+ }
+ // This is to avoid undefined behavior if 'device' isn't a valid enum value.
+ return false;
+}
+
+static inline bool isOutputDevice(const std::string& device) {
+ return isOutputDevice(stringToAudioDevice(device));
+}
+
+static inline bool isTelephonyDevice(AudioDevice device) {
+ return device == AudioDevice::AUDIO_DEVICE_OUT_TELEPHONY_TX ||
+ device == AudioDevice::AUDIO_DEVICE_IN_TELEPHONY_RX;
+}
+
+static inline bool isTelephonyDevice(const std::string& device) {
+ return isTelephonyDevice(stringToAudioDevice(device));
+}
+
+static inline bool maybeVendorExtension(const std::string& s) {
+ // Only checks whether the string starts with the "vendor prefix".
+ static const std::string vendorPrefix = "VX_";
+ return s.size() > vendorPrefix.size() && s.substr(0, vendorPrefix.size()) == vendorPrefix;
+}
+
+static inline bool isVendorExtension(const std::string& s) {
+ // Must be the same as the "vendorExtension" rule from the XSD file.
+ static const std::regex vendorExtension("VX_[A-Z0-9]{3,}_[_A-Z0-9]+");
+ return std::regex_match(s.begin(), s.end(), vendorExtension);
+}
+
+static inline bool isUnknownAudioChannelMask(const std::string& mask) {
+ return stringToAudioChannelMask(mask) == AudioChannelMask::UNKNOWN;
+}
+
+static inline bool isUnknownAudioContentType(const std::string& contentType) {
+ return stringToAudioContentType(contentType) == AudioContentType::UNKNOWN;
+}
+
+static inline bool isUnknownAudioDevice(const std::string& device) {
+ return stringToAudioDevice(device) == AudioDevice::UNKNOWN && !isVendorExtension(device);
+}
+
+static inline bool isUnknownAudioFormat(const std::string& format) {
+ return stringToAudioFormat(format) == AudioFormat::UNKNOWN && !isVendorExtension(format);
+}
+
+static inline bool isUnknownAudioGainMode(const std::string& mode) {
+ return stringToAudioGainMode(mode) == AudioGainMode::UNKNOWN;
+}
+
+static inline bool isUnknownAudioInOutFlag(const std::string& flag) {
+ return stringToAudioInOutFlag(flag) == AudioInOutFlag::UNKNOWN;
+}
+
+static inline bool isUnknownAudioSource(const std::string& source) {
+ return stringToAudioSource(source) == AudioSource::UNKNOWN;
+}
+
+static inline bool isUnknownAudioStreamType(const std::string& streamType) {
+ return stringToAudioStreamType(streamType) == AudioStreamType::UNKNOWN;
+}
+
+static inline bool isUnknownAudioUsage(const std::string& usage) {
+ return stringToAudioUsage(usage) == AudioUsage::UNKNOWN;
+}
+
+static inline bool isLinearPcm(AudioFormat format) {
+ switch (format) {
+ case AudioFormat::AUDIO_FORMAT_PCM_16_BIT:
+ case AudioFormat::AUDIO_FORMAT_PCM_8_BIT:
+ case AudioFormat::AUDIO_FORMAT_PCM_32_BIT:
+ case AudioFormat::AUDIO_FORMAT_PCM_8_24_BIT:
+ case AudioFormat::AUDIO_FORMAT_PCM_FLOAT:
+ case AudioFormat::AUDIO_FORMAT_PCM_24_BIT_PACKED:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static inline bool isLinearPcm(const std::string& format) {
+ return isLinearPcm(stringToAudioFormat(format));
+}
+
+static inline bool isUnknownAudioEncapsulationType(const std::string& encapsulationType) {
+ return stringToAudioEncapsulationType(encapsulationType) == AudioEncapsulationType::UNKNOWN;
+}
+
+} // namespace android::audio::policy::configuration::V7_1
+
+#endif // ANDROID_AUDIO_POLICY_CONFIGURATION_V7_1__ENUMS_H
diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp
index 5a5b5d2..218d7c0 100644
--- a/audio/common/all-versions/default/7.0/HidlUtils.cpp
+++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp
@@ -21,7 +21,7 @@
#define LOG_TAG "HidlUtils"
#include <log/log.h>
-#include <android_audio_policy_configuration_V7_0-enums.h>
+#include PATH(APM_XSD_ENUMS_H_FILENAME)
#include <common/all-versions/HidlSupport.h>
#include <common/all-versions/VersionUtils.h>
@@ -31,11 +31,11 @@
namespace hardware {
namespace audio {
namespace common {
-namespace CPP_VERSION {
+namespace COMMON_TYPES_CPP_VERSION {
namespace implementation {
namespace xsd {
-using namespace ::android::audio::policy::configuration::V7_0;
+using namespace ::android::audio::policy::configuration::CPP_VERSION;
}
#define CONVERT_CHECKED(expr, result) \
@@ -1151,7 +1151,7 @@
}
} // namespace implementation
-} // namespace CPP_VERSION
+} // namespace COMMON_TYPES_CPP_VERSION
} // namespace common
} // namespace audio
} // namespace hardware
diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h
index 98ecc07..ad9dee2 100644
--- a/audio/common/all-versions/default/HidlUtils.h
+++ b/audio/common/all-versions/default/HidlUtils.h
@@ -17,7 +17,9 @@
#ifndef android_hardware_audio_Hidl_Utils_H_
#define android_hardware_audio_Hidl_Utils_H_
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format off
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
+// clang-format on
#include <memory>
#include <string>
@@ -29,11 +31,11 @@
namespace hardware {
namespace audio {
namespace common {
-namespace CPP_VERSION {
+namespace COMMON_TYPES_CPP_VERSION {
namespace implementation {
using ::android::hardware::hidl_vec;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
struct HidlUtils {
static status_t audioConfigFromHal(const audio_config_t& halConfig, bool isInput,
@@ -267,7 +269,7 @@
#endif // MAJOR_VERSION <= 6
} // namespace implementation
-} // namespace CPP_VERSION
+} // namespace COMMON_TYPES_CPP_VERSION
} // namespace common
} // namespace audio
} // namespace hardware
diff --git a/audio/common/all-versions/default/UuidUtils.h b/audio/common/all-versions/default/UuidUtils.h
index cd04fb0..4a64f0a 100644
--- a/audio/common/all-versions/default/UuidUtils.h
+++ b/audio/common/all-versions/default/UuidUtils.h
@@ -20,7 +20,7 @@
#include <string>
// clang-format off
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
// clang-format on
#include <system/audio.h>
@@ -32,7 +32,7 @@
namespace CPP_VERSION {
namespace implementation {
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
class UuidUtils {
public:
diff --git a/audio/common/all-versions/default/VersionUtils.h b/audio/common/all-versions/default/VersionUtils.h
index 9bfca0c..9771374 100644
--- a/audio/common/all-versions/default/VersionUtils.h
+++ b/audio/common/all-versions/default/VersionUtils.h
@@ -17,7 +17,30 @@
#ifndef ANDROID_HARDWARE_AUDIO_EFFECT_VERSION_UTILS_H
#define ANDROID_HARDWARE_AUDIO_EFFECT_VERSION_UTILS_H
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// A workaround for b/216149583 (vendor code having its own copy of VersionMacro.h)
+#ifndef COMMON_TYPES_MINOR_VERSION
+#define COMMON_TYPES_MINOR_VERSION MINOR_VERSION
+#endif
+#ifndef CORE_TYPES_MINOR_VERSION
+#define CORE_TYPES_MINOR_VERSION MINOR_VERSION
+#endif
+#ifndef COMMON_TYPES_FILE_VERSION
+#define COMMON_TYPES_FILE_VERSION EXPAND_CONCAT_3(MAJOR_VERSION, ., COMMON_TYPES_MINOR_VERSION)
+#endif
+#ifndef CORE_TYPES_FILE_VERSION
+#define CORE_TYPES_FILE_VERSION EXPAND_CONCAT_3(MAJOR_VERSION, ., CORE_TYPES_MINOR_VERSION)
+#endif
+#ifndef COMMON_TYPES_CPP_VERSION
+#define COMMON_TYPES_CPP_VERSION EXPAND_CONCAT_4(V, MAJOR_VERSION, _, COMMON_TYPES_MINOR_VERSION)
+#endif
+#ifndef CORE_TYPES_CPP_VERSION
+#define CORE_TYPES_CPP_VERSION EXPAND_CONCAT_4(V, MAJOR_VERSION, _, CORE_TYPES_MINOR_VERSION)
+#endif
+// End of workaround
+
+// clang-format off
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
+// clang-format on
namespace android {
namespace hardware {
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index 89585b0..e26369f 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -66,6 +66,7 @@
const std::vector<InterfacesList> mandatoryInterfaces = {
{
"Audio Core API",
+ "android.hardware.audio@7.1::IDevicesFactory",
"android.hardware.audio@7.0::IDevicesFactory",
"android.hardware.audio@6.0::IDevicesFactory",
"android.hardware.audio@5.0::IDevicesFactory",
diff --git a/audio/common/all-versions/default/tests/hidlutils6_tests.cpp b/audio/common/all-versions/default/tests/hidlutils6_tests.cpp
index 3a24e75..ca59b9d 100644
--- a/audio/common/all-versions/default/tests/hidlutils6_tests.cpp
+++ b/audio/common/all-versions/default/tests/hidlutils6_tests.cpp
@@ -23,14 +23,14 @@
#include <system/audio.h>
using namespace android;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
// Not generated automatically because DeviceAddress contains
// an union.
//
// operator== must be defined in the same namespace as the data type.
-namespace android::hardware::audio::common::CPP_VERSION {
+namespace android::hardware::audio::common::COMMON_TYPES_CPP_VERSION {
inline bool operator==(const DeviceAddress& lhs, const DeviceAddress& rhs) {
if (lhs.device != rhs.device) return false;
@@ -49,7 +49,7 @@
return lhs.busAddress == rhs.busAddress;
}
-} // namespace android::hardware::audio::common::CPP_VERSION
+} // namespace android::hardware::audio::common::COMMON_TYPES_CPP_VERSION
static void ConvertDeviceAddress(const DeviceAddress& device) {
audio_devices_t halDeviceType;
diff --git a/audio/common/all-versions/default/tests/hidlutils_tests.cpp b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
index c9e6fac..2749cce 100644
--- a/audio/common/all-versions/default/tests/hidlutils_tests.cpp
+++ b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
@@ -29,8 +29,8 @@
using namespace android;
using ::android::hardware::hidl_vec;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
namespace xsd {
using namespace ::android::audio::policy::configuration::V7_0;
}
diff --git a/audio/common/all-versions/util/include/common/all-versions/VersionMacro.h b/audio/common/all-versions/util/include/common/all-versions/VersionMacro.h
index dc54cee..875e167 100644
--- a/audio/common/all-versions/util/include/common/all-versions/VersionMacro.h
+++ b/audio/common/all-versions/util/include/common/all-versions/VersionMacro.h
@@ -21,6 +21,14 @@
#error "MAJOR_VERSION and MINOR_VERSION must be defined"
#endif
+#ifndef COMMON_TYPES_MINOR_VERSION
+#define COMMON_TYPES_MINOR_VERSION MINOR_VERSION
+#endif
+
+#ifndef CORE_TYPES_MINOR_VERSION
+#define CORE_TYPES_MINOR_VERSION MINOR_VERSION
+#endif
+
/** Allows macro expansion for x and add surrounding `<>`.
* Is intended to be used for version dependant includes as
* `#include` do not macro expand if starting with < or "
@@ -34,10 +42,30 @@
#define EXPAND_CONCAT_3(a, b, c) CONCAT_3(a, b, c)
/** The directory name of the version: <major>.<minor> */
#define FILE_VERSION EXPAND_CONCAT_3(MAJOR_VERSION, ., MINOR_VERSION)
+#define COMMON_TYPES_FILE_VERSION EXPAND_CONCAT_3(MAJOR_VERSION, ., COMMON_TYPES_MINOR_VERSION)
+#define CORE_TYPES_FILE_VERSION EXPAND_CONCAT_3(MAJOR_VERSION, ., CORE_TYPES_MINOR_VERSION)
#define CONCAT_4(a, b, c, d) a##b##c##d
#define EXPAND_CONCAT_4(a, b, c, d) CONCAT_4(a, b, c, d)
/** The c++ namespace of the version: V<major>_<minor> */
#define CPP_VERSION EXPAND_CONCAT_4(V, MAJOR_VERSION, _, MINOR_VERSION)
+#define COMMON_TYPES_CPP_VERSION EXPAND_CONCAT_4(V, MAJOR_VERSION, _, COMMON_TYPES_MINOR_VERSION)
+#define CORE_TYPES_CPP_VERSION EXPAND_CONCAT_4(V, MAJOR_VERSION, _, CORE_TYPES_MINOR_VERSION)
+
+/* Gluing these file names from macros is non-trivial due to "illegal tokens"
+ occurring during expansion. The XSD and enums always use the minor version. */
+// clang-format off
+#if MAJOR_VERSION >= 7
+#if MINOR_VERSION == 0
+#define APM_XSD_H_FILENAME android_audio_policy_configuration_V7_0.h
+#define APM_XSD_ENUMS_H_FILENAME android_audio_policy_configuration_V7_0-enums.h
+#elif MINOR_VERSION == 1
+#define APM_XSD_H_FILENAME android_audio_policy_configuration_V7_1.h
+#define APM_XSD_ENUMS_H_FILENAME android_audio_policy_configuration_V7_1-enums.h
+#else
+#error "Unsupported minor version"
+#endif
+#endif
+// clang-format on
#endif // ANDROID_HARDWARE_VERSION_MACRO_H
diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp
index 8fb7111..86380a5 100644
--- a/audio/core/all-versions/default/Android.bp
+++ b/audio/core/all-versions/default/Android.bp
@@ -159,3 +159,29 @@
name: "android.hardware.audio@7.0-impl",
defaults: ["android.hardware.audio@7.0-impl_default"],
}
+
+cc_defaults {
+ name: "android.hardware.audio@7.1-impl_default",
+ defaults: ["android.hardware.audio-impl_default"],
+ shared_libs: [
+ "android.hardware.audio@7.0",
+ "android.hardware.audio@7.1",
+ "android.hardware.audio@7.0-util",
+ "android.hardware.audio.common@7.0",
+ "android.hardware.audio.common@7.1-enums",
+ "android.hardware.audio.common@7.0-util",
+ "libbase",
+ ],
+ cflags: [
+ "-DMAJOR_VERSION=7",
+ "-DMINOR_VERSION=1",
+ "-DCOMMON_TYPES_MINOR_VERSION=0",
+ "-DCORE_TYPES_MINOR_VERSION=0",
+ "-include common/all-versions/VersionMacro.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.audio@7.1-impl",
+ defaults: ["android.hardware.audio@7.1-impl_default"],
+}
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp
index 130dfba..98a59b9 100644
--- a/audio/core/all-versions/default/Device.cpp
+++ b/audio/core/all-versions/default/Device.cpp
@@ -39,7 +39,10 @@
namespace CPP_VERSION {
namespace implementation {
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
+namespace util {
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util;
+}
Device::Device(audio_hw_device_t* device) : mIsClosed(false), mDevice(device) {}
@@ -82,7 +85,7 @@
if (mDevice->set_master_volume == NULL) {
return Result::NOT_SUPPORTED;
}
- if (!isGainNormalized(volume)) {
+ if (!util::isGainNormalized(volume)) {
ALOGW("Can not set a master volume (%f) outside [0,1]", volume);
return Result::INVALID_ARGUMENTS;
}
@@ -148,7 +151,7 @@
return Void();
}
-std::tuple<Result, sp<IStreamOut>> Device::openOutputStreamImpl(int32_t ioHandle,
+std::tuple<Result, sp<IStreamOut>> Device::openOutputStreamCore(int32_t ioHandle,
const DeviceAddress& device,
const AudioConfig& config,
const AudioOutputFlags& flags,
@@ -185,7 +188,7 @@
return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut};
}
-std::tuple<Result, sp<IStreamIn>> Device::openInputStreamImpl(
+std::tuple<Result, sp<IStreamIn>> Device::openInputStreamCore(
int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
const AudioInputFlags& flags, AudioSource source, AudioConfig* suggestedConfig) {
audio_config_t halConfig;
@@ -228,7 +231,7 @@
openOutputStream_cb _hidl_cb) {
AudioConfig suggestedConfig;
auto [result, streamOut] =
- openOutputStreamImpl(ioHandle, device, config, flags, &suggestedConfig);
+ openOutputStreamCore(ioHandle, device, config, flags, &suggestedConfig);
_hidl_cb(result, streamOut, suggestedConfig);
return Void();
}
@@ -238,12 +241,36 @@
AudioSource source, openInputStream_cb _hidl_cb) {
AudioConfig suggestedConfig;
auto [result, streamIn] =
- openInputStreamImpl(ioHandle, device, config, flags, source, &suggestedConfig);
+ openInputStreamCore(ioHandle, device, config, flags, source, &suggestedConfig);
_hidl_cb(result, streamIn, suggestedConfig);
return Void();
}
#elif MAJOR_VERSION >= 4
+std::tuple<Result, sp<IStreamOut>, AudioConfig> Device::openOutputStreamImpl(
+ int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
+ const SourceMetadata& sourceMetadata,
+#if MAJOR_VERSION <= 6
+ AudioOutputFlags flags) {
+ if (status_t status = CoreUtils::sourceMetadataToHal(sourceMetadata, nullptr);
+ status != NO_ERROR) {
+#else
+ const AudioOutputFlags& flags) {
+ if (status_t status = CoreUtils::sourceMetadataToHalV7(sourceMetadata,
+ false /*ignoreNonVendorTags*/, nullptr);
+ status != NO_ERROR) {
+#endif
+ return {analyzeStatus("sourceMetadataToHal", status), nullptr, {}};
+ }
+ AudioConfig suggestedConfig;
+ auto [result, streamOut] =
+ openOutputStreamCore(ioHandle, device, config, flags, &suggestedConfig);
+ if (streamOut) {
+ streamOut->updateSourceMetadata(sourceMetadata);
+ }
+ return {result, streamOut, suggestedConfig};
+}
+
Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
const AudioConfig& config,
#if MAJOR_VERSION <= 6
@@ -253,27 +280,46 @@
#endif
const SourceMetadata& sourceMetadata,
openOutputStream_cb _hidl_cb) {
-#if MAJOR_VERSION <= 6
- if (status_t status = CoreUtils::sourceMetadataToHal(sourceMetadata, nullptr);
- status != NO_ERROR) {
-#else
- if (status_t status = CoreUtils::sourceMetadataToHalV7(sourceMetadata,
- false /*ignoreNonVendorTags*/, nullptr);
- status != NO_ERROR) {
-#endif
- _hidl_cb(analyzeStatus("sourceMetadataToHal", status), nullptr, AudioConfig{});
- return Void();
- }
- AudioConfig suggestedConfig;
- auto [result, streamOut] =
- openOutputStreamImpl(ioHandle, device, config, flags, &suggestedConfig);
- if (streamOut) {
- streamOut->updateSourceMetadata(sourceMetadata);
- }
+ auto [result, streamOut, suggestedConfig] =
+ openOutputStreamImpl(ioHandle, device, config, sourceMetadata, flags);
_hidl_cb(result, streamOut, suggestedConfig);
return Void();
}
+std::tuple<Result, sp<IStreamIn>, AudioConfig> Device::openInputStreamImpl(
+ int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
+#if MAJOR_VERSION <= 6
+ AudioInputFlags flags,
+#else
+ const AudioInputFlags& flags,
+#endif
+ const SinkMetadata& sinkMetadata) {
+ if (sinkMetadata.tracks.size() == 0) {
+ // This should never happen, the framework must not create as stream
+ // if there is no client
+ ALOGE("openInputStream called without tracks connected");
+ return {Result::INVALID_ARGUMENTS, nullptr, AudioConfig{}};
+ }
+#if MAJOR_VERSION <= 6
+ if (status_t status = CoreUtils::sinkMetadataToHal(sinkMetadata, nullptr); status != NO_ERROR) {
+#else
+ if (status_t status = CoreUtils::sinkMetadataToHalV7(sinkMetadata,
+ false /*ignoreNonVendorTags*/, nullptr);
+ status != NO_ERROR) {
+#endif
+ return {analyzeStatus("sinkMetadataToHal", status), nullptr, AudioConfig{}};
+ }
+ // Pick the first one as the main.
+ AudioSource source = sinkMetadata.tracks[0].source;
+ AudioConfig suggestedConfig;
+ auto [result, streamIn] =
+ openInputStreamCore(ioHandle, device, config, flags, source, &suggestedConfig);
+ if (streamIn) {
+ streamIn->updateSinkMetadata(sinkMetadata);
+ }
+ return {result, streamIn, suggestedConfig};
+}
+
Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device,
const AudioConfig& config,
#if MAJOR_VERSION <= 6
@@ -283,36 +329,35 @@
#endif
const SinkMetadata& sinkMetadata,
openInputStream_cb _hidl_cb) {
- if (sinkMetadata.tracks.size() == 0) {
- // This should never happen, the framework must not create as stream
- // if there is no client
- ALOGE("openInputStream called without tracks connected");
- _hidl_cb(Result::INVALID_ARGUMENTS, nullptr, AudioConfig{});
- return Void();
- }
-#if MAJOR_VERSION <= 6
- if (status_t status = CoreUtils::sinkMetadataToHal(sinkMetadata, nullptr); status != NO_ERROR) {
-#else
- if (status_t status = CoreUtils::sinkMetadataToHalV7(sinkMetadata,
- false /*ignoreNonVendorTags*/, nullptr);
- status != NO_ERROR) {
-#endif
- _hidl_cb(analyzeStatus("sinkMetadataToHal", status), nullptr, AudioConfig{});
- return Void();
- }
- // Pick the first one as the main.
- AudioSource source = sinkMetadata.tracks[0].source;
- AudioConfig suggestedConfig;
- auto [result, streamIn] =
- openInputStreamImpl(ioHandle, device, config, flags, source, &suggestedConfig);
- if (streamIn) {
- streamIn->updateSinkMetadata(sinkMetadata);
- }
+ auto [result, streamIn, suggestedConfig] =
+ openInputStreamImpl(ioHandle, device, config, flags, sinkMetadata);
_hidl_cb(result, streamIn, suggestedConfig);
return Void();
}
#endif /* MAJOR_VERSION */
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+Return<void> Device::openOutputStream_7_1(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config, const AudioOutputFlags& flags,
+ const SourceMetadata& sourceMetadata,
+ openOutputStream_7_1_cb _hidl_cb) {
+ auto [result, streamOut, suggestedConfig] =
+ openOutputStreamImpl(ioHandle, device, config, sourceMetadata, flags);
+ _hidl_cb(result, streamOut, suggestedConfig);
+ return Void();
+}
+
+Return<void> Device::openInputStream_7_1(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config, const AudioInputFlags& flags,
+ const SinkMetadata& sinkMetadata,
+ openInputStream_7_1_cb _hidl_cb) {
+ auto [result, streamIn, suggestedConfig] =
+ openInputStreamImpl(ioHandle, device, config, flags, sinkMetadata);
+ _hidl_cb(result, streamIn, suggestedConfig);
+ return Void();
+}
+#endif // V7.1
+
Return<bool> Device::supportsAudioPatches() {
return version() >= AUDIO_DEVICE_API_VERSION_3_0;
}
diff --git a/audio/core/all-versions/default/DevicesFactory.cpp b/audio/core/all-versions/default/DevicesFactory.cpp
index 729f18c..f44daf0 100644
--- a/audio/core/all-versions/default/DevicesFactory.cpp
+++ b/audio/core/all-versions/default/DevicesFactory.cpp
@@ -47,22 +47,54 @@
_hidl_cb(Result::INVALID_ARGUMENTS, nullptr);
return Void();
}
+
+Return<void> DevicesFactory::openDevice(const char* moduleName, openDevice_cb _hidl_cb) {
+ return openDevice<implementation::Device>(moduleName, _hidl_cb);
+}
#elif MAJOR_VERSION >= 4
Return<void> DevicesFactory::openDevice(const hidl_string& moduleName, openDevice_cb _hidl_cb) {
if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
return openDevice<PrimaryDevice>(moduleName.c_str(), _hidl_cb);
}
- return openDevice(moduleName.c_str(), _hidl_cb);
+ return openDevice<implementation::Device>(moduleName.c_str(), _hidl_cb);
}
Return<void> DevicesFactory::openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) {
return openDevice<PrimaryDevice>(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb);
}
#endif
-Return<void> DevicesFactory::openDevice(const char* moduleName, openDevice_cb _hidl_cb) {
- return openDevice<implementation::Device>(moduleName, _hidl_cb);
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+Return<void> DevicesFactory::openDevice_7_1(const hidl_string& moduleName,
+ openDevice_7_1_cb _hidl_cb) {
+ if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
+ Result result;
+ sp<IPrimaryDevice> primary;
+ auto ret = openDevice<PrimaryDevice>(
+ AUDIO_HARDWARE_MODULE_ID_PRIMARY,
+ [&result, &primary](Result r, const sp<IPrimaryDevice>& p) {
+ result = r;
+ primary = p;
+ });
+ if (ret.isOk() && result == Result::OK && primary != nullptr) {
+ auto getDeviceRet = primary->getDevice();
+ if (getDeviceRet.isOk()) {
+ _hidl_cb(result, getDeviceRet);
+ } else {
+ _hidl_cb(Result::NOT_INITIALIZED, nullptr);
+ }
+ } else {
+ _hidl_cb(result, nullptr);
+ }
+ return Void();
+ }
+ return openDevice<implementation::Device>(moduleName.c_str(), _hidl_cb);
}
+Return<void> DevicesFactory::openPrimaryDevice_7_1(openPrimaryDevice_7_1_cb _hidl_cb) {
+ return openDevice<PrimaryDevice>(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb);
+}
+#endif // V7.1
+
template <class DeviceShim, class Callback>
Return<void> DevicesFactory::openDevice(const char* moduleName, Callback _hidl_cb) {
audio_hw_device_t* halDevice;
diff --git a/audio/core/all-versions/default/ParametersUtil.cpp b/audio/core/all-versions/default/ParametersUtil.cpp
index 4d53645..e21eff2 100644
--- a/audio/core/all-versions/default/ParametersUtil.cpp
+++ b/audio/core/all-versions/default/ParametersUtil.cpp
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace audio {
-namespace CPP_VERSION {
+namespace CORE_TYPES_CPP_VERSION {
namespace implementation {
/** Converts a status_t in Result according to the rules of AudioParameter::get*
@@ -168,7 +168,7 @@
}
} // namespace implementation
-} // namespace CPP_VERSION
+} // namespace CORE_TYPES_CPP_VERSION
} // namespace audio
} // namespace hardware
} // namespace android
diff --git a/audio/core/all-versions/default/PrimaryDevice.cpp b/audio/core/all-versions/default/PrimaryDevice.cpp
index fe56177..cf162f1 100644
--- a/audio/core/all-versions/default/PrimaryDevice.cpp
+++ b/audio/core/all-versions/default/PrimaryDevice.cpp
@@ -29,6 +29,10 @@
namespace CPP_VERSION {
namespace implementation {
+namespace util {
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util;
+}
+
PrimaryDevice::PrimaryDevice(audio_hw_device_t* device) : mDevice(new Device(device)) {}
PrimaryDevice::~PrimaryDevice() {
@@ -195,7 +199,7 @@
// Methods from ::android::hardware::audio::CPP_VERSION::IPrimaryDevice follow.
Return<Result> PrimaryDevice::setVoiceVolume(float volume) {
- if (!isGainNormalized(volume)) {
+ if (!util::isGainNormalized(volume)) {
ALOGW("Can not set a voice volume (%f) outside [0,1]", volume);
return Result::INVALID_ARGUMENTS;
}
@@ -326,7 +330,7 @@
return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_SET_SAMPLING_RATE, int(sampleRateHz));
}
Return<Result> PrimaryDevice::setBtHfpVolume(float volume) {
- if (!isGainNormalized(volume)) {
+ if (!util::isGainNormalized(volume)) {
ALOGW("Can not set BT HFP volume (%f) outside [0,1]", volume);
return Result::INVALID_ARGUMENTS;
}
diff --git a/audio/core/all-versions/default/Stream.cpp b/audio/core/all-versions/default/Stream.cpp
index 7e32573..8e85a8b 100644
--- a/audio/core/all-versions/default/Stream.cpp
+++ b/audio/core/all-versions/default/Stream.cpp
@@ -37,8 +37,12 @@
namespace CPP_VERSION {
namespace implementation {
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
using ::android::hardware::audio::common::utils::splitString;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
+namespace util {
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util;
+}
Stream::Stream(bool isInput, audio_stream_t* stream) : mIsInput(isInput), mStream(stream) {
(void)mIsInput; // prevent 'unused field' warnings in pre-V7 versions.
diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp
index 2aeee43..2bea425 100644
--- a/audio/core/all-versions/default/StreamIn.cpp
+++ b/audio/core/all-versions/default/StreamIn.cpp
@@ -37,7 +37,11 @@
namespace CPP_VERSION {
namespace implementation {
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
+namespace util {
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util;
+}
namespace {
@@ -348,7 +352,7 @@
}
Return<Result> StreamIn::setGain(float gain) {
- if (!isGainNormalized(gain)) {
+ if (!util::isGainNormalized(gain)) {
ALOGW("Can not set a stream input gain (%f) outside [0,1]", gain);
return Result::INVALID_ARGUMENTS;
}
diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp
index d027231..09df4ed 100644
--- a/audio/core/all-versions/default/StreamOut.cpp
+++ b/audio/core/all-versions/default/StreamOut.cpp
@@ -39,7 +39,11 @@
namespace CPP_VERSION {
namespace implementation {
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
+namespace util {
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util;
+}
namespace {
@@ -334,7 +338,7 @@
if (mStream->set_volume == NULL) {
return Result::NOT_SUPPORTED;
}
- if (!isGainNormalized(left)) {
+ if (!util::isGainNormalized(left)) {
ALOGW("Can not set a stream output volume {%f, %f} outside [0,1]", left, right);
return Result::INVALID_ARGUMENTS;
}
@@ -757,6 +761,73 @@
ALOGW_IF(!result.isOk(), "Client callback failed: %s", result.description().c_str());
return 0;
}
+
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+Return<Result> StreamOut::setLatencyMode(LatencyMode mode) {
+ return mStream->set_latency_mode != nullptr
+ ? Stream::analyzeStatus(
+ "set_latency_mode",
+ mStream->set_latency_mode(mStream,
+ static_cast<audio_latency_mode_t>(mode)))
+ : Result::NOT_SUPPORTED;
+};
+
+Return<void> StreamOut::getRecommendedLatencyModes(getRecommendedLatencyModes_cb _hidl_cb) {
+ Result retval = Result::NOT_SUPPORTED;
+ hidl_vec<LatencyMode> hidlModes;
+ size_t num_modes = AUDIO_LATENCY_MODE_CNT;
+ audio_latency_mode_t modes[AUDIO_LATENCY_MODE_CNT];
+
+ if (mStream->get_recommended_latency_modes != nullptr &&
+ mStream->get_recommended_latency_modes(mStream, &modes[0], &num_modes) == 0) {
+ if (num_modes == 0 || num_modes > AUDIO_LATENCY_MODE_CNT) {
+ ALOGW("%s invalid number of modes returned: %zu", __func__, num_modes);
+ retval = Result::INVALID_STATE;
+ } else {
+ hidlModes.resize(num_modes);
+ for (size_t i = 0; i < num_modes; ++i) {
+ hidlModes[i] = static_cast<LatencyMode>(modes[i]);
+ }
+ retval = Result::OK;
+ }
+ }
+ _hidl_cb(retval, hidlModes);
+ return Void();
+};
+
+// static
+void StreamOut::latencyModeCallback(audio_latency_mode_t* modes, size_t num_modes, void* cookie) {
+ StreamOut* self = reinterpret_cast<StreamOut*>(cookie);
+ sp<IStreamOutLatencyModeCallback> callback = self->mLatencyModeCallback.load();
+ if (callback.get() == nullptr) return;
+
+ ALOGV("%s", __func__);
+
+ if (num_modes == 0 || num_modes > AUDIO_LATENCY_MODE_CNT) {
+ ALOGW("%s invalid number of modes returned: %zu", __func__, num_modes);
+ return;
+ }
+
+ hidl_vec<LatencyMode> hidlModes(num_modes);
+ for (size_t i = 0; i < num_modes; ++i) {
+ hidlModes[i] = static_cast<LatencyMode>(modes[i]);
+ }
+ Return<void> result = callback->onRecommendedLatencyModeChanged(hidlModes);
+ ALOGW_IF(!result.isOk(), "Client callback failed: %s", result.description().c_str());
+}
+
+Return<Result> StreamOut::setLatencyModeCallback(
+ const sp<IStreamOutLatencyModeCallback>& callback) {
+ if (mStream->set_latency_mode_callback == nullptr) return Result::NOT_SUPPORTED;
+ int result = mStream->set_latency_mode_callback(mStream, StreamOut::latencyModeCallback, this);
+ if (result == 0) {
+ mLatencyModeCallback = callback;
+ }
+ return Stream::analyzeStatus("set_latency_mode_callback", result, {ENOSYS} /*ignore*/);
+};
+
+#endif
+
#endif
} // namespace implementation
diff --git a/audio/core/all-versions/default/include/core/default/Device.h b/audio/core/all-versions/default/include/core/default/Device.h
index 94cad53..0aeb6b3 100644
--- a/audio/core/all-versions/default/include/core/default/Device.h
+++ b/audio/core/all-versions/default/include/core/default/Device.h
@@ -44,7 +44,10 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::ParametersUtil;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CPP_VERSION;
using AudioInputFlags = CoreUtils::AudioInputFlags;
using AudioOutputFlags = CoreUtils::AudioOutputFlags;
@@ -63,14 +66,32 @@
Return<void> getInputBufferSize(const AudioConfig& config,
getInputBufferSize_cb _hidl_cb) override;
- std::tuple<Result, sp<IStreamOut>> openOutputStreamImpl(int32_t ioHandle,
+ std::tuple<Result, sp<IStreamOut>> openOutputStreamCore(int32_t ioHandle,
const DeviceAddress& device,
const AudioConfig& config,
const AudioOutputFlags& flags,
AudioConfig* suggestedConfig);
- std::tuple<Result, sp<IStreamIn>> openInputStreamImpl(
+ std::tuple<Result, sp<IStreamIn>> openInputStreamCore(
int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
const AudioInputFlags& flags, AudioSource source, AudioConfig* suggestedConfig);
+#if MAJOR_VERSION >= 4
+ std::tuple<Result, sp<IStreamOut>, AudioConfig> openOutputStreamImpl(
+ int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
+ const SourceMetadata& sourceMetadata,
+#if MAJOR_VERSION <= 6
+ AudioOutputFlags flags);
+#else
+ const AudioOutputFlags& flags);
+#endif
+ std::tuple<Result, sp<IStreamIn>, AudioConfig> openInputStreamImpl(
+ int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
+#if MAJOR_VERSION <= 6
+ AudioInputFlags flags,
+#else
+ const AudioInputFlags& flags,
+#endif
+ const SinkMetadata& sinkMetadata);
+#endif // MAJOR_VERSION >= 4
Return<void> openOutputStream(int32_t ioHandle, const DeviceAddress& device,
const AudioConfig& config,
@@ -97,6 +118,17 @@
#endif
openInputStream_cb _hidl_cb) override;
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ Return<void> openOutputStream_7_1(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config, const AudioOutputFlags& flags,
+ const SourceMetadata& sourceMetadata,
+ openOutputStream_7_1_cb _hidl_cb) override;
+ Return<void> openInputStream_7_1(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config, const AudioInputFlags& flags,
+ const SinkMetadata& sinkMetadata,
+ openInputStream_7_1_cb _hidl_cb) override;
+#endif
+
Return<bool> supportsAudioPatches() override;
Return<void> createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
const hidl_vec<AudioPortConfig>& sinks,
diff --git a/audio/core/all-versions/default/include/core/default/DevicesFactory.h b/audio/core/all-versions/default/include/core/default/DevicesFactory.h
index 9f93a38..566bc8a 100644
--- a/audio/core/all-versions/default/include/core/default/DevicesFactory.h
+++ b/audio/core/all-versions/default/include/core/default/DevicesFactory.h
@@ -44,11 +44,17 @@
Return<void> openDevice(const hidl_string& device, openDevice_cb _hidl_cb) override;
Return<void> openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) override;
#endif
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ Return<void> openDevice_7_1(const hidl_string& device, openDevice_7_1_cb _hidl_cb) override;
+ Return<void> openPrimaryDevice_7_1(openPrimaryDevice_7_1_cb _hidl_cb) override;
+#endif
- private:
+ private:
template <class DeviceShim, class Callback>
Return<void> openDevice(const char* moduleName, Callback _hidl_cb);
+#if MAJOR_VERSION == 2
Return<void> openDevice(const char* moduleName, openDevice_cb _hidl_cb);
+#endif
static int loadAudioInterface(const char* if_name, audio_hw_device_t** dev);
};
diff --git a/audio/core/all-versions/default/include/core/default/ParametersUtil.h b/audio/core/all-versions/default/include/core/default/ParametersUtil.h
index 45d9b21..25c193a 100644
--- a/audio/core/all-versions/default/include/core/default/ParametersUtil.h
+++ b/audio/core/all-versions/default/include/core/default/ParametersUtil.h
@@ -17,7 +17,10 @@
#ifndef ANDROID_HARDWARE_AUDIO_PARAMETERS_UTIL_H_
#define ANDROID_HARDWARE_AUDIO_PARAMETERS_UTIL_H_
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+// clang-format off
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+// clang-format on
#include <functional>
#include <memory>
@@ -28,13 +31,13 @@
namespace android {
namespace hardware {
namespace audio {
-namespace CPP_VERSION {
+namespace CORE_TYPES_CPP_VERSION {
namespace implementation {
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using namespace ::android::hardware::audio::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
class ParametersUtil {
public:
@@ -62,7 +65,7 @@
};
} // namespace implementation
-} // namespace CPP_VERSION
+} // namespace CORE_TYPES_CPP_VERSION
} // namespace audio
} // namespace hardware
} // namespace android
diff --git a/audio/core/all-versions/default/include/core/default/PrimaryDevice.h b/audio/core/all-versions/default/include/core/default/PrimaryDevice.h
index 5f65acf..8b37e01 100644
--- a/audio/core/all-versions/default/include/core/default/PrimaryDevice.h
+++ b/audio/core/all-versions/default/include/core/default/PrimaryDevice.h
@@ -36,7 +36,8 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CPP_VERSION;
struct PrimaryDevice : public IPrimaryDevice {
@@ -135,8 +136,10 @@
Return<Result> setBtHfpVolume(float volume) override;
Return<Result> updateRotation(IPrimaryDevice::Rotation rotation) override;
#endif
-
- private:
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ Return<sp<::android::hardware::audio::V7_1::IDevice>> getDevice() override { return mDevice; }
+#endif
+ private:
sp<Device> mDevice;
virtual ~PrimaryDevice();
diff --git a/audio/core/all-versions/default/include/core/default/Stream.h b/audio/core/all-versions/default/include/core/default/Stream.h
index 66d60e3..4e79884 100644
--- a/audio/core/all-versions/default/include/core/default/Stream.h
+++ b/audio/core/all-versions/default/include/core/default/Stream.h
@@ -17,7 +17,9 @@
#ifndef ANDROID_HARDWARE_AUDIO_STREAM_H
#define ANDROID_HARDWARE_AUDIO_STREAM_H
-#include PATH(android/hardware/audio/FILE_VERSION/IStream.h)
+// clang-format off
+#include PATH(android/hardware/audio/COMMON_TYPES_FILE_VERSION/IStream.h)
+// clang-format on
#include "ParametersUtil.h"
@@ -41,10 +43,13 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::ParametersUtil;
#if MAJOR_VERSION <= 6
-using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioChannelBitfield;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::
+ AudioChannelBitfield;
#endif
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CPP_VERSION;
struct Stream : public IStream, public ParametersUtil {
diff --git a/audio/core/all-versions/default/include/core/default/StreamIn.h b/audio/core/all-versions/default/include/core/default/StreamIn.h
index a980f3f..a6346e5 100644
--- a/audio/core/all-versions/default/include/core/default/StreamIn.h
+++ b/audio/core/all-versions/default/include/core/default/StreamIn.h
@@ -42,7 +42,8 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CPP_VERSION;
struct StreamIn : public IStreamIn {
diff --git a/audio/core/all-versions/default/include/core/default/StreamOut.h b/audio/core/all-versions/default/include/core/default/StreamOut.h
index 0b07972..ce5253f 100644
--- a/audio/core/all-versions/default/include/core/default/StreamOut.h
+++ b/audio/core/all-versions/default/include/core/default/StreamOut.h
@@ -43,7 +43,8 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CPP_VERSION;
struct StreamOut : public IStreamOut {
@@ -152,6 +153,12 @@
Result doUpdateSourceMetadata(const SourceMetadata& sourceMetadata);
#if MAJOR_VERSION >= 7
Result doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata);
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ Return<Result> setLatencyMode(LatencyMode mode) override;
+ Return<void> getRecommendedLatencyModes(getRecommendedLatencyModes_cb _hidl_cb) override;
+ Return<Result> setLatencyModeCallback(
+ const sp<IStreamOutLatencyModeCallback>& callback) override;
+#endif
#endif
#endif // MAJOR_VERSION >= 4
@@ -162,6 +169,9 @@
mediautils::atomic_sp<IStreamOutCallback> mCallback; // for non-blocking write and drain
#if MAJOR_VERSION >= 6
mediautils::atomic_sp<IStreamOutEventCallback> mEventCallback;
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ mediautils::atomic_sp<IStreamOutLatencyModeCallback> mLatencyModeCallback;
+#endif
#endif
std::unique_ptr<CommandMQ> mCommandMQ;
std::unique_ptr<DataMQ> mDataMQ;
@@ -176,6 +186,9 @@
#if MAJOR_VERSION >= 6
static int asyncEventCallback(stream_event_callback_type_t event, void* param, void* cookie);
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ static void latencyModeCallback(audio_latency_mode_t* modes, size_t num_modes, void* cookie);
+#endif
#endif
};
diff --git a/audio/core/all-versions/default/include/core/default/Util.h b/audio/core/all-versions/default/include/core/default/Util.h
index 78ae03e..abf5317 100644
--- a/audio/core/all-versions/default/include/core/default/Util.h
+++ b/audio/core/all-versions/default/include/core/default/Util.h
@@ -17,7 +17,9 @@
#ifndef ANDROID_HARDWARE_AUDIO_UTIL_H
#define ANDROID_HARDWARE_AUDIO_UTIL_H
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+// clang-format off
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+// clang-format on
#include <algorithm>
#include <vector>
@@ -27,19 +29,19 @@
namespace android {
namespace hardware {
namespace audio {
-namespace CPP_VERSION {
+namespace CORE_TYPES_CPP_VERSION {
namespace implementation {
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using namespace ::android::hardware::audio::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
+
+namespace util {
/** @return true if gain is between 0 and 1 included. */
constexpr bool isGainNormalized(float gain) {
return gain >= 0.0 && gain <= 1.0;
}
-namespace util {
-
template <typename T>
inline bool element_in(T e, const std::vector<T>& v) {
return std::find(v.begin(), v.end(), e) != v.end();
@@ -72,7 +74,7 @@
} // namespace util
} // namespace implementation
-} // namespace CPP_VERSION
+} // namespace CORE_TYPES_CPP_VERSION
} // namespace audio
} // namespace hardware
} // namespace android
diff --git a/audio/core/all-versions/default/util/CoreUtils.cpp b/audio/core/all-versions/default/util/CoreUtils.cpp
index 773be21..8e83ea1 100644
--- a/audio/core/all-versions/default/util/CoreUtils.cpp
+++ b/audio/core/all-versions/default/util/CoreUtils.cpp
@@ -15,24 +15,24 @@
*/
#if MAJOR_VERSION >= 7
-#include <android_audio_policy_configuration_V7_0-enums.h>
+#include PATH(APM_XSD_ENUMS_H_FILENAME)
#endif
#include <HidlUtils.h>
#include <log/log.h>
#include "util/CoreUtils.h"
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
#if MAJOR_VERSION >= 7
namespace xsd {
-using namespace ::android::audio::policy::configuration::V7_0;
+using namespace ::android::audio::policy::configuration::CPP_VERSION;
}
#endif
namespace android {
namespace hardware {
namespace audio {
-namespace CPP_VERSION {
+namespace CORE_TYPES_CPP_VERSION {
namespace implementation {
#define CONVERT_CHECKED(expr, result) \
@@ -389,7 +389,7 @@
#if MAJOR_VERSION >= 7
namespace xsd {
-using namespace ::android::audio::policy::configuration::V7_0;
+using namespace ::android::audio::policy::configuration::CPP_VERSION;
}
status_t CoreUtils::audioInputFlagsFromHal(audio_input_flags_t halFlagMask,
@@ -470,7 +470,7 @@
#endif
} // namespace implementation
-} // namespace CPP_VERSION
+} // namespace CORE_TYPES_CPP_VERSION
} // namespace audio
} // namespace hardware
} // namespace android
diff --git a/audio/core/all-versions/default/util/include/util/CoreUtils.h b/audio/core/all-versions/default/util/include/util/CoreUtils.h
index 1e5272a..dc35772 100644
--- a/audio/core/all-versions/default/util/include/util/CoreUtils.h
+++ b/audio/core/all-versions/default/util/include/util/CoreUtils.h
@@ -17,7 +17,7 @@
#pragma once
// clang-format off
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
// clang-format off
#include <vector>
@@ -30,13 +30,13 @@
namespace android {
namespace hardware {
namespace audio {
-namespace CPP_VERSION {
+namespace CORE_TYPES_CPP_VERSION {
namespace implementation {
using ::android::hardware::audio::common::utils::EnumBitfield;
using ::android::hardware::hidl_vec;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using namespace ::android::hardware::audio::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
struct CoreUtils {
// Note: the converters for DeviceAddress have to be in CoreUtils for HAL V4
@@ -93,8 +93,8 @@
return NO_ERROR;
}
#else
- using AudioInputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>;
- using AudioOutputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>;
+ using AudioInputFlags = hidl_vec<::android::hardware::audio::CORE_TYPES_CPP_VERSION::AudioInOutFlag>;
+ using AudioOutputFlags = hidl_vec<::android::hardware::audio::CORE_TYPES_CPP_VERSION::AudioInOutFlag>;
static status_t audioInputFlagsFromHal(audio_input_flags_t halFlagMask, AudioInputFlags* flags);
static status_t audioInputFlagsToHal(const AudioInputFlags& flags, audio_input_flags_t* halFlagMask);
static status_t audioOutputFlagsFromHal(audio_output_flags_t halFlagMask, AudioOutputFlags* flags);
diff --git a/audio/core/all-versions/default/util/tests/coreutils_tests.cpp b/audio/core/all-versions/default/util/tests/coreutils_tests.cpp
index 0c18482..3976b08 100644
--- a/audio/core/all-versions/default/util/tests/coreutils_tests.cpp
+++ b/audio/core/all-versions/default/util/tests/coreutils_tests.cpp
@@ -28,7 +28,7 @@
#include <xsdc/XsdcSupport.h>
using namespace android;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CPP_VERSION;
using ::android::hardware::hidl_vec;
using ::android::hardware::audio::CPP_VERSION::implementation::CoreUtils;
diff --git a/audio/core/all-versions/vts/functional/2.0/AudioPrimaryHidlHalUtils.h b/audio/core/all-versions/vts/functional/2.0/AudioPrimaryHidlHalUtils.h
index 1cffd41..dd80dd6 100644
--- a/audio/core/all-versions/vts/functional/2.0/AudioPrimaryHidlHalUtils.h
+++ b/audio/core/all-versions/vts/functional/2.0/AudioPrimaryHidlHalUtils.h
@@ -14,16 +14,18 @@
* limitations under the License.
*/
+// clang-format off
#include PATH(android/hardware/audio/FILE_VERSION/IStream.h)
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
+// clang-format on
#include <hidl/HidlSupport.h>
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
-using ::android::hardware::audio::common::CPP_VERSION::AudioChannelMask;
-using ::android::hardware::audio::common::CPP_VERSION::AudioFormat;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioChannelMask;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioFormat;
using ::android::hardware::audio::CPP_VERSION::IStream;
using ::android::hardware::audio::CPP_VERSION::ParameterValue;
using ::android::hardware::audio::CPP_VERSION::Result;
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index 787654b..a9797bb 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -17,7 +17,7 @@
#include "AudioPrimaryHidlHalTest.h"
#if MAJOR_VERSION >= 7
-#include <android_audio_policy_configuration_V7_0.h>
+#include PATH(APM_XSD_H_FILENAME)
#include <xsdc/XsdcSupport.h>
using android::xsdc_enum_range;
@@ -28,17 +28,37 @@
if (getDeviceName() != DeviceManager::kPrimaryDevice) {
GTEST_SKIP() << "No primary device on this factory"; // returns
}
-
- { // Scope for device SPs
- sp<IDevice> baseDevice =
- DeviceManager::getInstance().get(getFactoryName(), DeviceManager::kPrimaryDevice);
- ASSERT_TRUE(baseDevice != nullptr);
- Return<sp<IPrimaryDevice>> primaryDevice = IPrimaryDevice::castFrom(baseDevice);
- EXPECT_TRUE(primaryDevice.isOk());
- EXPECT_TRUE(sp<IPrimaryDevice>(primaryDevice) != nullptr);
- }
EXPECT_TRUE(
DeviceManager::getInstance().reset(getFactoryName(), DeviceManager::kPrimaryDevice));
+
+ // Must use IDevicesFactory directly because DeviceManager always uses
+ // the latest interfaces version and corresponding methods for opening
+ // them. However, in minor package uprevs IPrimaryDevice does not inherit
+ // IDevice from the same package and thus IDevice can not be upcasted
+ // (see the interfaces in V7.1).
+ auto factory = DevicesFactoryManager::getInstance().get(getFactoryName());
+ ASSERT_TRUE(factory != nullptr);
+ sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IDevice> baseDevice;
+ Result result;
+ auto ret = factory->openDevice(DeviceManager::kPrimaryDevice, returnIn(result, baseDevice));
+ ASSERT_TRUE(ret.isOk()) << ret.description();
+ ASSERT_EQ(Result::OK, result);
+ ASSERT_TRUE(baseDevice != nullptr);
+ {
+ Return<sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IPrimaryDevice>>
+ primaryDevice = ::android::hardware::audio::CORE_TYPES_CPP_VERSION::IPrimaryDevice::
+ castFrom(baseDevice);
+ EXPECT_TRUE(primaryDevice.isOk());
+ EXPECT_TRUE(sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IPrimaryDevice>(
+ primaryDevice) != nullptr);
+ }
+#if MAJOR_VERSION < 6
+ baseDevice.clear();
+ DeviceManager::waitForInstanceDestruction();
+#else
+ auto closeRet = baseDevice->close();
+ EXPECT_TRUE(closeRet.isOk());
+#endif
}
//////////////////////////////////////////////////////////////////////////////
@@ -183,7 +203,7 @@
areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported")
: testSetDevices(stream.get(), address))
-static void checkGetHwAVSync(IDevice* device) {
+static void checkGetHwAVSync(::android::hardware::audio::CPP_VERSION::IDevice* device) {
Result res;
AudioHwSync sync;
ASSERT_OK(device->getHwAvSync(returnIn(res, sync)));
@@ -215,7 +235,7 @@
ASSERT_OK(stream->updateSinkMetadata(initMetadata));
#elif MAJOR_VERSION >= 7
- xsdc_enum_range<android::audio::policy::configuration::V7_0::AudioSource> range;
+ xsdc_enum_range<android::audio::policy::configuration::CPP_VERSION::AudioSource> range;
// Test all possible track configuration
for (auto source : range) {
for (float volume : {0.0, 0.5, 1.0}) {
@@ -272,8 +292,9 @@
// Restore initial
ASSERT_OK(stream->updateSourceMetadata(initMetadata));
#elif MAJOR_VERSION >= 7
- xsdc_enum_range<android::audio::policy::configuration::V7_0::AudioUsage> usageRange;
- xsdc_enum_range<android::audio::policy::configuration::V7_0::AudioContentType> contentRange;
+ xsdc_enum_range<android::audio::policy::configuration::CPP_VERSION::AudioUsage> usageRange;
+ xsdc_enum_range<android::audio::policy::configuration::CPP_VERSION::AudioContentType>
+ contentRange;
// Test all possible track configuration
for (auto usage : usageRange) {
for (auto content : contentRange) {
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
index 81a1f7b..a567cf9 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
@@ -14,33 +14,36 @@
* limitations under the License.
*/
-#include PATH(android/hardware/audio/FILE_VERSION/IStream.h)
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format off
+#include PATH(android/hardware/audio/FILE_VERSION/IStreamIn.h)
+#include PATH(android/hardware/audio/FILE_VERSION/IStreamOut.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
+// clang-format on
#include <hidl/HidlSupport.h>
using ::android::hardware::hidl_bitfield;
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
-using ::android::hardware::audio::common::CPP_VERSION::AudioChannelMask;
-using ::android::hardware::audio::common::CPP_VERSION::AudioFormat;
-using ::android::hardware::audio::CPP_VERSION::IStream;
-using ::android::hardware::audio::CPP_VERSION::ParameterValue;
-using ::android::hardware::audio::CPP_VERSION::Result;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioChannelMask;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioFormat;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStream;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::ParameterValue;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::Result;
using namespace ::android::hardware::audio::common::test::utility;
-using Rotation = ::android::hardware::audio::CPP_VERSION::IPrimaryDevice::Rotation;
-using ::android::hardware::audio::common::CPP_VERSION::AudioContentType;
-using ::android::hardware::audio::common::CPP_VERSION::AudioUsage;
-using ::android::hardware::audio::CPP_VERSION::MicrophoneInfo;
+using Rotation = ::android::hardware::audio::CORE_TYPES_CPP_VERSION::IPrimaryDevice::Rotation;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioContentType;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioUsage;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::MicrophoneInfo;
#if MAJOR_VERSION < 5
using ::android::hardware::audio::CPP_VERSION::SinkMetadata;
using ::android::hardware::audio::CPP_VERSION::SourceMetadata;
#else
-using ::android::hardware::audio::common::CPP_VERSION::SinkMetadata;
-using ::android::hardware::audio::common::CPP_VERSION::SourceMetadata;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::SinkMetadata;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::SourceMetadata;
#endif
struct Parameters {
diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
index 8af4c78..aef94da 100644
--- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
@@ -59,7 +59,8 @@
testAccessors<OPTIONAL>(&OutputStreamTest::getStream, "dual mono mode",
Initial{DualMonoMode::OFF},
{DualMonoMode::LR, DualMonoMode::LL, DualMonoMode::RR},
- &IStreamOut::setDualMonoMode, &IStreamOut::getDualMonoMode);
+ &::android::hardware::audio::CPP_VERSION::IStreamOut::setDualMonoMode,
+ &::android::hardware::audio::CPP_VERSION::IStreamOut::getDualMonoMode);
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DualMonoModeAccessorHidlTest);
@@ -73,7 +74,8 @@
testAccessors<OPTIONAL>(
&OutputStreamTest::getStream, "audio description mix level",
Initial{-std::numeric_limits<float>::infinity()}, {-48.0f, -1.0f, 0.0f, 1.0f, 48.0f},
- &IStreamOut::setAudioDescriptionMixLevel, &IStreamOut::getAudioDescriptionMixLevel,
+ &::android::hardware::audio::CPP_VERSION::IStreamOut::setAudioDescriptionMixLevel,
+ &::android::hardware::audio::CPP_VERSION::IStreamOut::getAudioDescriptionMixLevel,
{48.5f, 1000.0f, std::numeric_limits<float>::infinity()});
}
@@ -105,7 +107,8 @@
PlaybackRate{0.5f, 0.5f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE},
PlaybackRate{1000.0f, 1000.0f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE},
PlaybackRate{1.0f, 1.0f, TimestretchMode::VOICE, TimestretchFallbackMode::FAIL}},
- &IStreamOut::setPlaybackRateParameters, &IStreamOut::getPlaybackRateParameters,
+ &::android::hardware::audio::CPP_VERSION::IStreamOut::setPlaybackRateParameters,
+ &::android::hardware::audio::CPP_VERSION::IStreamOut::getPlaybackRateParameters,
{PlaybackRate{1000.0f, 1000.0f, TimestretchMode::DEFAULT,
TimestretchFallbackMode::FAIL},
PlaybackRate{1000.0f, 1000.0f, TimestretchMode::VOICE,
diff --git a/audio/core/all-versions/vts/functional/6.0/Generators.cpp b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
index e3b98c9..dafd326 100644
--- a/audio/core/all-versions/vts/functional/6.0/Generators.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
@@ -21,8 +21,8 @@
#include "PolicyConfig.h"
// clang-format off
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
// clang-format on
// Forward declaration for functions that are substituted
@@ -30,7 +30,7 @@
const PolicyConfig& getCachedPolicyConfig();
const std::vector<DeviceParameter>& getDeviceParameters();
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CPP_VERSION;
std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice) {
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index 222fad7..f25c391 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -381,13 +381,13 @@
"IDevice::open{Input|Output}Stream method.");
AudioConfig suggestedConfig{};
if (isParamForInputStream()) {
- sp<IStreamIn> stream;
+ sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn> stream;
ASSERT_OK(getDevice()->openInputStream(AudioIoHandle{}, getDeviceAddress(), getConfig(),
getFlags(), getSinkMetadata(),
returnIn(res, stream, suggestedConfig)));
ASSERT_TRUE(stream == nullptr);
} else {
- sp<IStreamOut> stream;
+ sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamOut> stream;
ASSERT_OK(getDevice()->openOutputStream(AudioIoHandle{}, getDeviceAddress(), getConfig(),
getFlags(), getSourceMetadata(),
returnIn(res, stream, suggestedConfig)));
@@ -551,13 +551,15 @@
}
void releasePatchIfNeeded() {
- if (areAudioPatchesSupported()) {
- if (mHasPatch) {
+ if (getDevice()) {
+ if (areAudioPatchesSupported() && mHasPatch) {
EXPECT_OK(getDevice()->releaseAudioPatch(mPatchHandle));
mHasPatch = false;
}
} else {
- EXPECT_OK(stream->setDevices({address}));
+ if (stream) {
+ EXPECT_OK(stream->setDevices({address}));
+ }
}
}
@@ -724,13 +726,15 @@
}
void releasePatchIfNeeded() {
- if (areAudioPatchesSupported()) {
- if (mHasPatch) {
+ if (getDevice()) {
+ if (areAudioPatchesSupported() && mHasPatch) {
EXPECT_OK(getDevice()->releaseAudioPatch(mPatchHandle));
mHasPatch = false;
}
} else {
- EXPECT_OK(stream->setDevices({address}));
+ if (stream) {
+ EXPECT_OK(stream->setDevices({address}));
+ }
}
}
diff --git a/audio/core/all-versions/vts/functional/7.0/Generators.cpp b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
index 42bf1d3..f936d0a 100644
--- a/audio/core/all-versions/vts/functional/7.0/Generators.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
@@ -20,20 +20,20 @@
#include "7.0/PolicyConfig.h"
// clang-format off
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
// clang-format on
-#include <android_audio_policy_configuration_V7_0-enums.h>
-#include <android_audio_policy_configuration_V7_0.h>
+#include PATH(APM_XSD_ENUMS_H_FILENAME)
+#include PATH(APM_XSD_H_FILENAME)
// Forward declaration for functions that are substituted
// in generator unit tests.
const PolicyConfig& getCachedPolicyConfig();
const std::vector<DeviceParameter>& getDeviceParameters();
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using namespace ::android::hardware::audio::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
namespace xsd {
using namespace ::android::audio::policy::configuration::CPP_VERSION;
}
diff --git a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.cpp b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.cpp
index 2988207..d674403 100644
--- a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.cpp
@@ -30,9 +30,9 @@
using ::android::NO_ERROR;
using ::android::OK;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using namespace ::android::hardware::audio::CPP_VERSION;
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
using ::android::hardware::audio::common::utils::splitString;
namespace xsd {
using namespace ::android::audio::policy::configuration::CPP_VERSION;
diff --git a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
index f798839..4aea503 100644
--- a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
+++ b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
@@ -25,15 +25,15 @@
#include <utils/Errors.h>
// clang-format off
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
// clang-format on
-#include <android_audio_policy_configuration_V7_0-enums.h>
-#include <android_audio_policy_configuration_V7_0.h>
+#include PATH(APM_XSD_ENUMS_H_FILENAME)
+#include PATH(APM_XSD_H_FILENAME)
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using namespace ::android::hardware::audio::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
namespace xsd {
using namespace ::android::audio::policy::configuration::CPP_VERSION;
using Module = Modules::Module;
diff --git a/audio/core/all-versions/vts/functional/7.1/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.1/AudioPrimaryHidlHalTest.cpp
new file mode 100644
index 0000000..b750f56
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/7.1/AudioPrimaryHidlHalTest.cpp
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// pull in all the <= 7.0 tests
+#include "7.0/AudioPrimaryHidlHalTest.cpp"
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index cfee26a..d810c55 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -179,6 +179,39 @@
test_config: "VtsHalAudioV7_0TargetTest.xml",
}
+cc_test {
+ name: "VtsHalAudioV7_1TargetTest",
+ defaults: ["VtsHalAudioTargetTest_defaults"],
+ srcs: [
+ "7.1/AudioPrimaryHidlHalTest.cpp",
+ "7.0/Generators.cpp",
+ "7.0/PolicyConfig.cpp",
+ ],
+ generated_headers: ["audio_policy_configuration_V7_1_parser"],
+ generated_sources: ["audio_policy_configuration_V7_1_parser"],
+ static_libs: [
+ "android.hardware.audio@7.0",
+ "android.hardware.audio@7.1",
+ "android.hardware.audio.common@7.0",
+ "android.hardware.audio.common@7.0-enums",
+ "android.hardware.audio.common@7.1-enums",
+ "android.hardware.audio.common@7.0-util",
+ ],
+ cflags: [
+ "-DMAJOR_VERSION=7",
+ "-DMINOR_VERSION=1",
+ "-DCOMMON_TYPES_MINOR_VERSION=0",
+ "-DCORE_TYPES_MINOR_VERSION=0",
+ "-include common/all-versions/VersionMacro.h",
+ ],
+ data: [
+ ":audio_policy_configuration_V7_1",
+ ],
+ // Use test_config for vts suite.
+ // TODO(b/146104851): Add auto-gen rules and remove it.
+ test_config: "VtsHalAudioV7_1TargetTest.xml",
+}
+
// Note: the following aren't VTS tests, but rather unit tests
// to verify correctness of test utilities.
cc_test {
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 340903a..404532a 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -37,15 +37,17 @@
#include <android-base/logging.h>
#include <system/audio_config.h>
+// clang-format off
#include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
#include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h)
#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
#if MAJOR_VERSION >= 7
-#include <android_audio_policy_configuration_V7_0-enums.h>
-#include <android_audio_policy_configuration_V7_0.h>
+#include PATH(APM_XSD_ENUMS_H_FILENAME)
+#include PATH(APM_XSD_H_FILENAME)
#endif
+// clang-format on
#include <fmq/EventFlag.h>
#include <fmq/MessageQueue.h>
@@ -86,7 +88,7 @@
using ::android::hardware::audio::common::utils::mkEnumBitfield;
using ::android::hardware::details::toHexString;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::common::test::utility;
using namespace ::android::hardware::audio::CPP_VERSION;
using ReadParameters = ::android::hardware::audio::CPP_VERSION::IStreamIn::ReadParameters;
@@ -124,6 +126,9 @@
class HidlTest : public ::testing::Test {
public:
+ using IDevice = ::android::hardware::audio::CPP_VERSION::IDevice;
+ using IDevicesFactory = ::android::hardware::audio::CPP_VERSION::IDevicesFactory;
+
virtual ~HidlTest() = default;
// public access to avoid annoyances when using this method in template classes
// derived from test classes
@@ -168,7 +173,8 @@
}
TEST(CheckConfig, audioPolicyConfigurationValidation) {
- const auto factories = ::android::hardware::getAllHalInstanceNames(IDevicesFactory::descriptor);
+ const auto factories = ::android::hardware::getAllHalInstanceNames(
+ ::android::hardware::audio::CPP_VERSION::IDevicesFactory::descriptor);
if (factories.size() == 0) {
GTEST_SKIP() << "Skipping audioPolicyConfigurationValidation because no factory instances "
"are found.";
@@ -198,8 +204,8 @@
const std::vector<DeviceParameter>& getDeviceParameters() {
static std::vector<DeviceParameter> parameters = [] {
std::vector<DeviceParameter> result;
- const auto factories =
- ::android::hardware::getAllHalInstanceNames(IDevicesFactory::descriptor);
+ const auto factories = ::android::hardware::getAllHalInstanceNames(
+ ::android::hardware::audio::CPP_VERSION::IDevicesFactory::descriptor);
const auto devices = getCachedPolicyConfig().getModulesWithDevicesNames();
result.reserve(devices.size());
for (const auto& factoryName : factories) {
@@ -217,8 +223,8 @@
const std::vector<DeviceParameter>& getDeviceParametersForFactoryTests() {
static std::vector<DeviceParameter> parameters = [] {
std::vector<DeviceParameter> result;
- const auto factories =
- ::android::hardware::getAllHalInstanceNames(IDevicesFactory::descriptor);
+ const auto factories = ::android::hardware::getAllHalInstanceNames(
+ ::android::hardware::audio::CPP_VERSION::IDevicesFactory::descriptor);
for (const auto& factoryName : factories) {
result.emplace_back(factoryName,
DeviceManager::getInstance().getPrimary(factoryName) != nullptr
@@ -288,6 +294,8 @@
// Test audio devices factory
class AudioHidlTest : public AudioHidlTestWithDeviceParameter {
public:
+ using IPrimaryDevice = ::android::hardware::audio::CPP_VERSION::IPrimaryDevice;
+
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(AudioHidlTestWithDeviceParameter::SetUp()); // setup base
ASSERT_TRUE(getDevicesFactory() != nullptr);
@@ -301,7 +309,7 @@
TEST_P(AudioHidlTest, OpenDeviceInvalidParameter) {
doc::test("Test passing an invalid parameter to openDevice");
Result result;
- sp<IDevice> device;
+ sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IDevice> device;
#if MAJOR_VERSION == 2
auto invalidDevice = IDevicesFactory::Device(-1);
#elif MAJOR_VERSION >= 4
@@ -572,8 +580,8 @@
[](auto&& arg) -> std::string {
using T = std::decay_t<decltype(arg)>;
// Need to use FQN of toString to avoid confusing the compiler
- return ::android::hardware::audio::common::CPP_VERSION::toString<T>(
- hidl_bitfield<T>(arg));
+ return ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::
+ toString<T>(hidl_bitfield<T>(arg));
},
std::get<PARAM_FLAGS>(info.param)));
#elif MAJOR_VERSION >= 7
@@ -890,6 +898,8 @@
class StreamWriter : public StreamWorker<StreamWriter> {
public:
+ using IStreamOut = ::android::hardware::audio::CPP_VERSION::IStreamOut;
+
StreamWriter(IStreamOut* stream, size_t bufferSize)
: mStream(stream), mBufferSize(bufferSize), mData(mBufferSize) {}
~StreamWriter() {
@@ -998,7 +1008,8 @@
EventFlag* mEfGroup = nullptr;
};
-class OutputStreamTest : public OpenStreamTest<IStreamOut> {
+class OutputStreamTest
+ : public OpenStreamTest<::android::hardware::audio::CPP_VERSION::IStreamOut> {
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
#if MAJOR_VERSION <= 6
@@ -1012,9 +1023,12 @@
[&](AudioIoHandle handle, AudioConfig config, auto cb) {
#if MAJOR_VERSION == 2
return getDevice()->openOutputStream(handle, address, config, flags, cb);
-#elif MAJOR_VERSION >= 4
+#elif MAJOR_VERSION >= 4 && (MAJOR_VERSION < 7 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0))
return getDevice()->openOutputStream(handle, address, config, flags,
initMetadata, cb);
+#elif MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ return getDevice()->openOutputStream_7_1(handle, address, config, flags,
+ initMetadata, cb);
#endif
},
config);
@@ -1075,6 +1089,8 @@
class StreamReader : public StreamWorker<StreamReader> {
public:
+ using IStreamIn = ::android::hardware::audio::CPP_VERSION::IStreamIn;
+
StreamReader(IStreamIn* stream, size_t bufferSize)
: mStream(stream), mBufferSize(bufferSize), mData(mBufferSize) {}
~StreamReader() {
@@ -1188,7 +1204,7 @@
EventFlag* mEfGroup = nullptr;
};
-class InputStreamTest : public OpenStreamTest<IStreamIn> {
+class InputStreamTest : public OpenStreamTest<::android::hardware::audio::CPP_VERSION::IStreamIn> {
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
#if MAJOR_VERSION <= 6
@@ -1210,8 +1226,13 @@
auto flags = getInputFlags();
testOpen(
[&](AudioIoHandle handle, AudioConfig config, auto cb) {
+#if MAJOR_VERSION < 7 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0)
return getDevice()->openInputStream(handle, address, config, flags,
initMetadata, cb);
+#elif MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ return getDevice()->openInputStream_7_1(handle, address, config, flags,
+ initMetadata, cb);
+#endif
},
config);
}
@@ -1584,7 +1605,8 @@
"InputStream::setGain");
}
-static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize, uint32_t framesCount) {
+static void testPrepareForReading(::android::hardware::audio::CPP_VERSION::IStreamIn* stream,
+ uint32_t frameSize, uint32_t framesCount) {
Result res;
// Ignore output parameters as the call should fail
ASSERT_OK(stream->prepareForReading(frameSize, framesCount,
@@ -1655,7 +1677,8 @@
"setVolume");
}
-static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize, uint32_t framesCount) {
+static void testPrepareForWriting(::android::hardware::audio::CPP_VERSION::IStreamOut* stream,
+ uint32_t frameSize, uint32_t framesCount) {
Result res;
// Ignore output parameters as the call should fail
ASSERT_OK(stream->prepareForWriting(frameSize, framesCount,
@@ -1682,6 +1705,8 @@
}
struct Capability {
+ using IStreamOut = ::android::hardware::audio::CPP_VERSION::IStreamOut;
+
Capability(IStreamOut* stream) {
EXPECT_OK(stream->supportsPauseAndResume(returnIn(pause, resume)));
drain = extract(stream->supportsDrain());
@@ -1725,7 +1750,7 @@
Return<void> onError() override { return {}; }
};
-static bool isAsyncModeSupported(IStreamOut* stream) {
+static bool isAsyncModeSupported(::android::hardware::audio::CPP_VERSION::IStreamOut* stream) {
auto res = stream->setCallback(new MockOutCallbacks);
stream->clearCallback(); // try to restore the no callback state, ignore
// any error
@@ -1780,7 +1805,8 @@
ASSERT_RESULT(Result::INVALID_STATE, stream->pause());
}
-static void testDrain(IStreamOut* stream, AudioDrain type) {
+static void testDrain(::android::hardware::audio::CPP_VERSION::IStreamOut* stream,
+ AudioDrain type) {
if (!Capability(stream).drain) {
doc::partialTest("The output stream does not support drain");
return;
@@ -1866,7 +1892,8 @@
}
using TtyModeAccessorPrimaryHidlTest =
- AccessorHidlTest<IPrimaryDevice::TtyMode, AudioPrimaryHidlTest>;
+ AccessorHidlTest<::android::hardware::audio::CPP_VERSION::IPrimaryDevice::TtyMode,
+ AudioPrimaryHidlTest>;
TEST_P(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
doc::test("Query and set the TTY mode state");
testAccessors<OPTIONAL>(
diff --git a/audio/core/all-versions/vts/functional/AudioTestDefinitions.h b/audio/core/all-versions/vts/functional/AudioTestDefinitions.h
index aa67630..802b87b 100644
--- a/audio/core/all-versions/vts/functional/AudioTestDefinitions.h
+++ b/audio/core/all-versions/vts/functional/AudioTestDefinitions.h
@@ -22,8 +22,8 @@
#include <vector>
// clang-format off
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
// clang-format on
enum { PARAM_FACTORY_NAME, PARAM_DEVICE_NAME };
@@ -34,14 +34,14 @@
#if MAJOR_VERSION <= 6
enum { PARAM_DEVICE, PARAM_CONFIG, PARAM_FLAGS };
enum { INDEX_INPUT, INDEX_OUTPUT };
-using DeviceConfigParameter =
- std::tuple<DeviceParameter, android::hardware::audio::common::CPP_VERSION::AudioConfig,
- std::variant<android::hardware::audio::common::CPP_VERSION::AudioInputFlag,
- android::hardware::audio::common::CPP_VERSION::AudioOutputFlag>>;
+using DeviceConfigParameter = std::tuple<
+ DeviceParameter, android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioConfig,
+ std::variant<android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioInputFlag,
+ android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioOutputFlag>>;
#elif MAJOR_VERSION >= 7
enum { PARAM_DEVICE, PARAM_PORT_NAME, PARAM_CONFIG, PARAM_FLAGS };
using DeviceConfigParameter =
std::tuple<DeviceParameter, std::string,
- android::hardware::audio::common::CPP_VERSION::AudioConfig,
- std::vector<android::hardware::audio::CPP_VERSION::AudioInOutFlag>>;
+ android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioConfig,
+ std::vector<android::hardware::audio::CORE_TYPES_CPP_VERSION::AudioInOutFlag>>;
#endif
diff --git a/audio/core/all-versions/vts/functional/ConfigHelper.h b/audio/core/all-versions/vts/functional/ConfigHelper.h
index a2bb1ee..e4008cf 100644
--- a/audio/core/all-versions/vts/functional/ConfigHelper.h
+++ b/audio/core/all-versions/vts/functional/ConfigHelper.h
@@ -21,8 +21,8 @@
#include "PolicyConfig.h"
// clang-format off
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
// clang-format on
using ::android::hardware::audio::common::utils::EnumBitfield;
diff --git a/audio/core/all-versions/vts/functional/DeviceManager.h b/audio/core/all-versions/vts/functional/DeviceManager.h
index 6db78a7..c8e0167 100644
--- a/audio/core/all-versions/vts/functional/DeviceManager.h
+++ b/audio/core/all-versions/vts/functional/DeviceManager.h
@@ -22,19 +22,21 @@
#include <android-base/logging.h>
#include <hwbinder/IPCThreadState.h>
+#include <system/audio.h>
// clang-format off
#include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
#include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h)
#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
// clang-format on
#include "utility/ReturnIn.h"
using ::android::sp;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::Result;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::common::test::utility;
using namespace ::android::hardware::audio::CPP_VERSION;
@@ -104,21 +106,30 @@
static sp<IDevice> createInterfaceInstance(const FactoryAndDevice& factoryAndDevice) {
auto [factoryName, name] = factoryAndDevice;
sp<IDevicesFactory> factory = DevicesFactoryManager::getInstance().get(factoryName);
- return name == kPrimaryDevice ? openPrimaryDevice(factory) : openDevice(factory, name);
+ return openDevice(factory, name);
}
using InterfaceManager::reset;
static constexpr const char* kPrimaryDevice = "primary";
sp<IDevice> get(const std::string& factoryName, const std::string& name) {
+ if (name == kPrimaryDevice) {
+ (void)getPrimary(factoryName); // for initializing primaryDevice if needed.
+ }
return InterfaceManager::get(std::make_tuple(factoryName, name));
}
sp<IPrimaryDevice> getPrimary(const std::string& factoryName) {
- sp<IDevice> device = get(factoryName, kPrimaryDevice);
- return device != nullptr ? IPrimaryDevice::castFrom(device) : nullptr;
+ if (primaryDevice == nullptr) {
+ sp<IDevicesFactory> factory = DevicesFactoryManager::getInstance().get(factoryName);
+ primaryDevice = openPrimaryDevice(factory);
+ }
+ return primaryDevice;
}
bool reset(const std::string& factoryName, const std::string& name)
__attribute__((warn_unused_result)) {
+ if (name == kPrimaryDevice) {
+ primaryDevice.clear();
+ }
#if MAJOR_VERSION <= 5
return InterfaceManager::reset(std::make_tuple(factoryName, name), true);
#elif MAJOR_VERSION >= 6
@@ -140,35 +151,75 @@
private:
static sp<IDevice> openDevice(const sp<IDevicesFactory>& factory, const std::string& name) {
if (factory == nullptr) return nullptr;
- sp<IDevice> device;
-#if MAJOR_VERSION >= 4
Result result;
+ sp<IDevice> device;
+#if MAJOR_VERSION == 2
+ IDevicesFactory::Device dev = IDevicesFactory::IDevicesFactory::Device(-1);
+ if (name == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
+ dev = IDevicesFactory::Device::PRIMARY;
+ } else if (name == AUDIO_HARDWARE_MODULE_ID_A2DP) {
+ dev = IDevicesFactory::Device::A2DP;
+ } else if (name == AUDIO_HARDWARE_MODULE_ID_USB) {
+ dev = IDevicesFactory::Device::USB;
+ } else if (name == AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX) {
+ dev = IDevicesFactory::Device::R_SUBMIX;
+ } else if (name == AUDIO_HARDWARE_MODULE_ID_STUB) {
+ dev = IDevicesFactory::Device::STUB;
+ }
+ auto ret = factory->openDevice(dev, returnIn(result, device));
+#elif MAJOR_VERSION >= 4 && (MAJOR_VERSION < 7 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0))
auto ret = factory->openDevice(name, returnIn(result, device));
+#elif MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ auto ret = factory->openDevice_7_1(name, returnIn(result, device));
+#endif
if (!ret.isOk() || result != Result::OK || device == nullptr) {
ALOGW("Device %s can not be opened, transaction: %s, result %d, device %p",
name.c_str(), ret.description().c_str(), result, device.get());
return nullptr;
}
-#else
- (void)name;
-#endif
return device;
}
- static sp<IDevice> openPrimaryDevice(const sp<IDevicesFactory>& factory) {
- if (factory == nullptr) return nullptr;
+ static sp<IPrimaryDevice> openPrimaryDevice(const sp<IDevicesFactory>& factory) {
+ if (factory == nullptr) return {};
Result result;
sp<IDevice> device;
+ sp<IPrimaryDevice> primaryDevice;
#if MAJOR_VERSION == 2
auto ret = factory->openDevice(IDevicesFactory::Device::PRIMARY, returnIn(result, device));
-#elif MAJOR_VERSION >= 4
+ if (ret.isOk() && result == Result::OK && device != nullptr) {
+ primaryDevice = IPrimaryDevice::castFrom(device);
+ }
+#elif MAJOR_VERSION >= 4 && (MAJOR_VERSION < 7 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0))
auto ret = factory->openPrimaryDevice(returnIn(result, device));
+ if (ret.isOk() && result == Result::OK && device != nullptr) {
+ primaryDevice = IPrimaryDevice::castFrom(device);
+ }
+#elif MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ auto ret = factory->openPrimaryDevice_7_1(returnIn(result, primaryDevice));
+ if (ret.isOk() && result == Result::OK && primaryDevice != nullptr) {
+ auto getDeviceRet = primaryDevice->getDevice();
+ if (getDeviceRet.isOk()) {
+ device = getDeviceRet;
+ } else {
+ primaryDevice.clear();
+ ALOGW("Primary device can not downcast, transaction: %s, primary %p",
+ getDeviceRet.description().c_str(), primaryDevice.get());
+ return {};
+ }
+ }
#endif
if (!ret.isOk() || result != Result::OK || device == nullptr) {
ALOGW("Primary device can not be opened, transaction: %s, result %d, device %p",
ret.description().c_str(), result, device.get());
- return nullptr;
+ return {};
}
- return device;
+ return primaryDevice;
}
+
+ private:
+ // There can only be one primary device across all HAL modules.
+ // A reference to a complete interface is used because in V7.1 IDevice can not
+ // be upcasted to IPrimaryDevice.
+ sp<IPrimaryDevice> primaryDevice;
};
diff --git a/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml b/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml
new file mode 100644
index 0000000..7b33a8f
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs VtsHalAudioV7_1TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.StopServicesSetup"/>
+
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="setprop vts.native_server.on 1"/>
+ <option name="teardown-command" value="setprop vts.native_server.on 0"/>
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalAudioV7_1TargetTest->/data/local/tmp/VtsHalAudioV7_1TargetTest" />
+ <option name="push" value="audio_policy_configuration_V7_1.xsd->/data/local/tmp/audio_policy_configuration_V7_1.xsd" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalAudioV7_1TargetTest" />
+ <option name="native-test-timeout" value="5m" />
+ </test>
+</configuration>
diff --git a/audio/core/all-versions/vts/functional/tests/generators_tests.cpp b/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
index 3fdd8e6..76bf93e 100644
--- a/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
+++ b/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
@@ -33,7 +33,7 @@
#endif
using namespace android;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
#if MAJOR_VERSION == 7
namespace xsd {
using namespace ::android::audio::policy::configuration::CPP_VERSION;
diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp
index ccfc6b2..49f6bf2 100644
--- a/audio/effect/all-versions/default/Effect.cpp
+++ b/audio/effect/all-versions/default/Effect.cpp
@@ -42,9 +42,10 @@
namespace implementation {
#if MAJOR_VERSION <= 6
-using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioChannelBitfield;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::
+ AudioChannelBitfield;
#endif
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
namespace {
diff --git a/audio/effect/all-versions/default/Effect.h b/audio/effect/all-versions/default/Effect.h
index d5218f7..f9a6796 100644
--- a/audio/effect/all-versions/default/Effect.h
+++ b/audio/effect/all-versions/default/Effect.h
@@ -48,9 +48,10 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
#if MAJOR_VERSION <= 6
-using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioDeviceBitfield;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::
+ AudioDeviceBitfield;
#endif
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
struct Effect : public IEffect {
diff --git a/audio/effect/all-versions/default/EffectsFactory.cpp b/audio/effect/all-versions/default/EffectsFactory.cpp
index eb1cb49..e93ad89 100644
--- a/audio/effect/all-versions/default/EffectsFactory.cpp
+++ b/audio/effect/all-versions/default/EffectsFactory.cpp
@@ -53,7 +53,7 @@
namespace CPP_VERSION {
namespace implementation {
-using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::UuidUtils;
// static
sp<IEffect> EffectsFactory::dispatchEffectInstanceCreation(const effect_descriptor_t& halDescriptor,
diff --git a/audio/effect/all-versions/default/EffectsFactory.h b/audio/effect/all-versions/default/EffectsFactory.h
index 0b86836..da16923 100644
--- a/audio/effect/all-versions/default/EffectsFactory.h
+++ b/audio/effect/all-versions/default/EffectsFactory.h
@@ -41,7 +41,7 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
struct EffectsFactory : public IEffectsFactory {
diff --git a/audio/effect/all-versions/default/EnvironmentalReverbEffect.h b/audio/effect/all-versions/default/EnvironmentalReverbEffect.h
index 9694b5d..001774d 100644
--- a/audio/effect/all-versions/default/EnvironmentalReverbEffect.h
+++ b/audio/effect/all-versions/default/EnvironmentalReverbEffect.h
@@ -43,7 +43,7 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
struct EnvironmentalReverbEffect : public IEnvironmentalReverbEffect {
diff --git a/audio/effect/all-versions/default/EqualizerEffect.h b/audio/effect/all-versions/default/EqualizerEffect.h
index 7a6bc0a..c4d76c1 100644
--- a/audio/effect/all-versions/default/EqualizerEffect.h
+++ b/audio/effect/all-versions/default/EqualizerEffect.h
@@ -43,7 +43,7 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
struct EqualizerEffect : public IEqualizerEffect {
diff --git a/audio/effect/all-versions/default/LoudnessEnhancerEffect.h b/audio/effect/all-versions/default/LoudnessEnhancerEffect.h
index 6d80207..122ec36 100644
--- a/audio/effect/all-versions/default/LoudnessEnhancerEffect.h
+++ b/audio/effect/all-versions/default/LoudnessEnhancerEffect.h
@@ -39,7 +39,7 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
struct LoudnessEnhancerEffect : public ILoudnessEnhancerEffect {
diff --git a/audio/effect/all-versions/default/NoiseSuppressionEffect.h b/audio/effect/all-versions/default/NoiseSuppressionEffect.h
index 6cc45b9..96b9ecf 100644
--- a/audio/effect/all-versions/default/NoiseSuppressionEffect.h
+++ b/audio/effect/all-versions/default/NoiseSuppressionEffect.h
@@ -41,7 +41,7 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
struct NoiseSuppressionEffect : public INoiseSuppressionEffect {
diff --git a/audio/effect/all-versions/default/PresetReverbEffect.h b/audio/effect/all-versions/default/PresetReverbEffect.h
index eb55e20..9d82c08 100644
--- a/audio/effect/all-versions/default/PresetReverbEffect.h
+++ b/audio/effect/all-versions/default/PresetReverbEffect.h
@@ -39,7 +39,7 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
struct PresetReverbEffect : public IPresetReverbEffect {
diff --git a/audio/effect/all-versions/default/VirtualizerEffect.cpp b/audio/effect/all-versions/default/VirtualizerEffect.cpp
index 1dce181..6efc4ea 100644
--- a/audio/effect/all-versions/default/VirtualizerEffect.cpp
+++ b/audio/effect/all-versions/default/VirtualizerEffect.cpp
@@ -34,7 +34,7 @@
namespace CPP_VERSION {
namespace implementation {
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
VirtualizerEffect::VirtualizerEffect(effect_handle_t handle)
: mEffect(new Effect(false /*isInput*/, handle)) {}
diff --git a/audio/effect/all-versions/default/VirtualizerEffect.h b/audio/effect/all-versions/default/VirtualizerEffect.h
index 3ed06d1..f26e4fa 100644
--- a/audio/effect/all-versions/default/VirtualizerEffect.h
+++ b/audio/effect/all-versions/default/VirtualizerEffect.h
@@ -40,9 +40,10 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
#if MAJOR_VERSION <= 6
-using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioChannelBitfield;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::
+ AudioChannelBitfield;
#endif
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
struct VirtualizerEffect : public IVirtualizerEffect {
diff --git a/audio/effect/all-versions/default/VisualizerEffect.h b/audio/effect/all-versions/default/VisualizerEffect.h
index 3ae4b08..b8424c4 100644
--- a/audio/effect/all-versions/default/VisualizerEffect.h
+++ b/audio/effect/all-versions/default/VisualizerEffect.h
@@ -39,7 +39,7 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
struct VisualizerEffect : public IVisualizerEffect {
diff --git a/audio/effect/all-versions/default/util/EffectUtils.cpp b/audio/effect/all-versions/default/util/EffectUtils.cpp
index 1156d21..296f84d 100644
--- a/audio/effect/all-versions/default/util/EffectUtils.cpp
+++ b/audio/effect/all-versions/default/util/EffectUtils.cpp
@@ -25,8 +25,8 @@
#include "util/EffectUtils.h"
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
-using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::UuidUtils;
using ::android::hardware::audio::common::utils::EnumBitfield;
namespace android {
@@ -36,7 +36,7 @@
namespace CPP_VERSION {
namespace implementation {
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
#define CONVERT_CHECKED(expr, result) \
if (status_t status = (expr); status != NO_ERROR) { \
diff --git a/audio/effect/all-versions/default/util/tests/effectutils_tests.cpp b/audio/effect/all-versions/default/util/tests/effectutils_tests.cpp
index d021fa0..adfa167 100644
--- a/audio/effect/all-versions/default/util/tests/effectutils_tests.cpp
+++ b/audio/effect/all-versions/default/util/tests/effectutils_tests.cpp
@@ -27,7 +27,7 @@
#include <xsdc/XsdcSupport.h>
using namespace android;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
using ::android::hardware::audio::effect::CPP_VERSION::implementation::EffectUtils;
namespace xsd {
diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
index 23e7786..e59423f 100644
--- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
@@ -50,7 +50,7 @@
using ::android::hardware::audio::common::utils::mkEnumBitfield;
using ::android::hidl::allocator::V1_0::IAllocator;
using ::android::hidl::memory::V1_0::IMemory;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
#if MAJOR_VERSION >= 7
// Make an alias for enumerations generated from the APM config XSD.
diff --git a/bluetooth/audio/2.0/vts/OWNERS b/bluetooth/audio/2.0/vts/OWNERS
deleted file mode 100644
index b266b06..0000000
--- a/bluetooth/audio/2.0/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-include platform/packages/modules/Bluetooth:/OWNERS
-
-cheneyni@google.com
diff --git a/bluetooth/audio/2.1/vts/OWNERS b/bluetooth/audio/2.1/vts/OWNERS
deleted file mode 100644
index b266b06..0000000
--- a/bluetooth/audio/2.1/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-include platform/packages/modules/Bluetooth:/OWNERS
-
-cheneyni@google.com
diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
index f577537..7c91805 100644
--- a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
+++ b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
@@ -69,4 +69,12 @@
* encoding.
*/
updateAudioConfiguration(AudioConfiguration audioConfig);
+
+ /**
+ * Called when the supported latency mode is updated.
+ *
+ * @param allowed If the peripheral devices can't keep up with low latency
+ * mode, the API will be called with supported is false.
+ */
+ setLowLatencyModeAllowed(bool allowed);
};
diff --git a/bluetooth/audio/2.2/OWNERS b/bluetooth/audio/2.2/OWNERS
new file mode 100644
index 0000000..84f5b1e
--- /dev/null
+++ b/bluetooth/audio/2.2/OWNERS
@@ -0,0 +1,3 @@
+aliceypkuo@google.com
+ugoyu@google.com
+sattiraju@google.com
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
index 202cfb9..62511e9 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
@@ -209,6 +209,18 @@
return Void();
}
+Return<void> BluetoothAudioProvider::setLowLatencyModeAllowed(bool allowed) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
+
+ if (stack_iface_ == nullptr) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " has NO session";
+ return Void();
+ }
+ LOG(INFO) << __func__ << " allowed: " << allowed;
+ return Void();
+}
+
} // namespace implementation
} // namespace V2_2
} // namespace audio
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
index 425ea3b..90c158e 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
@@ -56,6 +56,8 @@
Return<void> updateAudioConfiguration(
const AudioConfiguration& audioConfig) override;
+ Return<void> setLowLatencyModeAllowed(bool allowed) override;
+
protected:
sp<BluetoothAudioDeathRecipient> death_recipient_;
diff --git a/bluetooth/audio/aidl/default/OWNERS b/bluetooth/audio/OWNERS
similarity index 98%
rename from bluetooth/audio/aidl/default/OWNERS
rename to bluetooth/audio/OWNERS
index 17ea464..a8e9bda 100644
--- a/bluetooth/audio/aidl/default/OWNERS
+++ b/bluetooth/audio/OWNERS
@@ -1,4 +1,4 @@
include platform/packages/modules/Bluetooth:/OWNERS
cheneyni@google.com
-aliceypkuo@google.com
\ No newline at end of file
+aliceypkuo@google.com
diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp
index 5107240..52671b8 100644
--- a/bluetooth/audio/aidl/Android.bp
+++ b/bluetooth/audio/aidl/Android.bp
@@ -47,6 +47,7 @@
"//apex_available:platform",
"com.android.bluetooth",
],
+ min_sdk_version: "31",
},
},
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
index 9a1557a..cc3c641 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -40,4 +40,6 @@
void suspendStream();
void updateSourceMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
void updateSinkMetadata(in android.hardware.audio.common.SinkMetadata sinkMetadata);
+ void setLatencyMode(in android.hardware.bluetooth.audio.LatencyMode latencyMode);
+ void setCodecType(in android.hardware.bluetooth.audio.CodecType codecType);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NeighboringCell.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
similarity index 88%
rename from radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NeighboringCell.aidl
rename to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
index 4f29c0b..5583679 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NeighboringCell.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,9 +31,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.radio.network;
-@VintfStability
-parcelable NeighboringCell {
- String cid;
- int rssi;
+package android.hardware.bluetooth.audio;
+@Backing(type="int") @VintfStability
+enum LatencyMode {
+ UNKNOWN = 0,
+ LOW_LATENCY = 1,
+ FREE = 2,
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
index 827f57d..81c2ce2 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -18,6 +18,8 @@
import android.hardware.audio.common.SinkMetadata;
import android.hardware.audio.common.SourceMetadata;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.LatencyMode;
import android.hardware.bluetooth.audio.PresentationPosition;
/**
@@ -78,4 +80,18 @@
* @param sinkMetadata as passed from Audio Framework
*/
void updateSinkMetadata(in SinkMetadata sinkMetadata);
+
+ /**
+ * Called when latency mode is changed.
+ *
+ * @param latencyMode latency mode from audio
+ */
+ void setLatencyMode(in LatencyMode latencyMode);
+
+ /**
+ * Called when codec type is changed.
+ *
+ * @param codecType codec type from audio
+ */
+ void setCodecType(in CodecType codecType);
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl
new file mode 100644
index 0000000..0c354f7
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+@VintfStability
+@Backing(type="int")
+enum LatencyMode {
+ UNKNOWN,
+ LOW_LATENCY,
+ FREE,
+}
diff --git a/bluetooth/audio/aidl/vts/OWNERS b/bluetooth/audio/aidl/vts/OWNERS
deleted file mode 100644
index 17ea464..0000000
--- a/bluetooth/audio/aidl/vts/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-include platform/packages/modules/Bluetooth:/OWNERS
-
-cheneyni@google.com
-aliceypkuo@google.com
\ No newline at end of file
diff --git a/bluetooth/audio/utils/OWNERS b/bluetooth/audio/utils/OWNERS
deleted file mode 100644
index 17ea464..0000000
--- a/bluetooth/audio/utils/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-include platform/packages/modules/Bluetooth:/OWNERS
-
-cheneyni@google.com
-aliceypkuo@google.com
\ No newline at end of file
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index f626db8..96cd9ef 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -508,6 +508,36 @@
}
}
+void BluetoothAudioSession::SetLatencyMode(LatencyMode latency_mode) {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ if (!IsSessionReady()) {
+ LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
+ << " has NO session";
+ return;
+ }
+
+ auto hal_retval = stack_iface_->setLatencyMode(latency_mode);
+ if (!hal_retval.isOk()) {
+ LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+ << toString(session_type_) << " failed";
+ }
+}
+
+void BluetoothAudioSession::SetCodecType(CodecType codec_type) {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ if (!IsSessionReady()) {
+ LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
+ << " has NO session";
+ return;
+ }
+
+ auto hal_retval = stack_iface_->setCodecType(codec_type);
+ if (!hal_retval.isOk()) {
+ LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+ << toString(session_type_) << " failed";
+ }
+}
+
bool BluetoothAudioSession::IsAidlAvailable() {
if (is_aidl_checked) return is_aidl_available;
is_aidl_available =
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
index 73bc0f8..5adc0e2 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
@@ -20,6 +20,7 @@
#include <aidl/android/hardware/audio/common/SourceMetadata.h>
#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.h>
#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.h>
+#include <aidl/android/hardware/bluetooth/audio/LatencyMode.h>
#include <aidl/android/hardware/bluetooth/audio/SessionType.h>
#include <fmq/AidlMessageQueue.h>
#include <hardware/audio.h>
@@ -164,6 +165,8 @@
bool GetPresentationPosition(PresentationPosition& presentation_position);
void UpdateSourceMetadata(const struct source_metadata& source_metadata);
void UpdateSinkMetadata(const struct sink_metadata& sink_metadata);
+ void SetLatencyMode(LatencyMode latency_mode);
+ void SetCodecType(CodecType codec_type);
// The control function writes stream to FMQ
size_t OutWritePcmData(const void* buffer, size_t bytes);
diff --git a/common/aidl/Android.bp b/common/aidl/Android.bp
index 028c923..549d970 100644
--- a/common/aidl/Android.bp
+++ b/common/aidl/Android.bp
@@ -30,6 +30,7 @@
ndk: {
apex_available: [
"//apex_available:platform",
+ "com.android.bluetooth",
"com.android.media.swcodec",
"com.android.neuralnetworks",
],
diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp
index 842a75f..6fd4200 100644
--- a/common/fmq/aidl/Android.bp
+++ b/common/fmq/aidl/Android.bp
@@ -29,6 +29,13 @@
cpp: {
enabled: false,
},
+ ndk: {
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.bluetooth",
+ ],
+ min_sdk_version: "29",
+ },
},
versions: ["1"],
}
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index f751efc..b65b159 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -10,7 +10,7 @@
<hal format="hidl" optional="false">
<name>android.hardware.audio</name>
<version>6.0</version>
- <version>7.0</version>
+ <version>7.0-1</version>
<interface>
<name>IDevicesFactory</name>
<instance>default</instance>
diff --git a/graphics/OWNERS b/graphics/OWNERS
new file mode 100644
index 0000000..75ceb23
--- /dev/null
+++ b/graphics/OWNERS
@@ -0,0 +1,9 @@
+# Bug component: 1075130
+
+# Graphics team
+adyabr@google.com
+alecmouri@google.com
+chrisforbes@google.com
+jreck@google.com
+lpy@google.com
+sumir@google.com
\ No newline at end of file
diff --git a/health/aidl/README.md b/health/aidl/README.md
index a64fe93..54d6758 100644
--- a/health/aidl/README.md
+++ b/health/aidl/README.md
@@ -60,7 +60,11 @@
[android.hardware.health-service.example.rc](default/android.hardware.health-service.example.rc).
Specifically:
-* You may ignore the `service` line. The name of the service does not matter.
+* For the `service` line, if the name of the service is **NOT**
+ `vendor.charger`, and there are actions
+ in the rc file triggered by `on property:init.svc.<name>=running` where
+ `<name>` is the name of your charger service, then you need a custom health
+ AIDL service.
* If your service belongs to additional classes beside `charger`, you need a
custom health AIDL service.
* Modify the `seclabel` line. Replace `charger` with `charger_vendor`.
@@ -232,13 +236,19 @@
It is recommended that you move the existing `service` entry with
`class charger` to the `init.rc` file in your custom health service.
+If there are existing actions in the rc file triggered by
+`on property:init.svc.<name>=running`, where `<name>` is the name of your
+existing charger service (usually `vendor.charger`), then the name of the
+service must be kept as-is. If you modify the name of the service, the actions
+are not triggered properly.
+
Modify the entry to invoke the health service binary with `--charger` argument.
See
[android.hardware.health-service.example.rc](default/android.hardware.health-service.example.rc)
for an example:
```text
-service vendor.charger-tuna /vendor/bin/hw/android.hardware.health-service-tuna --charger
+service vendor.charger /vendor/bin/hw/android.hardware.health-service-tuna --charger
class charger
seclabel u:r:charger_vendor:s0
# ...
diff --git a/health/aidl/default/android.hardware.health-service.example.rc b/health/aidl/default/android.hardware.health-service.example.rc
index 4258890..e052024 100644
--- a/health/aidl/default/android.hardware.health-service.example.rc
+++ b/health/aidl/default/android.hardware.health-service.example.rc
@@ -5,7 +5,7 @@
capabilities WAKE_ALARM BLOCK_SUSPEND
file /dev/kmsg w
-service vendor.charger-default /vendor/bin/hw/android.hardware.health-service.example --charger
+service vendor.charger /vendor/bin/hw/android.hardware.health-service.example --charger
class charger
seclabel u:r:charger_vendor:s0
user system
diff --git a/identity/aidl/Android.bp b/identity/aidl/Android.bp
index dad3b8d..e3b8191 100644
--- a/identity/aidl/Android.bp
+++ b/identity/aidl/Android.bp
@@ -15,6 +15,7 @@
],
imports: [
"android.hardware.keymaster",
+ "android.hardware.security.keymint",
],
stability: "vintf",
backend: {
@@ -25,6 +26,7 @@
vndk: {
enabled: true,
},
+ apps_enabled: false,
},
},
versions: [
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
index cd8d56b..9b96ea8 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
@@ -39,4 +39,5 @@
int dataChunkSize;
boolean isDirectAccess;
@utf8InCpp String[] supportedDocTypes;
+ boolean isRemoteKeyProvisioningSupported = false;
}
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
index c912c52..31ca8b1 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
@@ -38,6 +38,7 @@
android.hardware.identity.IWritableIdentityCredential createCredential(in @utf8InCpp String docType, in boolean testCredential);
android.hardware.identity.IIdentityCredential getCredential(in android.hardware.identity.CipherSuite cipherSuite, in byte[] credentialData);
android.hardware.identity.IPresentationSession createPresentationSession(in android.hardware.identity.CipherSuite cipherSuite);
+ android.hardware.security.keymint.IRemotelyProvisionedComponent getRemotelyProvisionedComponent();
const int STATUS_OK = 0;
const int STATUS_FAILED = 1;
const int STATUS_CIPHER_SUITE_NOT_SUPPORTED = 2;
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
index 9a0fa9e..5377349 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
@@ -41,4 +41,5 @@
byte[] addEntryValue(in byte[] content);
@SuppressWarnings(value={"out-array"}) void finishAddingEntries(out byte[] credentialData, out byte[] proofOfProvisioningSignature);
void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize);
+ void setRemotelyProvisionedAttestationKey(in byte[] attestationKeyBlob, in byte[] attestationCertificate);
}
diff --git a/identity/aidl/android/hardware/identity/HardwareInformation.aidl b/identity/aidl/android/hardware/identity/HardwareInformation.aidl
index d67739d..acd13b6 100644
--- a/identity/aidl/android/hardware/identity/HardwareInformation.aidl
+++ b/identity/aidl/android/hardware/identity/HardwareInformation.aidl
@@ -51,4 +51,19 @@
*
*/
@utf8InCpp String[] supportedDocTypes;
+
+ /**
+ * isRemoteKeyProvisioningSupported indicates whether or not the underlying implementation
+ * supports a remotely provisioned key for attestation or not. If this field is false, then
+ * the implementation only uses a factory-installed, fixed attestation key. If this field is
+ * true, then an IRemotelyProvisionedComponent is associated with the IIdentityCredentialStore,
+ * and a remotely provisioned key blob may be provided for credential key attestation.
+ *
+ * Note that remote provisioning is not required, even when it is supported. Implementations
+ * MUST use a factory-installed attestation key as a fallback for when there are no
+ * remotely provisioned keys available. This behavior mirrors keystore key attestation.
+ *
+ * This field was added in API version 4.
+ */
+ boolean isRemoteKeyProvisioningSupported = false;
}
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
index 84d6ed0..82b0a83 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
@@ -438,8 +438,9 @@
* If the method is called on an instance obtained via IPresentationSession.getCredential(),
* STATUS_FAILED must be returned.
*
- * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes
- * and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes.
+ * @param challenge a challenge set by the issuer to ensure freshness. Implementations must
+ * support challenges that are at least 32 bytes. Fails with STATUS_INVALID_DATA if bigger
+ * than 32 bytes.
* @return a COSE_Sign1 signature described above.
*/
byte[] deleteCredentialWithChallenge(in byte[] challenge);
@@ -463,8 +464,9 @@
* If the method is called on an instance obtained via IPresentationSession.getCredential(),
* STATUS_FAILED must be returned.
*
- * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes
- * and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes.
+ * @param challenge a challenge set by the issuer to ensure freshness. Implementations must
+ * support challenges that are at least 32 bytes. Fails with STATUS_INVALID_DATA if bigger
+ * than 32 bytes.
* @return a COSE_Sign1 signature described above.
*/
byte[] proveOwnership(in byte[] challenge);
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
index 86be7f5..d3e4da0 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
@@ -21,6 +21,7 @@
import android.hardware.identity.IIdentityCredential;
import android.hardware.identity.IPresentationSession;
import android.hardware.identity.IWritableIdentityCredential;
+import android.hardware.security.keymint.IRemotelyProvisionedComponent;
/**
* IIdentityCredentialStore provides an interface to a secure store for user identity documents.
@@ -215,16 +216,16 @@
* @return an IWritableIdentityCredential interface that provides operations to
* provision a credential.
*/
- IWritableIdentityCredential createCredential(in @utf8InCpp String docType,
- in boolean testCredential);
+ IWritableIdentityCredential createCredential(
+ in @utf8InCpp String docType, in boolean testCredential);
/**
* getCredential retrieves an IIdentityCredential interface which allows use of a stored
* Credential.
*
- * The cipher suite used to communicate with the remote verifier must also be specified. Currently
- * only a single cipher-suite is supported. Support for other cipher suites may be added in a
- * future version of this HAL.
+ * The cipher suite used to communicate with the remote verifier must also be specified.
+ * Currently only a single cipher-suite is supported. Support for other cipher suites may be
+ * added in a future version of this HAL.
*
* This method fails with STATUS_INVALID_DATA if the passed in credentialData cannot be
* decoded or decrypted.
@@ -263,4 +264,23 @@
* @return an IPresentationSession interface.
*/
IPresentationSession createPresentationSession(in CipherSuite cipherSuite);
+
+ /**
+ * Fetch the IRemotelyProvisionedComponent that is used to generate attestation keys for
+ * remote provisionining. Keys generated by this component are to be certified by a remote
+ * provisionined authority, then used to attest to credential keys via
+ * IWritableIdentityCredential.setRemotelyProvisionedAttestationKey.
+ *
+ * Support for this method is indicated by HardwareInformation. If the
+ * |isRemoteKeyProvisioningSupported| field is false, this method will fail with
+ * EX_UNSUPPORTED_OPERATION.
+ *
+ * This method was added in API version 4.
+ *
+ * @see
+ * android.hardware.identity.IWritableIdentityCredential#setRemotelyProvisionedAttestationKey
+ *
+ * @return an IRemotelyProvisionedComponent that is used to generate attestation keys.
+ */
+ IRemotelyProvisionedComponent getRemotelyProvisionedComponent();
}
diff --git a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
index 22bcf61..1c80cbb 100644
--- a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
@@ -127,11 +127,13 @@
* https://developer.android.com/training/articles/security-key-attestation#certificate_schema_attestationid
*
* @param attestationChallenge a challenge set by the issuer to ensure freshness. If
- * this is empty, the call fails with STATUS_INVALID_DATA.
+ * this is empty, the call fails with STATUS_INVALID_DATA. Implementations must
+ * support challenges of at least 32 bytes.
*
* @return the X.509 certificate chain for the credentialKey
*/
- Certificate[] getAttestationCertificate(in byte[] attestationApplicationId, in byte[] attestationChallenge);
+ Certificate[] getAttestationCertificate(
+ in byte[] attestationApplicationId, in byte[] attestationChallenge);
/**
* Start the personalization process.
@@ -183,11 +185,11 @@
* in the secure environment. If this requirement is not met the call fails with
* STATUS_INVALID_DATA.
*
- * @return a structure with the passed-in data and MAC created with storageKey for authenticating
- * the data at a later point in time.
+ * @return a structure with the passed-in data and MAC created with storageKey for
+ * authenticating the data at a later point in time.
*/
SecureAccessControlProfile addAccessControlProfile(in int id, in Certificate readerCertificate,
- in boolean userAuthenticationRequired, in long timeoutMillis, in long secureUserId);
+ in boolean userAuthenticationRequired, in long timeoutMillis, in long secureUserId);
/**
* Begins the process of adding an entry to the credential. All access control profiles must be
@@ -209,7 +211,7 @@
* is not met this method fails with STATUS_INVALID_DATA.
*/
void beginAddEntry(in int[] accessControlProfileIds, in @utf8InCpp String nameSpace,
- in @utf8InCpp String name, in int entrySize);
+ in @utf8InCpp String name, in int entrySize);
/**
* Continues the process of adding an entry, providing a value or part of a value.
@@ -221,8 +223,8 @@
* chunk sizes must equal the value of the beginAddEntry() entrySize argument. If this
* requirement is not met the call fails with STATUS_INVALID_DATA.
*
- * @param content is the entry value, encoded as CBOR. In the case the content exceeds gcmChunkSize,
- * this may be partial content up to gcmChunkSize bytes long.
+ * @param content is the entry value, encoded as CBOR. In the case the content exceeds
+ * gcmChunkSize, this may be partial content up to gcmChunkSize bytes long.
*
* @return the encrypted and MACed content. For directly-available credentials the contents are
* implementation-defined. For other credentials, the result contains
@@ -321,8 +323,7 @@
* }
*/
@SuppressWarnings(value={"out-array"})
- void finishAddingEntries(out byte[] credentialData,
- out byte[] proofOfProvisioningSignature);
+ void finishAddingEntries(out byte[] credentialData, out byte[] proofOfProvisioningSignature);
/**
* Sets the expected size of the ProofOfProvisioning returned by finishAddingEntries(). This
@@ -336,4 +337,35 @@
*/
void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize);
+ /**
+ * Sets the attestation key used to sign the credentialKey certificate. This method is used to
+ * support remotely provisioned attestation keys, removing the credential's dependency on any
+ * factory-provisioned attestation key.
+ *
+ * This method must be called before getAttestationCertificate. After this method is called,
+ * the certificate chain returned by getAttestationCertificate will contain a leaf certificate
+ * signed by attestationKeyBlob and the chain in attestationCertificate will make up the rest
+ * of the returned chain.
+ *
+ * Returns EX_UNSUPPORTED_FUNCTION if remote provisioning is not supported
+ * (see IIdentityCredentialStore.getHardwareInformation()).
+ *
+ * This method was added in API version 4.
+ *
+ * @param attestationKeyBlob is a key blob generated by the IRemotelyProvisionedComponent that
+ * is returned by ICredentialStore.getRemotelyProvisionedComponent. The format is vendor-
+ * specified, and matches the key blob returned by IKeyMintDevice.generateKey.
+ *
+ * @param attestationCertificate contains the X.509 certificate chain that certifies the
+ * attestationKeyBlob. This certificate is expected to have been remotely provisioned
+ * by a trusted authority. This parameter must contain a concatenated chain of DER-encoded
+ * X.509 certificates. The certificates must be ordered such that the attestation key
+ * certificate is first (starting at byte 0). The issuer certificate for the attestation
+ * certificate immediately follows, continuing this chain to the final, root certificate.
+ *
+ * @see getAttestationCertificate
+ * @see android.hardware.identity.ICredentialStore#getRemotelyProvisionedComponent
+ */
+ void setRemotelyProvisionedAttestationKey(
+ in byte[] attestationKeyBlob, in byte[] attestationCertificate);
}
diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp
index ca24afa..32b3543 100644
--- a/identity/aidl/default/Android.bp
+++ b/identity/aidl/default/Android.bp
@@ -42,6 +42,7 @@
"android.hardware.identity-support-lib",
"android.hardware.identity-V4-ndk",
"android.hardware.keymaster-V4-ndk",
+ "android.hardware.security.keymint-V2-ndk",
],
}
@@ -81,6 +82,9 @@
init_rc: ["identity-default.rc"],
vintf_fragments: ["identity-default.xml"],
vendor: true,
+ defaults: [
+ "keymint_use_latest_hal_aidl_ndk_static",
+ ],
cflags: [
"-Wall",
"-Wextra",
diff --git a/identity/aidl/default/EicOpsImpl.cc b/identity/aidl/default/EicOpsImpl.cc
index c98a91e..3fd9f1d 100644
--- a/identity/aidl/default/EicOpsImpl.cc
+++ b/identity/aidl/default/EicOpsImpl.cc
@@ -267,25 +267,42 @@
bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const uint8_t* challenge,
size_t challengeSize, const uint8_t* applicationId,
- size_t applicationIdSize, bool testCredential, uint8_t* cert,
- size_t* certSize) {
- vector<uint8_t> challengeVec(challengeSize);
- memcpy(challengeVec.data(), challenge, challengeSize);
-
- vector<uint8_t> applicationIdVec(applicationIdSize);
- memcpy(applicationIdVec.data(), applicationId, applicationIdSize);
-
- optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> ret =
- android::hardware::identity::support::createEcKeyPairAndAttestation(
- challengeVec, applicationIdVec, testCredential);
- if (!ret) {
- eicDebug("Error generating CredentialKey and attestation");
- return false;
+ size_t applicationIdSize, bool testCredential,
+ const uint8_t* attestationKeyBlob, size_t attestationKeyBlobSize,
+ const uint8_t* attestationKeyCert, size_t attestationKeyCertSize,
+ uint8_t* cert, size_t* certSize) {
+ vector<uint8_t> flatChain;
+ vector<uint8_t> keyPair;
+ vector<uint8_t> challengeVec(challenge, challenge + challengeSize);
+ vector<uint8_t> applicationIdVec(applicationId, applicationId + applicationIdSize);
+ if (attestationKeyBlob && attestationKeyBlobSize > 0 && attestationKeyCert &&
+ attestationKeyCertSize > 0) {
+ vector<uint8_t> attestationKeyBlobVec(attestationKeyBlob,
+ attestationKeyBlob + attestationKeyBlobSize);
+ vector<uint8_t> attestationKeyCertVec(attestationKeyCert,
+ attestationKeyCert + attestationKeyCertSize);
+ optional<std::pair<vector<uint8_t>, vector<uint8_t>>> keyAndCert =
+ android::hardware::identity::support::createEcKeyPairWithAttestationKey(
+ challengeVec, applicationIdVec, attestationKeyBlobVec,
+ attestationKeyCertVec, testCredential);
+ if (!keyAndCert) {
+ eicDebug("Error generating CredentialKey and attestation");
+ return false;
+ }
+ keyPair = std::move(keyAndCert->first);
+ flatChain = std::move(keyAndCert->second);
+ } else {
+ optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> ret =
+ android::hardware::identity::support::createEcKeyPairAndAttestation(
+ challengeVec, applicationIdVec, testCredential);
+ if (!ret) {
+ eicDebug("Error generating CredentialKey and attestation");
+ return false;
+ }
+ keyPair = std::move(ret->first);
+ flatChain = android::hardware::identity::support::certificateChainJoin(ret->second);
}
- // Extract certificate chain.
- vector<uint8_t> flatChain =
- android::hardware::identity::support::certificateChainJoin(ret.value().second);
if (*certSize < flatChain.size()) {
eicDebug("Buffer for certificate is only %zd bytes long, need %zd bytes", *certSize,
flatChain.size());
@@ -296,7 +313,7 @@
// Extract private key.
optional<vector<uint8_t>> privKey =
- android::hardware::identity::support::ecKeyPairGetPrivateKey(ret.value().first);
+ android::hardware::identity::support::ecKeyPairGetPrivateKey(keyPair);
if (!privKey) {
eicDebug("Error extracting private key");
return false;
@@ -520,10 +537,12 @@
#ifdef EIC_DEBUG
void eicPrint(const char* format, ...) {
+ char buf[1024];
va_list args;
va_start(args, format);
- vfprintf(stderr, format, args);
+ vsnprintf(buf, sizeof(buf), format, args);
va_end(args);
+ LOG(INFO) << buf;
}
void eicHexdump(const char* message, const uint8_t* data, size_t dataSize) {
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.cpp b/identity/aidl/default/FakeSecureHardwareProxy.cpp
index 91e634c..9b9a749 100644
--- a/identity/aidl/default/FakeSecureHardwareProxy.cpp
+++ b/identity/aidl/default/FakeSecureHardwareProxy.cpp
@@ -155,7 +155,11 @@
size_t publicKeyCertSize = sizeof publicKeyCert;
if (!eicProvisioningCreateCredentialKey(&ctx_, challenge.data(), challenge.size(),
applicationId.data(), applicationId.size(),
- publicKeyCert, &publicKeyCertSize)) {
+ /*attestationKeyBlob=*/nullptr,
+ /*attestationKeyBlobSize=*/0,
+ /*attestationKeyCert=*/nullptr,
+ /*attestationKeyCertSize=*/0, publicKeyCert,
+ &publicKeyCertSize)) {
return std::nullopt;
}
vector<uint8_t> pubKeyCert(publicKeyCertSize);
@@ -163,6 +167,23 @@
return pubKeyCert;
}
+optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::createCredentialKeyUsingRkp(
+ const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
+ const vector<uint8_t>& attestationKeyBlob, const vector<uint8_t>& attstationKeyCert) {
+ size_t publicKeyCertSize = 4096;
+ vector<uint8_t> publicKeyCert(publicKeyCertSize);
+ if (!eicProvisioningCreateCredentialKey(&ctx_, challenge.data(), challenge.size(),
+ applicationId.data(), applicationId.size(),
+ attestationKeyBlob.data(), attestationKeyBlob.size(),
+ attstationKeyCert.data(), attstationKeyCert.size(),
+ publicKeyCert.data(), &publicKeyCertSize)) {
+ LOG(ERROR) << "error creating credential key";
+ return std::nullopt;
+ }
+ publicKeyCert.resize(publicKeyCertSize);
+ return publicKeyCert;
+}
+
bool FakeSecureHardwareProvisioningProxy::startPersonalization(
int accessControlProfileCount, const vector<int>& entryCounts, const string& docType,
size_t expectedProofOfProvisioningSize) {
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.h b/identity/aidl/default/FakeSecureHardwareProxy.h
index df98c7a..2512074 100644
--- a/identity/aidl/default/FakeSecureHardwareProxy.h
+++ b/identity/aidl/default/FakeSecureHardwareProxy.h
@@ -43,6 +43,11 @@
optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge,
const vector<uint8_t>& applicationId) override;
+ optional<vector<uint8_t>> createCredentialKeyUsingRkp(
+ const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
+ const vector<uint8_t>& attestationKeyBlob,
+ const vector<uint8_t>& attestationKeyCert) override;
+
bool startPersonalization(int accessControlProfileCount, const vector<int>& entryCounts,
const string& docType,
size_t expectedProofOfProvisioningSize) override;
diff --git a/identity/aidl/default/common/IdentityCredential.cpp b/identity/aidl/default/common/IdentityCredential.cpp
index 7678ecb..ff80752 100644
--- a/identity/aidl/default/common/IdentityCredential.cpp
+++ b/identity/aidl/default/common/IdentityCredential.cpp
@@ -1012,8 +1012,8 @@
IIdentityCredentialStore::STATUS_FAILED, "Error creating provisioning proxy"));
}
shared_ptr<WritableIdentityCredential> wc =
- ndk::SharedRefBase::make<WritableIdentityCredential>(provisioningHwProxy, docType_,
- testCredential_);
+ ndk::SharedRefBase::make<WritableIdentityCredential>(
+ provisioningHwProxy, docType_, testCredential_, hardwareInformation_);
if (!wc->initializeForUpdate(encryptedCredentialKeys_)) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_FAILED,
diff --git a/identity/aidl/default/common/IdentityCredential.h b/identity/aidl/default/common/IdentityCredential.h
index 2935fb8..5929829 100644
--- a/identity/aidl/default/common/IdentityCredential.h
+++ b/identity/aidl/default/common/IdentityCredential.h
@@ -48,11 +48,13 @@
public:
IdentityCredential(sp<SecureHardwareProxyFactory> hwProxyFactory,
const vector<uint8_t>& credentialData,
- std::shared_ptr<PresentationSession> session)
+ std::shared_ptr<PresentationSession> session,
+ HardwareInformation hardwareInformation)
: hwProxyFactory_(hwProxyFactory),
credentialData_(credentialData),
session_(std::move(session)),
numStartRetrievalCalls_(0),
+ hardwareInformation_(std::move(hardwareInformation)),
expectedDeviceNameSpacesSize_(0) {}
// Parses and decrypts credentialData_, return a status code from
@@ -103,6 +105,7 @@
vector<uint8_t> credentialData_;
shared_ptr<PresentationSession> session_;
int numStartRetrievalCalls_;
+ HardwareInformation hardwareInformation_;
// Set by initialize()
string docType_;
diff --git a/identity/aidl/default/common/IdentityCredentialStore.cpp b/identity/aidl/default/common/IdentityCredentialStore.cpp
index 4703ffe..bbc2cef 100644
--- a/identity/aidl/default/common/IdentityCredentialStore.cpp
+++ b/identity/aidl/default/common/IdentityCredentialStore.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "IdentityCredentialStore"
#include <android-base/logging.h>
+#include <android/binder_manager.h>
#include "IdentityCredential.h"
#include "IdentityCredentialStore.h"
@@ -25,15 +26,24 @@
namespace aidl::android::hardware::identity {
+using ::aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent;
+
+IdentityCredentialStore::IdentityCredentialStore(sp<SecureHardwareProxyFactory> hwProxyFactory,
+ optional<string> remotelyProvisionedComponent)
+ : hwProxyFactory_(hwProxyFactory),
+ remotelyProvisionedComponentName_(remotelyProvisionedComponent) {
+ hardwareInformation_.credentialStoreName = "Identity Credential Reference Implementation";
+ hardwareInformation_.credentialStoreAuthorName = "Google";
+ hardwareInformation_.dataChunkSize = kGcmChunkSize;
+ hardwareInformation_.isDirectAccess = false;
+ hardwareInformation_.supportedDocTypes = {};
+ hardwareInformation_.isRemoteKeyProvisioningSupported =
+ remotelyProvisionedComponentName_.has_value();
+}
+
ndk::ScopedAStatus IdentityCredentialStore::getHardwareInformation(
HardwareInformation* hardwareInformation) {
- HardwareInformation hw;
- hw.credentialStoreName = "Identity Credential Reference Implementation";
- hw.credentialStoreAuthorName = "Google";
- hw.dataChunkSize = kGcmChunkSize;
- hw.isDirectAccess = false;
- hw.supportedDocTypes = {};
- *hardwareInformation = hw;
+ *hardwareInformation = hardwareInformation_;
return ndk::ScopedAStatus::ok();
}
@@ -42,7 +52,8 @@
shared_ptr<IWritableIdentityCredential>* outWritableCredential) {
sp<SecureHardwareProvisioningProxy> hwProxy = hwProxyFactory_->createProvisioningProxy();
shared_ptr<WritableIdentityCredential> wc =
- ndk::SharedRefBase::make<WritableIdentityCredential>(hwProxy, docType, testCredential);
+ ndk::SharedRefBase::make<WritableIdentityCredential>(hwProxy, docType, testCredential,
+ hardwareInformation_);
if (!wc->initialize()) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_FAILED,
@@ -63,7 +74,7 @@
}
shared_ptr<IdentityCredential> credential = ndk::SharedRefBase::make<IdentityCredential>(
- hwProxyFactory_, credentialData, nullptr /* session */);
+ hwProxyFactory_, credentialData, nullptr /* session */, hardwareInformation_);
auto ret = credential->initialize();
if (ret != IIdentityCredentialStore::STATUS_OK) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
@@ -83,8 +94,8 @@
}
sp<SecureHardwareSessionProxy> hwProxy = hwProxyFactory_->createSessionProxy();
- shared_ptr<PresentationSession> session =
- ndk::SharedRefBase::make<PresentationSession>(hwProxyFactory_, hwProxy);
+ shared_ptr<PresentationSession> session = ndk::SharedRefBase::make<PresentationSession>(
+ hwProxyFactory_, hwProxy, hardwareInformation_);
auto ret = session->initialize();
if (ret != IIdentityCredentialStore::STATUS_OK) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
@@ -94,4 +105,23 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus IdentityCredentialStore::getRemotelyProvisionedComponent(
+ shared_ptr<IRemotelyProvisionedComponent>* outRemotelyProvisionedComponent) {
+ if (!remotelyProvisionedComponentName_) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(
+ EX_UNSUPPORTED_OPERATION, "Remote key provisioning is not supported"));
+ }
+
+ ndk::SpAIBinder binder(
+ AServiceManager_waitForService(remotelyProvisionedComponentName_->c_str()));
+ if (binder.get() == nullptr) {
+ return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+ IIdentityCredentialStore::STATUS_FAILED,
+ "Unable to get remotely provisioned component"));
+ }
+
+ *outRemotelyProvisionedComponent = IRemotelyProvisionedComponent::fromBinder(binder);
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/IdentityCredentialStore.h b/identity/aidl/default/common/IdentityCredentialStore.h
index 77b894d..dd1261b 100644
--- a/identity/aidl/default/common/IdentityCredentialStore.h
+++ b/identity/aidl/default/common/IdentityCredentialStore.h
@@ -18,6 +18,7 @@
#define ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIALSTORE_H
#include <aidl/android/hardware/identity/BnIdentityCredentialStore.h>
+#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
#include "SecureHardwareProxy.h"
@@ -25,14 +26,18 @@
using ::android::sp;
using ::android::hardware::identity::SecureHardwareProxyFactory;
+using ::std::optional;
using ::std::shared_ptr;
using ::std::string;
using ::std::vector;
class IdentityCredentialStore : public BnIdentityCredentialStore {
public:
- IdentityCredentialStore(sp<SecureHardwareProxyFactory> hwProxyFactory)
- : hwProxyFactory_(hwProxyFactory) {}
+ // If remote key provisioning is supported, pass the service name for the correct
+ // IRemotelyProvisionedComponent to the remotelyProvisionedComponent parameter. Else
+ // pass std::nullopt to indicate remote key provisioning is not supported.
+ IdentityCredentialStore(sp<SecureHardwareProxyFactory> hwProxyFactory,
+ optional<string> remotelyProvisionedComponent);
// The GCM chunk size used by this implementation is 64 KiB.
static constexpr size_t kGcmChunkSize = 64 * 1024;
@@ -50,8 +55,14 @@
ndk::ScopedAStatus createPresentationSession(
CipherSuite cipherSuite, shared_ptr<IPresentationSession>* outSession) override;
+ ndk::ScopedAStatus getRemotelyProvisionedComponent(
+ shared_ptr<::aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent>*
+ outRemotelyProvisionedComponent) override;
+
private:
sp<SecureHardwareProxyFactory> hwProxyFactory_;
+ optional<string> remotelyProvisionedComponentName_;
+ HardwareInformation hardwareInformation_;
};
} // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/PresentationSession.cpp b/identity/aidl/default/common/PresentationSession.cpp
index fbd8972..2eb7f2e 100644
--- a/identity/aidl/default/common/PresentationSession.cpp
+++ b/identity/aidl/default/common/PresentationSession.cpp
@@ -122,8 +122,8 @@
ndk::ScopedAStatus PresentationSession::getCredential(
const vector<uint8_t>& credentialData, shared_ptr<IIdentityCredential>* outCredential) {
shared_ptr<PresentationSession> p = ref<PresentationSession>();
- shared_ptr<IdentityCredential> credential =
- ndk::SharedRefBase::make<IdentityCredential>(hwProxyFactory_, credentialData, p);
+ shared_ptr<IdentityCredential> credential = ndk::SharedRefBase::make<IdentityCredential>(
+ hwProxyFactory_, credentialData, p, hardwareInformation_);
int ret = credential->initialize();
if (ret != IIdentityCredentialStore::STATUS_OK) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
diff --git a/identity/aidl/default/common/PresentationSession.h b/identity/aidl/default/common/PresentationSession.h
index 76ca67b..4cb174a 100644
--- a/identity/aidl/default/common/PresentationSession.h
+++ b/identity/aidl/default/common/PresentationSession.h
@@ -38,8 +38,11 @@
class PresentationSession : public BnPresentationSession {
public:
PresentationSession(sp<SecureHardwareProxyFactory> hwProxyFactory,
- sp<SecureHardwareSessionProxy> hwProxy)
- : hwProxyFactory_(std::move(hwProxyFactory)), hwProxy_(std::move(hwProxy)) {}
+ sp<SecureHardwareSessionProxy> hwProxy,
+ HardwareInformation hardwareInformation)
+ : hwProxyFactory_(std::move(hwProxyFactory)),
+ hwProxy_(std::move(hwProxy)),
+ hardwareInformation_(std::move(hardwareInformation)) {}
virtual ~PresentationSession();
@@ -65,6 +68,7 @@
// Set by constructor
sp<SecureHardwareProxyFactory> hwProxyFactory_;
sp<SecureHardwareSessionProxy> hwProxy_;
+ HardwareInformation hardwareInformation_;
// Set by initialize()
uint64_t id_;
diff --git a/identity/aidl/default/common/SecureHardwareProxy.h b/identity/aidl/default/common/SecureHardwareProxy.h
index a580444..9f63ad8 100644
--- a/identity/aidl/default/common/SecureHardwareProxy.h
+++ b/identity/aidl/default/common/SecureHardwareProxy.h
@@ -82,6 +82,18 @@
virtual optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge,
const vector<uint8_t>& applicationId) = 0;
+ // Returns public key certificate with a remotely provisioned attestation key.
+ //
+ // This returns a single certificate that is signed by the given |attestationKeyBlob|.
+ // The implementation of eicOpsCreateCredentialKey() on the TA side must coordinate
+ // with its corresponding keymint implementation to sign using the attestation key. The
+ // |attestationKeyCert| parameter is the certificates for |attestationKeyBlob|,
+ // formatted as concatenated, DER-encoded, X.509 certificates.
+ virtual optional<vector<uint8_t>> createCredentialKeyUsingRkp(
+ const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
+ const vector<uint8_t>& attestationKeyBlob,
+ const vector<uint8_t>& attestationKeyCert) = 0;
+
virtual bool startPersonalization(int accessControlProfileCount, const vector<int>& entryCounts,
const string& docType,
size_t expectedProofOfProvisioningSize) = 0;
diff --git a/identity/aidl/default/common/WritableIdentityCredential.cpp b/identity/aidl/default/common/WritableIdentityCredential.cpp
index 200ee61..e420a7b 100644
--- a/identity/aidl/default/common/WritableIdentityCredential.cpp
+++ b/identity/aidl/default/common/WritableIdentityCredential.cpp
@@ -79,8 +79,15 @@
IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge can not be empty"));
}
- optional<vector<uint8_t>> certChain =
- hwProxy_->createCredentialKey(attestationChallenge, attestationApplicationId);
+ optional<vector<uint8_t>> certChain;
+ if (attestationKeyBlob_ && attestationCertificateChain_) {
+ certChain = hwProxy_->createCredentialKeyUsingRkp(
+ attestationChallenge, attestationApplicationId, *attestationKeyBlob_,
+ attestationCertificateChain_->at(0));
+ } else {
+ certChain = hwProxy_->createCredentialKey(attestationChallenge, attestationApplicationId);
+ }
+
if (!certChain) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_FAILED,
@@ -95,8 +102,14 @@
}
*outCertificateChain = vector<Certificate>();
- for (const vector<uint8_t>& cert : certs.value()) {
- Certificate c = Certificate();
+ for (vector<uint8_t>& cert : certs.value()) {
+ Certificate c;
+ c.encodedCertificate = std::move(cert);
+ outCertificateChain->push_back(std::move(c));
+ }
+
+ for (const vector<uint8_t>& cert : *attestationCertificateChain_) {
+ Certificate c;
c.encodedCertificate = cert;
outCertificateChain->push_back(std::move(c));
}
@@ -402,4 +415,36 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus WritableIdentityCredential::setRemotelyProvisionedAttestationKey(
+ const vector<uint8_t>& attestationKeyBlob,
+ const vector<uint8_t>& attestationCertificateChain) {
+ if (!hardwareInformation_.isRemoteKeyProvisioningSupported) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(
+ EX_UNSUPPORTED_OPERATION, "Remote key provisioning is not supported"));
+ }
+
+ if (attestationKeyBlob.empty() || attestationCertificateChain.empty()) {
+ return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+ IIdentityCredentialStore::STATUS_FAILED,
+ "Empty data passed to setRemotlyProvisionedAttestationKey"));
+ }
+
+ if (attestationKeyBlob_.has_value()) {
+ return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+ IIdentityCredentialStore::STATUS_FAILED, "Attestation key already set"));
+ }
+
+ optional<vector<vector<uint8_t>>> certs =
+ support::certificateChainSplit(attestationCertificateChain);
+ if (!certs) {
+ return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+ IIdentityCredentialStore::STATUS_FAILED,
+ "Error splitting chain into separate certificates"));
+ }
+
+ attestationKeyBlob_ = attestationKeyBlob;
+ attestationCertificateChain_ = *certs;
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/WritableIdentityCredential.h b/identity/aidl/default/common/WritableIdentityCredential.h
index 36ad430..39d32c9 100644
--- a/identity/aidl/default/common/WritableIdentityCredential.h
+++ b/identity/aidl/default/common/WritableIdentityCredential.h
@@ -30,6 +30,7 @@
using ::android::sp;
using ::android::hardware::identity::SecureHardwareProvisioningProxy;
+using ::std::optional;
using ::std::set;
using ::std::string;
using ::std::vector;
@@ -41,8 +42,11 @@
// For an updated credential, call initializeForUpdate() right after construction.
//
WritableIdentityCredential(sp<SecureHardwareProvisioningProxy> hwProxy, const string& docType,
- bool testCredential)
- : hwProxy_(hwProxy), docType_(docType), testCredential_(testCredential) {}
+ bool testCredential, HardwareInformation hardwareInformation)
+ : hwProxy_(hwProxy),
+ docType_(docType),
+ testCredential_(testCredential),
+ hardwareInformation_(std::move(hardwareInformation)) {}
~WritableIdentityCredential();
@@ -78,11 +82,16 @@
vector<uint8_t>* outCredentialData,
vector<uint8_t>* outProofOfProvisioningSignature) override;
+ ndk::ScopedAStatus setRemotelyProvisionedAttestationKey(
+ const vector<uint8_t>& attestationKeyBlob,
+ const vector<uint8_t>& attestationCertificateChain) override;
+
private:
// Set by constructor.
sp<SecureHardwareProvisioningProxy> hwProxy_;
string docType_;
bool testCredential_;
+ HardwareInformation hardwareInformation_;
// This is set in initialize().
bool startPersonalizationCalled_;
@@ -109,6 +118,10 @@
vector<int32_t> entryAccessControlProfileIds_;
vector<uint8_t> entryBytes_;
set<string> allNameSpaces_;
+
+ // Remotely provisioned attestation data, set via setRemotelyProvisionedAttestationKey
+ optional<vector<uint8_t>> attestationKeyBlob_;
+ optional<vector<vector<uint8_t>>> attestationCertificateChain_;
};
} // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/libeic/EicOps.h b/identity/aidl/default/libeic/EicOps.h
index aa26e62..df96c7d 100644
--- a/identity/aidl/default/libeic/EicOps.h
+++ b/identity/aidl/default/libeic/EicOps.h
@@ -196,13 +196,19 @@
// Generates CredentialKey plus an attestation certificate.
//
-// The attestation certificate will be signed by the attestation keys the secure
-// area has been provisioned with. The given |challenge| and |applicationId|
-// will be used as will |testCredential|.
+// If |attestationKeyBlob| is non-NULL, the certificate must be signed by the
+// the provided attestation key. Else, the certificate must be signed by the
+// attestation key that the secure area has been factory provisioned with. The
+// given |challenge|, |applicationId|, and |testCredential| must be signed
+// into the attestation.
//
-// The generated certificate will be in X.509 format and returned in |cert|
-// and |certSize| must be set to the size of this array and this function will
-// set it to the size of the certification chain on successfully return.
+// When |attestationKeyBlob| is non-NULL, then |attestationKeyCert| must
+// also be passed so that the underlying implementation can properly chain up
+// the newly-generated certificate to the existing chain.
+//
+// The generated certificate must be in X.509 format and returned in |cert|
+// and |certSize| must be set to the size of this array. This function must
+// set |certSize| to the size of the certification chain on successfully return.
//
// This may return either a single certificate or an entire certificate
// chain. If it returns only a single certificate, the implementation of
@@ -211,8 +217,10 @@
//
bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const uint8_t* challenge,
size_t challengeSize, const uint8_t* applicationId,
- size_t applicationIdSize, bool testCredential, uint8_t* cert,
- size_t* certSize); // inout
+ size_t applicationIdSize, bool testCredential,
+ const uint8_t* attestationKeyBlob, size_t attestationKeyBlobSize,
+ const uint8_t* attestationKeyCert, size_t attestationKeyCertSize,
+ uint8_t* /*out*/ cert, size_t* /*inout*/ certSize);
// Generate an X.509 certificate for the key identified by |publicKey| which
// must be of the form returned by eicOpsCreateEcKey().
diff --git a/identity/aidl/default/libeic/EicProvisioning.c b/identity/aidl/default/libeic/EicProvisioning.c
index a241b71..ff009dd 100644
--- a/identity/aidl/default/libeic/EicProvisioning.c
+++ b/identity/aidl/default/libeic/EicProvisioning.c
@@ -133,7 +133,10 @@
bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
size_t challengeSize, const uint8_t* applicationId,
- size_t applicationIdSize, uint8_t* publicKeyCert,
+ size_t applicationIdSize, const uint8_t* attestationKeyBlob,
+ size_t attestationKeyBlobSize,
+ const uint8_t* attestationKeyCert,
+ size_t attestationKeyCertSize, uint8_t* publicKeyCert,
size_t* publicKeyCertSize) {
if (ctx->isUpdate) {
eicDebug("Cannot create CredentialKey on update");
@@ -142,7 +145,9 @@
if (!eicOpsCreateCredentialKey(ctx->credentialPrivateKey, challenge, challengeSize,
applicationId, applicationIdSize, ctx->testCredential,
- publicKeyCert, publicKeyCertSize)) {
+ attestationKeyBlob, attestationKeyBlobSize, attestationKeyCert,
+ attestationKeyCertSize, publicKeyCert, publicKeyCertSize)) {
+ eicDebug("Error creating credential key");
return false;
}
return true;
diff --git a/identity/aidl/default/libeic/EicProvisioning.h b/identity/aidl/default/libeic/EicProvisioning.h
index d94f8f1..2619bfc 100644
--- a/identity/aidl/default/libeic/EicProvisioning.h
+++ b/identity/aidl/default/libeic/EicProvisioning.h
@@ -77,7 +77,10 @@
bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
size_t challengeSize, const uint8_t* applicationId,
- size_t applicationIdSize, uint8_t* publicKeyCert,
+ size_t applicationIdSize, const uint8_t* attestationKeyBlob,
+ size_t attestationKeyBlobSize,
+ const uint8_t* attestationKeyCert,
+ size_t attestationKeyCertSize, uint8_t* publicKeyCert,
size_t* publicKeyCertSize);
bool eicProvisioningStartPersonalization(EicProvisioning* ctx, int accessControlProfileCount,
diff --git a/identity/aidl/default/service.cpp b/identity/aidl/default/service.cpp
index 78f4fbc..ed3c4cb 100644
--- a/identity/aidl/default/service.cpp
+++ b/identity/aidl/default/service.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "android.hardware.identity-service"
+#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
@@ -26,20 +27,35 @@
using ::android::sp;
using ::android::base::InitLogging;
+using ::android::base::LogdLogger;
+using ::android::base::LogId;
+using ::android::base::LogSeverity;
using ::android::base::StderrLogger;
using ::aidl::android::hardware::identity::IdentityCredentialStore;
+using ::aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent;
using ::android::hardware::identity::FakeSecureHardwareProxyFactory;
using ::android::hardware::identity::SecureHardwareProxyFactory;
+void ComboLogger(LogId id, LogSeverity severity, const char* tag, const char* file,
+ unsigned int line, const char* message) {
+ StderrLogger(id, severity, tag, file, line, message);
+
+ static LogdLogger logdLogger;
+ logdLogger(id, severity, tag, file, line, message);
+}
+
int main(int /*argc*/, char* argv[]) {
- InitLogging(argv, StderrLogger);
+ InitLogging(argv, ComboLogger);
sp<SecureHardwareProxyFactory> hwProxyFactory = new FakeSecureHardwareProxyFactory();
+ const std::string remotelyProvisionedComponentName =
+ std::string(IRemotelyProvisionedComponent::descriptor) + "/default";
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<IdentityCredentialStore> store =
- ndk::SharedRefBase::make<IdentityCredentialStore>(hwProxyFactory);
+ ndk::SharedRefBase::make<IdentityCredentialStore>(hwProxyFactory,
+ remotelyProvisionedComponentName);
const std::string instance = std::string() + IdentityCredentialStore::descriptor + "/default";
binder_status_t status = AServiceManager_addService(store->asBinder().get(), instance.c_str());
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index 7b6f2c8..20faeee 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -11,6 +11,8 @@
name: "VtsHalIdentityTargetTest",
defaults: [
"VtsHalTargetTestDefaults",
+ "keymint_use_latest_hal_aidl_cpp_static",
+ "keymint_use_latest_hal_aidl_ndk_static",
"use_libaidlvintf_gtest_helper_static",
],
cflags: [
@@ -32,12 +34,15 @@
],
shared_libs: [
"libbinder",
+ "libbinder_ndk",
"libcrypto",
],
static_libs: [
+ "android.hardware.security.secureclock-V1-ndk",
"libcppbor_external",
"libcppcose_rkp",
"libkeymaster_portable",
+ "libkeymint_vts_test_utils",
"libpuresoftkeymasterdevice",
"android.hardware.keymaster@4.0",
"android.hardware.identity-support-lib",
@@ -46,9 +51,23 @@
"android.hardware.keymaster-V4-ndk",
"libkeymaster4support",
"libkeymaster4_1support",
+ "libkeymint_remote_prov_support",
],
test_suites: [
"general-tests",
"vts",
],
}
+
+java_test_host {
+ name: "IdentityCredentialImplementedTest",
+ libs: [
+ "tradefed",
+ "vts-core-tradefed-harness",
+ ],
+ srcs: ["src/**/*.java"],
+ test_suites: [
+ "vts",
+ ],
+ test_config: "IdentityCredentialImplementedTest.xml",
+}
diff --git a/identity/aidl/vts/DeleteCredentialTests.cpp b/identity/aidl/vts/DeleteCredentialTests.cpp
index 7627c9c..a126463 100644
--- a/identity/aidl/vts/DeleteCredentialTests.cpp
+++ b/identity/aidl/vts/DeleteCredentialTests.cpp
@@ -146,7 +146,9 @@
credentialData_, &credential)
.isOk());
- vector<uint8_t> challenge = {65, 66, 67};
+ // Implementations must support at least 32 bytes.
+ string challengeString = "0123456789abcdef0123456789abcdef";
+ vector<uint8_t> challenge(challengeString.begin(), challengeString.end());
vector<uint8_t> proofOfDeletionSignature;
ASSERT_TRUE(
credential->deleteCredentialWithChallenge(challenge, &proofOfDeletionSignature).isOk());
@@ -154,8 +156,13 @@
support::coseSignGetPayload(proofOfDeletionSignature);
ASSERT_TRUE(proofOfDeletion);
string cborPretty = cppbor::prettyPrint(proofOfDeletion.value(), 32, {});
- EXPECT_EQ("['ProofOfDeletion', 'org.iso.18013-5.2019.mdl', {0x41, 0x42, 0x43}, true, ]",
- cborPretty);
+ EXPECT_EQ(
+ "['ProofOfDeletion', 'org.iso.18013-5.2019.mdl', {"
+ "0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, "
+ "0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, "
+ "0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, "
+ "0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66}, true, ]",
+ cborPretty);
EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfDeletionSignature, {}, // Additional data
credentialPubKey_));
}
diff --git a/identity/aidl/vts/IdentityCredentialImplementedTest.xml b/identity/aidl/vts/IdentityCredentialImplementedTest.xml
new file mode 100644
index 0000000..1d76a74
--- /dev/null
+++ b/identity/aidl/vts/IdentityCredentialImplementedTest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs IdentityCredentialImplementedTest">
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+
+ <test class="com.android.tradefed.testtype.HostTest" >
+ <option name="jar" value="IdentityCredentialImplementedTest.jar" />
+ </test>
+</configuration>
diff --git a/identity/aidl/vts/ProveOwnershipTests.cpp b/identity/aidl/vts/ProveOwnershipTests.cpp
index c622193..f8ec670 100644
--- a/identity/aidl/vts/ProveOwnershipTests.cpp
+++ b/identity/aidl/vts/ProveOwnershipTests.cpp
@@ -125,14 +125,22 @@
credentialData_, &credential)
.isOk());
- vector<uint8_t> challenge = {17, 18};
+ // Implementations must support at least 32 bytes.
+ string challengeString = "0123456789abcdef0123456789abcdef";
+ vector<uint8_t> challenge(challengeString.begin(), challengeString.end());
vector<uint8_t> proofOfOwnershipSignature;
ASSERT_TRUE(credential->proveOwnership(challenge, &proofOfOwnershipSignature).isOk());
optional<vector<uint8_t>> proofOfOwnership =
support::coseSignGetPayload(proofOfOwnershipSignature);
ASSERT_TRUE(proofOfOwnership);
string cborPretty = cppbor::prettyPrint(proofOfOwnership.value(), 32, {});
- EXPECT_EQ("['ProofOfOwnership', 'org.iso.18013-5.2019.mdl', {0x11, 0x12}, true, ]", cborPretty);
+ EXPECT_EQ(
+ "['ProofOfOwnership', 'org.iso.18013-5.2019.mdl', {"
+ "0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, "
+ "0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, "
+ "0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, "
+ "0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66}, true, ]",
+ cborPretty);
EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfOwnershipSignature, {}, // Additional data
credentialPubKey_));
}
diff --git a/identity/aidl/vts/Util.cpp b/identity/aidl/vts/Util.cpp
index 1148cb0..f3d7c30 100644
--- a/identity/aidl/vts/Util.cpp
+++ b/identity/aidl/vts/Util.cpp
@@ -20,12 +20,16 @@
#include <android-base/logging.h>
+#include <KeyMintAidlTestBase.h>
#include <aidl/Gtest.h>
+#include <aidl/android/hardware/security/keymint/MacedPublicKey.h>
#include <android-base/stringprintf.h>
#include <keymaster/km_openssl/openssl_utils.h>
#include <keymasterV4_1/attestation_record.h>
-#include <charconv>
+#include <keymint_support/openssl_utils.h>
+#include <openssl/evp.h>
+#include <charconv>
#include <map>
namespace android::hardware::identity::test_utils {
@@ -36,10 +40,13 @@
using std::string;
using std::vector;
+using ::aidl::android::hardware::security::keymint::test::check_maced_pubkey;
+using ::aidl::android::hardware::security::keymint::test::p256_pub_key;
using ::android::sp;
using ::android::String16;
using ::android::base::StringPrintf;
using ::android::binder::Status;
+using ::android::hardware::security::keymint::MacedPublicKey;
using ::keymaster::X509_Ptr;
bool setupWritableCredential(sp<IWritableIdentityCredential>& writableCredential,
@@ -58,6 +65,77 @@
}
}
+optional<vector<vector<uint8_t>>> createFakeRemotelyProvisionedCertificateChain(
+ const MacedPublicKey& macedPublicKey) {
+ // The helper library uses the NDK symbols, so play a little trickery here to convert
+ // the data into the proper type so we can reuse the helper function to get the pubkey.
+ ::aidl::android::hardware::security::keymint::MacedPublicKey ndkMacedPublicKey;
+ ndkMacedPublicKey.macedKey = macedPublicKey.macedKey;
+
+ vector<uint8_t> publicKeyBits;
+ check_maced_pubkey(ndkMacedPublicKey, /*testMode=*/true, &publicKeyBits);
+
+ ::aidl::android::hardware::security::keymint::EVP_PKEY_Ptr publicKey;
+ p256_pub_key(publicKeyBits, &publicKey);
+
+ // Generate an arbitrary root key for our chain
+ bssl::UniquePtr<EC_KEY> ecRootKey(EC_KEY_new());
+ bssl::UniquePtr<EVP_PKEY> rootKey(EVP_PKEY_new());
+ if (ecRootKey.get() == nullptr || rootKey.get() == nullptr) {
+ LOG(ERROR) << "Memory allocation failed";
+ return {};
+ }
+
+ bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+ if (group.get() == nullptr) {
+ LOG(ERROR) << "Error creating EC group by curve name";
+ return {};
+ }
+
+ if (EC_KEY_set_group(ecRootKey.get(), group.get()) != 1 ||
+ EC_KEY_generate_key(ecRootKey.get()) != 1 || EC_KEY_check_key(ecRootKey.get()) < 0) {
+ LOG(ERROR) << "Error generating key";
+ return {};
+ }
+
+ if (EVP_PKEY_set1_EC_KEY(rootKey.get(), ecRootKey.get()) != 1) {
+ LOG(ERROR) << "Error getting private key";
+ return {};
+ }
+
+ // The VTS test does not fully validate the chain, so we're ok without the proper CA extensions.
+ map<string, vector<uint8_t>> extensions;
+
+ // Now make a self-signed cert
+ optional<vector<uint8_t>> root = support::ecPublicKeyGenerateCertificate(
+ rootKey.get(), rootKey.get(),
+ /*serialDecimal=*/"31415",
+ /*subject=*/"Android IdentityCredential VTS Test Root Certificate",
+ /*subject=*/"Android IdentityCredential VTS Test Root Certificate",
+ /*validityNotBefore=*/time(nullptr),
+ /*validityNotAfter=*/time(nullptr) + 365 * 24 * 3600, extensions);
+ if (!root) {
+ LOG(ERROR) << "Error generating root cert";
+ return std::nullopt;
+ }
+
+ // Now sign a CA cert so that we have a chain that's good enough to satisfy
+ // the VTS tests.
+ optional<vector<uint8_t>> intermediate = support::ecPublicKeyGenerateCertificate(
+ publicKey.get(), rootKey.get(),
+ /*serialDecimal=*/"42",
+ /*subject=*/"Android IdentityCredential VTS Test Root Certificate",
+ /*subject=*/"Android IdentityCredential VTS Test Attestation Certificate",
+ /*validityNotBefore=*/time(nullptr),
+ /*validityNotAfter=*/time(nullptr) + 365 * 24 * 3600, extensions);
+ if (!intermediate) {
+ LOG(ERROR) << "Error generating intermediate cert";
+ return std::nullopt;
+ }
+
+ return vector<vector<uint8_t>>{std::move(*intermediate), std::move(*root)};
+}
+
optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal) {
vector<uint8_t> privKey;
return generateReaderCertificate(serialDecimal, &privKey);
diff --git a/identity/aidl/vts/Util.h b/identity/aidl/vts/Util.h
index 80e52a2..b120dc9 100644
--- a/identity/aidl/vts/Util.h
+++ b/identity/aidl/vts/Util.h
@@ -19,6 +19,7 @@
#include <android/hardware/identity/IIdentityCredentialStore.h>
#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+#include <android/hardware/security/keymint/MacedPublicKey.h>
#include <cppbor.h>
#include <cppbor_parse.h>
#include <gtest/gtest.h>
@@ -97,6 +98,9 @@
bool setupWritableCredential(sp<IWritableIdentityCredential>& writableCredential,
sp<IIdentityCredentialStore>& credentialStore, bool testCredential);
+optional<vector<vector<uint8_t>>> createFakeRemotelyProvisionedCertificateChain(
+ const ::android::hardware::security::keymint::MacedPublicKey& macedPublicKey);
+
optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal);
optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal,
diff --git a/identity/aidl/vts/VtsAttestationTests.cpp b/identity/aidl/vts/VtsAttestationTests.cpp
index e12fe05..7caa259 100644
--- a/identity/aidl/vts/VtsAttestationTests.cpp
+++ b/identity/aidl/vts/VtsAttestationTests.cpp
@@ -66,7 +66,8 @@
ASSERT_TRUE(setupWritableCredential(writableCredential, credentialStore_,
false /* testCredential */));
- string challenge = "NotSoRandomChallenge1NotSoRandomChallenge1NotSoRandomChallenge1";
+ // Must support at least 32 bytes.
+ string challenge = "0123456789abcdef0123456789abcdef";
vector<uint8_t> attestationChallenge(challenge.begin(), challenge.end());
vector<Certificate> attestationCertificate;
string applicationId = "Attestation Verification";
diff --git a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
index bc37020..94d4c88 100644
--- a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
+++ b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
@@ -18,6 +18,8 @@
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
+#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
+#include <aidl/android/hardware/security/keymint/MacedPublicKey.h>
#include <android-base/logging.h>
#include <android/hardware/identity/IIdentityCredentialStore.h>
#include <android/hardware/identity/support/IdentityCredentialSupport.h>
@@ -42,6 +44,8 @@
using ::android::sp;
using ::android::String16;
using ::android::binder::Status;
+using ::android::hardware::security::keymint::IRemotelyProvisionedComponent;
+using ::android::hardware::security::keymint::MacedPublicKey;
class IdentityCredentialTests : public testing::TestWithParam<string> {
public:
@@ -101,6 +105,103 @@
attestationApplicationId, false);
}
+TEST_P(IdentityCredentialTests, verifyAttestationSuccessWithRemoteProvisioning) {
+ HardwareInformation hwInfo;
+ ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
+
+ if (!hwInfo.isRemoteKeyProvisioningSupported) {
+ GTEST_SKIP() << "Remote provisioning is not supported";
+ }
+
+ Status result;
+
+ sp<IWritableIdentityCredential> writableCredential;
+ ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
+ false /* testCredential */));
+
+ sp<IRemotelyProvisionedComponent> rpc;
+ result = credentialStore_->getRemotelyProvisionedComponent(&rpc);
+ ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
+
+ MacedPublicKey macedPublicKey;
+ std::vector<uint8_t> attestationKey;
+ result = rpc->generateEcdsaP256KeyPair(/*testMode=*/true, &macedPublicKey, &attestationKey);
+ ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
+
+ optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain =
+ test_utils::createFakeRemotelyProvisionedCertificateChain(macedPublicKey);
+ ASSERT_TRUE(remotelyProvisionedCertChain);
+
+ vector<uint8_t> concatenatedCerts;
+ for (const vector<uint8_t>& cert : *remotelyProvisionedCertChain) {
+ concatenatedCerts.insert(concatenatedCerts.end(), cert.begin(), cert.end());
+ }
+ result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
+ concatenatedCerts);
+ ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
+
+ string challenge = "NotSoRandomChallenge1NotSoRandomChallenge1NotSoRandomChallenge1";
+ vector<uint8_t> attestationChallenge(challenge.begin(), challenge.end());
+ vector<Certificate> attestationCertificate;
+ vector<uint8_t> attestationApplicationId = {1};
+
+ result = writableCredential->getAttestationCertificate(
+ attestationApplicationId, attestationChallenge, &attestationCertificate);
+
+ ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
+
+ test_utils::validateAttestationCertificate(attestationCertificate, attestationChallenge,
+ attestationApplicationId, false);
+
+ ASSERT_EQ(remotelyProvisionedCertChain->size() + 1, attestationCertificate.size());
+ for (size_t i = 0; i < remotelyProvisionedCertChain->size(); ++i) {
+ ASSERT_EQ(remotelyProvisionedCertChain->at(i),
+ attestationCertificate[i + 1].encodedCertificate)
+ << "Certificate mismatch (cert index " << i + 1 << " out of "
+ << attestationCertificate.size() << " total certs)";
+ }
+}
+
+TEST_P(IdentityCredentialTests, verifyRemotelyProvisionedKeyMayOnlyBeSetOnce) {
+ HardwareInformation hwInfo;
+ ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
+
+ if (!hwInfo.isRemoteKeyProvisioningSupported) {
+ GTEST_SKIP() << "Remote provisioning is not supported";
+ }
+
+ sp<IRemotelyProvisionedComponent> rpc;
+ Status result = credentialStore_->getRemotelyProvisionedComponent(&rpc);
+ ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
+
+ MacedPublicKey macedPublicKey;
+ std::vector<uint8_t> attestationKey;
+ result = rpc->generateEcdsaP256KeyPair(/*testMode=*/true, &macedPublicKey, &attestationKey);
+ ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
+
+ optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain =
+ test_utils::createFakeRemotelyProvisionedCertificateChain(macedPublicKey);
+ ASSERT_TRUE(remotelyProvisionedCertChain);
+
+ vector<uint8_t> concatenatedCerts;
+ for (const vector<uint8_t>& cert : *remotelyProvisionedCertChain) {
+ concatenatedCerts.insert(concatenatedCerts.end(), cert.begin(), cert.end());
+ }
+
+ sp<IWritableIdentityCredential> writableCredential;
+ ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
+ /*testCredential=*/false));
+
+ result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
+ concatenatedCerts);
+ ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
+
+ // Now try again, and verify that the implementation rejects it.
+ result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
+ concatenatedCerts);
+ EXPECT_FALSE(result.isOk());
+}
+
TEST_P(IdentityCredentialTests, verifyAttestationDoubleCallFails) {
Status result;
diff --git a/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java b/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java
new file mode 100644
index 0000000..19568af
--- /dev/null
+++ b/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tests.security.identity;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.annotations.RequiresDevice;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class IdentityCredentialImplementedTest extends BaseHostJUnit4Test {
+ // Returns the ro.vendor.api_level or 0 if not set.
+ //
+ // Throws NumberFormatException if ill-formatted.
+ //
+ // Throws DeviceNotAvailableException if device is not available.
+ //
+ private int getVendorApiLevel() throws NumberFormatException, DeviceNotAvailableException {
+ String vendorApiLevelString =
+ getDevice().executeShellCommand("getprop ro.vendor.api_level").trim();
+ if (vendorApiLevelString.isEmpty()) {
+ return 0;
+ }
+ return Integer.parseInt(vendorApiLevelString);
+ }
+
+ // As of Android 13 (API level 32), Identity Credential is required at feature version 202201
+ // or newer.
+ //
+ @RequiresDevice
+ @Test
+ public void testIdentityCredentialIsImplemented() throws Exception {
+ int vendorApiLevel = getVendorApiLevel();
+ assumeTrue(vendorApiLevel >= 32);
+
+ final String minimumFeatureVersionNeeded = "202201";
+
+ String result = getDevice().executeShellCommand(
+ "pm has-feature android.hardware.identity_credential "
+ + minimumFeatureVersionNeeded);
+ if (!result.trim().equals("true")) {
+ fail("Identity Credential feature version " + minimumFeatureVersionNeeded
+ + " required but not found");
+ }
+ }
+}
diff --git a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
index 3b91de6..82746d6 100644
--- a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
+++ b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
@@ -17,6 +17,8 @@
#ifndef IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
#define IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
+#include <openssl/evp.h>
+
#include <cstdint>
#include <map>
#include <optional>
@@ -128,6 +130,15 @@
const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
bool isTestCredential);
+// Alternate version of createEcKeyPairAndAttestation that accepts an attestation key
+// blob to sign the generated key. Only a single certificate is returned, rather than
+// a full chain.
+//
+optional<std::pair<vector<uint8_t>, vector<uint8_t>>> createEcKeyPairWithAttestationKey(
+ const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
+ const vector<uint8_t>& attestationKeyBlob, const vector<uint8_t>& attestationKeyCert,
+ bool isTestCredential);
+
// (TODO: remove when no longer used by 3rd party.)
optional<vector<vector<uint8_t>>> createAttestationForEcPublicKey(
const vector<uint8_t>& publicKey, const vector<uint8_t>& challenge,
@@ -240,6 +251,13 @@
time_t validityNotBefore, time_t validityNotAfter,
const map<string, vector<uint8_t>>& extensions);
+// Identical behavior to the above version of ecPublicKeyGenerateCertificate, except this
+// overload takes OpenSSL key parameters instead of key bitstrings as inputs.
+optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
+ EVP_PKEY* publicKey, EVP_PKEY* signingKey, const string& serialDecimal,
+ const string& issuer, const string& subject, time_t validityNotBefore,
+ time_t validityNotAfter, const map<string, vector<uint8_t>>& extensions);
+
// Performs Elliptic-curve Diffie-Helman using |publicKey| (which must be in the
// format returned by ecKeyPairGetPublicKey()) and |privateKey| (which must be
// in the format returned by ecKeyPairGetPrivateKey()).
diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp
index 7f4674d..36ecdb0 100644
--- a/identity/support/src/IdentityCredentialSupport.cpp
+++ b/identity/support/src/IdentityCredentialSupport.cpp
@@ -54,6 +54,7 @@
#include <keymaster/contexts/pure_soft_keymaster_context.h>
#include <keymaster/contexts/soft_attestation_cert.h>
#include <keymaster/keymaster_tags.h>
+#include <keymaster/km_openssl/asymmetric_key.h>
#include <keymaster/km_openssl/attestation_utils.h>
#include <keymaster/km_openssl/certificate_utils.h>
@@ -168,6 +169,286 @@
using X509_NAME_Ptr = bssl::UniquePtr<X509_NAME>;
using X509_EXTENSION_Ptr = bssl::UniquePtr<X509_EXTENSION>;
+namespace {
+
+EVP_PKEY_Ptr generateP256Key() {
+ EC_KEY_Ptr ec_key(EC_KEY_new());
+ EVP_PKEY_Ptr pkey(EVP_PKEY_new());
+ EC_GROUP_Ptr group(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+
+ if (ec_key.get() == nullptr || pkey.get() == nullptr) {
+ LOG(ERROR) << "Memory allocation failed";
+ return {};
+ }
+
+ if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
+ EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
+ LOG(ERROR) << "Error generating key";
+ return {};
+ }
+
+ if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
+ LOG(ERROR) << "Error getting private key";
+ return {};
+ }
+
+ return pkey;
+}
+
+optional<vector<uint8_t>> derEncodeKeyPair(const EVP_PKEY& pkey) {
+ int size = i2d_PrivateKey(&pkey, nullptr);
+ if (size == 0) {
+ LOG(ERROR) << "Error generating public key encoding";
+ return std::nullopt;
+ }
+
+ vector<uint8_t> keyPair(size);
+ unsigned char* p = keyPair.data();
+ i2d_PrivateKey(&pkey, &p);
+
+ return keyPair;
+}
+
+// Extract the issuer subject name from the leaf cert in the given chain,
+// returning it as DER-encoded bytes.
+optional<vector<uint8_t>> extractDerSubjectFromCertificate(const vector<uint8_t>& certificate) {
+ const uint8_t* input = certificate.data();
+ X509_Ptr cert(d2i_X509(/*cert=*/nullptr, &input, certificate.size()));
+ if (!cert) {
+ LOG(ERROR) << "Failed to parse certificate";
+ return std::nullopt;
+ }
+
+ X509_NAME* subject = X509_get_subject_name(cert.get());
+ if (!subject) {
+ LOG(ERROR) << "Failed to retrieve subject name";
+ return std::nullopt;
+ }
+
+ int encodedSubjectLength = i2d_X509_NAME(subject, /*out=*/nullptr);
+ if (encodedSubjectLength < 0) {
+ LOG(ERROR) << "Error obtaining encoded subject name length";
+ return std::nullopt;
+ }
+
+ vector<uint8_t> encodedSubject(encodedSubjectLength);
+ uint8_t* out = encodedSubject.data();
+ if (encodedSubjectLength != i2d_X509_NAME(subject, &out)) {
+ LOG(ERROR) << "Error encoding subject name";
+ return std::nullopt;
+ }
+
+ return encodedSubject;
+}
+
+// Generates the attestation certificate with the parameters passed in. Note
+// that the passed in |activeTimeMilliSeconds| |expireTimeMilliSeconds| are in
+// milli seconds since epoch. We are setting them to milliseconds due to
+// requirement in AuthorizationSet KM_DATE fields. The certificate created is
+// actually in seconds.
+//
+optional<vector<vector<uint8_t>>> signAttestationCertificate(
+ const ::keymaster::PureSoftKeymasterContext& context, const EVP_PKEY* key,
+ const vector<uint8_t>& applicationId, const vector<uint8_t>& challenge,
+ const vector<uint8_t>& attestationKeyBlob,
+ const vector<uint8_t>& derAttestationCertSubjectName, uint64_t activeTimeMilliSeconds,
+ uint64_t expireTimeMilliSeconds, bool isTestCredential) {
+ ::keymaster::X509_NAME_Ptr subjectName;
+ if (KM_ERROR_OK !=
+ ::keymaster::make_name_from_str("Android Identity Credential Key", &subjectName)) {
+ LOG(ERROR) << "Cannot create attestation subject";
+ return {};
+ }
+
+ vector<uint8_t> subject(i2d_X509_NAME(subjectName.get(), NULL));
+ unsigned char* subjectPtr = subject.data();
+
+ i2d_X509_NAME(subjectName.get(), &subjectPtr);
+
+ ::keymaster::AuthorizationSet auth_set(
+ ::keymaster::AuthorizationSetBuilder()
+ .Authorization(::keymaster::TAG_CERTIFICATE_NOT_BEFORE, activeTimeMilliSeconds)
+ .Authorization(::keymaster::TAG_CERTIFICATE_NOT_AFTER, expireTimeMilliSeconds)
+ .Authorization(::keymaster::TAG_ATTESTATION_CHALLENGE, challenge.data(),
+ challenge.size())
+ .Authorization(::keymaster::TAG_ACTIVE_DATETIME, activeTimeMilliSeconds)
+ // Even though identity attestation hal said the application
+ // id should be in software enforced authentication set,
+ // keymaster portable lib expect the input in this
+ // parameter because the software enforced in input to keymaster
+ // refers to the key software enforced properties. And this
+ // parameter refers to properties of the attestation which
+ // includes app id.
+ .Authorization(::keymaster::TAG_ATTESTATION_APPLICATION_ID,
+ applicationId.data(), applicationId.size())
+ .Authorization(::keymaster::TAG_CERTIFICATE_SUBJECT, subject.data(),
+ subject.size())
+ .Authorization(::keymaster::TAG_USAGE_EXPIRE_DATETIME, expireTimeMilliSeconds));
+
+ // Unique id and device id is not applicable for identity credential attestation,
+ // so we don't need to set those or application id.
+ ::keymaster::AuthorizationSet swEnforced(::keymaster::AuthorizationSetBuilder().Authorization(
+ ::keymaster::TAG_CREATION_DATETIME, activeTimeMilliSeconds));
+
+ ::keymaster::AuthorizationSetBuilder hwEnforcedBuilder =
+ ::keymaster::AuthorizationSetBuilder()
+ .Authorization(::keymaster::TAG_PURPOSE, KM_PURPOSE_SIGN)
+ .Authorization(::keymaster::TAG_KEY_SIZE, 256)
+ .Authorization(::keymaster::TAG_ALGORITHM, KM_ALGORITHM_EC)
+ .Authorization(::keymaster::TAG_NO_AUTH_REQUIRED)
+ .Authorization(::keymaster::TAG_DIGEST, KM_DIGEST_SHA_2_256)
+ .Authorization(::keymaster::TAG_EC_CURVE, KM_EC_CURVE_P_256)
+ .Authorization(::keymaster::TAG_OS_VERSION, 42)
+ .Authorization(::keymaster::TAG_OS_PATCHLEVEL, 43);
+
+ // Only include TAG_IDENTITY_CREDENTIAL_KEY if it's not a test credential
+ if (!isTestCredential) {
+ hwEnforcedBuilder.Authorization(::keymaster::TAG_IDENTITY_CREDENTIAL_KEY);
+ }
+ ::keymaster::AuthorizationSet hwEnforced(hwEnforcedBuilder);
+
+ keymaster_error_t error;
+ ::keymaster::AttestKeyInfo attestKeyInfo;
+ ::keymaster::KeymasterBlob issuerSubjectNameBlob;
+ if (!attestationKeyBlob.empty()) {
+ ::keymaster::KeymasterKeyBlob blob(attestationKeyBlob.data(), attestationKeyBlob.size());
+ ::keymaster::UniquePtr<::keymaster::Key> parsedKey;
+ error = context.ParseKeyBlob(blob, /*additional_params=*/{}, &parsedKey);
+ if (error != KM_ERROR_OK) {
+ LOG(ERROR) << "Error loading attestation key: " << error;
+ return std::nullopt;
+ }
+
+ attestKeyInfo.signing_key =
+ static_cast<::keymaster::AsymmetricKey&>(*parsedKey).InternalToEvp();
+ issuerSubjectNameBlob = ::keymaster::KeymasterBlob(derAttestationCertSubjectName.data(),
+ derAttestationCertSubjectName.size());
+ attestKeyInfo.issuer_subject = &issuerSubjectNameBlob;
+ }
+
+ ::keymaster::CertificateChain certChain = generate_attestation(
+ key, swEnforced, hwEnforced, auth_set, std::move(attestKeyInfo), context, &error);
+
+ if (KM_ERROR_OK != error) {
+ LOG(ERROR) << "Error generating attestation from EVP key: " << error;
+ return std::nullopt;
+ }
+
+ vector<vector<uint8_t>> vectors(certChain.entry_count);
+ for (std::size_t i = 0; i < certChain.entry_count; i++) {
+ vectors[i] = {certChain.entries[i].data,
+ certChain.entries[i].data + certChain.entries[i].data_length};
+ }
+ return vectors;
+}
+
+int parseDigits(const char** s, int numDigits) {
+ int result;
+ auto [_, ec] = std::from_chars(*s, *s + numDigits, result);
+ if (ec != std::errc()) {
+ LOG(ERROR) << "Error parsing " << numDigits << " digits "
+ << " from " << s;
+ return 0;
+ }
+ *s += numDigits;
+ return result;
+}
+
+bool parseAsn1Time(const ASN1_TIME* asn1Time, time_t* outTime) {
+ struct tm tm;
+
+ memset(&tm, '\0', sizeof(tm));
+ const char* timeStr = (const char*)asn1Time->data;
+ const char* s = timeStr;
+ if (asn1Time->type == V_ASN1_UTCTIME) {
+ tm.tm_year = parseDigits(&s, 2);
+ if (tm.tm_year < 70) {
+ tm.tm_year += 100;
+ }
+ } else if (asn1Time->type == V_ASN1_GENERALIZEDTIME) {
+ tm.tm_year = parseDigits(&s, 4) - 1900;
+ tm.tm_year -= 1900;
+ } else {
+ LOG(ERROR) << "Unsupported ASN1_TIME type " << asn1Time->type;
+ return false;
+ }
+ tm.tm_mon = parseDigits(&s, 2) - 1;
+ tm.tm_mday = parseDigits(&s, 2);
+ tm.tm_hour = parseDigits(&s, 2);
+ tm.tm_min = parseDigits(&s, 2);
+ tm.tm_sec = parseDigits(&s, 2);
+ // This may need to be updated if someone create certificates using +/- instead of Z.
+ //
+ if (*s != 'Z') {
+ LOG(ERROR) << "Expected Z in string '" << timeStr << "' at offset " << (s - timeStr);
+ return false;
+ }
+
+ time_t t = timegm(&tm);
+ if (t == -1) {
+ LOG(ERROR) << "Error converting broken-down time to time_t";
+ return false;
+ }
+ *outTime = t;
+ return true;
+}
+
+optional<uint64_t> getCertificateExpiryAsMillis(const uint8_t* derCert, size_t derCertSize) {
+ X509_Ptr x509Cert(d2i_X509(nullptr, &derCert, derCertSize));
+ if (!x509Cert) {
+ LOG(ERROR) << "Error parsing certificate";
+ return std::nullopt;
+ }
+
+ time_t notAfter;
+ if (!parseAsn1Time(X509_get0_notAfter(x509Cert.get()), ¬After)) {
+ LOG(ERROR) << "Error getting notAfter from batch certificate";
+ return std::nullopt;
+ }
+
+ return notAfter * 1000;
+}
+
+optional<vector<vector<uint8_t>>> createAttestation(EVP_PKEY* pkey,
+ const vector<uint8_t>& challenge,
+ const vector<uint8_t>& applicationId,
+ bool isTestCredential) {
+ // Pretend to be implemented in a trusted environment just so we can pass
+ // the VTS tests. Of course, this is a pretend-only game since hopefully no
+ // relying party is ever going to trust our batch key and those keys above
+ // it.
+ ::keymaster::PureSoftKeymasterContext context(::keymaster::KmVersion::KEYMINT_1,
+ KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT);
+
+ keymaster_error_t error;
+ ::keymaster::CertificateChain attestation_chain =
+ context.GetAttestationChain(KM_ALGORITHM_EC, &error);
+ if (KM_ERROR_OK != error) {
+ LOG(ERROR) << "Error getting attestation chain " << error;
+ return std::nullopt;
+ }
+
+ if (attestation_chain.entry_count < 1) {
+ LOG(ERROR) << "Expected at least one entry in attestation chain";
+ return std::nullopt;
+ }
+
+ uint64_t activeTimeMs = time(nullptr) * 1000;
+ optional<uint64_t> expireTimeMs = getCertificateExpiryAsMillis(
+ attestation_chain.entries[0].data, attestation_chain.entries[0].data_length);
+ if (!expireTimeMs) {
+ LOG(ERROR) << "Error getting expiration time for batch cert";
+ return std::nullopt;
+ }
+
+ return signAttestationCertificate(context, pkey, applicationId, challenge,
+ /*attestationKeyBlob=*/{},
+ /*derAttestationCertSubjectName=*/{}, activeTimeMs,
+ *expireTimeMs, isTestCredential);
+}
+
+} // namespace
+
// bool getRandom(size_t numBytes, vector<uint8_t>& output) {
optional<vector<uint8_t>> getRandom(size_t numBytes) {
vector<uint8_t> output;
@@ -577,69 +858,30 @@
return hmac;
}
-int parseDigits(const char** s, int numDigits) {
- int result;
- auto [_, ec] = std::from_chars(*s, *s + numDigits, result);
- if (ec != std::errc()) {
- LOG(ERROR) << "Error parsing " << numDigits << " digits "
- << " from " << s;
- return 0;
+optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
+ const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
+ bool isTestCredential) {
+ EVP_PKEY_Ptr pkey = generateP256Key();
+
+ optional<vector<vector<uint8_t>>> attestationCertChain =
+ createAttestation(pkey.get(), challenge, applicationId, isTestCredential);
+ if (!attestationCertChain) {
+ LOG(ERROR) << "Error create attestation from key and challenge";
+ return {};
}
- *s += numDigits;
- return result;
+
+ optional<vector<uint8_t>> keyPair = derEncodeKeyPair(*pkey);
+ if (!keyPair) {
+ return std::nullopt;
+ }
+
+ return make_pair(*keyPair, *attestationCertChain);
}
-bool parseAsn1Time(const ASN1_TIME* asn1Time, time_t* outTime) {
- struct tm tm;
-
- memset(&tm, '\0', sizeof(tm));
- const char* timeStr = (const char*)asn1Time->data;
- const char* s = timeStr;
- if (asn1Time->type == V_ASN1_UTCTIME) {
- tm.tm_year = parseDigits(&s, 2);
- if (tm.tm_year < 70) {
- tm.tm_year += 100;
- }
- } else if (asn1Time->type == V_ASN1_GENERALIZEDTIME) {
- tm.tm_year = parseDigits(&s, 4) - 1900;
- tm.tm_year -= 1900;
- } else {
- LOG(ERROR) << "Unsupported ASN1_TIME type " << asn1Time->type;
- return false;
- }
- tm.tm_mon = parseDigits(&s, 2) - 1;
- tm.tm_mday = parseDigits(&s, 2);
- tm.tm_hour = parseDigits(&s, 2);
- tm.tm_min = parseDigits(&s, 2);
- tm.tm_sec = parseDigits(&s, 2);
- // This may need to be updated if someone create certificates using +/- instead of Z.
- //
- if (*s != 'Z') {
- LOG(ERROR) << "Expected Z in string '" << timeStr << "' at offset " << (s - timeStr);
- return false;
- }
-
- time_t t = timegm(&tm);
- if (t == -1) {
- LOG(ERROR) << "Error converting broken-down time to time_t";
- return false;
- }
- *outTime = t;
- return true;
-}
-
-// Generates the attestation certificate with the parameters passed in. Note
-// that the passed in |activeTimeMilliSeconds| |expireTimeMilliSeconds| are in
-// milli seconds since epoch. We are setting them to milliseconds due to
-// requirement in AuthorizationSet KM_DATE fields. The certificate created is
-// actually in seconds.
-//
-// If 0 is passed for expiration time, the expiration time from batch
-// certificate will be used.
-//
-optional<vector<vector<uint8_t>>> createAttestation(
- const EVP_PKEY* key, const vector<uint8_t>& applicationId, const vector<uint8_t>& challenge,
- uint64_t activeTimeMilliSeconds, uint64_t expireTimeMilliSeconds, bool isTestCredential) {
+optional<std::pair<vector<uint8_t>, vector<uint8_t>>> createEcKeyPairWithAttestationKey(
+ const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
+ const vector<uint8_t>& attestationKeyBlob, const vector<uint8_t>& attestationKeyCert,
+ bool isTestCredential) {
// Pretend to be implemented in a trusted environment just so we can pass
// the VTS tests. Of course, this is a pretend-only game since hopefully no
// relying party is ever going to trust our batch key and those keys above
@@ -647,148 +889,45 @@
::keymaster::PureSoftKeymasterContext context(::keymaster::KmVersion::KEYMINT_1,
KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT);
- keymaster_error_t error;
- ::keymaster::CertificateChain attestation_chain =
- context.GetAttestationChain(KM_ALGORITHM_EC, &error);
- if (KM_ERROR_OK != error) {
- LOG(ERROR) << "Error getting attestation chain " << error;
- return {};
- }
- if (expireTimeMilliSeconds == 0) {
- if (attestation_chain.entry_count < 1) {
- LOG(ERROR) << "Expected at least one entry in attestation chain";
- return {};
- }
- keymaster_blob_t* bcBlob = &(attestation_chain.entries[0]);
- const uint8_t* bcData = bcBlob->data;
- auto bc = X509_Ptr(d2i_X509(nullptr, &bcData, bcBlob->data_length));
- time_t bcNotAfter;
- if (!parseAsn1Time(X509_get0_notAfter(bc.get()), &bcNotAfter)) {
- LOG(ERROR) << "Error getting notAfter from batch certificate";
- return {};
- }
- expireTimeMilliSeconds = bcNotAfter * 1000;
+ EVP_PKEY_Ptr pkey = generateP256Key();
+
+ uint64_t validFromMs = time(nullptr) * 1000;
+ optional<uint64_t> notAfterMs =
+ getCertificateExpiryAsMillis(attestationKeyCert.data(), attestationKeyCert.size());
+ if (!notAfterMs) {
+ LOG(ERROR) << "Error getting expiration time for attestation cert";
+ return std::nullopt;
}
- ::keymaster::X509_NAME_Ptr subjectName;
- if (KM_ERROR_OK !=
- ::keymaster::make_name_from_str("Android Identity Credential Key", &subjectName)) {
- LOG(ERROR) << "Cannot create attestation subject";
- return {};
+ optional<vector<uint8_t>> derIssuerSubject =
+ extractDerSubjectFromCertificate(attestationKeyCert);
+ if (!derIssuerSubject) {
+ LOG(ERROR) << "Error error extracting issuer name from the given certificate chain";
+ return std::nullopt;
}
- vector<uint8_t> subject(i2d_X509_NAME(subjectName.get(), NULL));
- unsigned char* subjectPtr = subject.data();
-
- i2d_X509_NAME(subjectName.get(), &subjectPtr);
-
- ::keymaster::AuthorizationSet auth_set(
- ::keymaster::AuthorizationSetBuilder()
- .Authorization(::keymaster::TAG_CERTIFICATE_NOT_BEFORE, activeTimeMilliSeconds)
- .Authorization(::keymaster::TAG_CERTIFICATE_NOT_AFTER, expireTimeMilliSeconds)
- .Authorization(::keymaster::TAG_ATTESTATION_CHALLENGE, challenge.data(),
- challenge.size())
- .Authorization(::keymaster::TAG_ACTIVE_DATETIME, activeTimeMilliSeconds)
- // Even though identity attestation hal said the application
- // id should be in software enforced authentication set,
- // keymaster portable lib expect the input in this
- // parameter because the software enforced in input to keymaster
- // refers to the key software enforced properties. And this
- // parameter refers to properties of the attestation which
- // includes app id.
- .Authorization(::keymaster::TAG_ATTESTATION_APPLICATION_ID,
- applicationId.data(), applicationId.size())
- .Authorization(::keymaster::TAG_CERTIFICATE_SUBJECT, subject.data(),
- subject.size())
- .Authorization(::keymaster::TAG_USAGE_EXPIRE_DATETIME, expireTimeMilliSeconds));
-
- // Unique id and device id is not applicable for identity credential attestation,
- // so we don't need to set those or application id.
- ::keymaster::AuthorizationSet swEnforced(::keymaster::AuthorizationSetBuilder().Authorization(
- ::keymaster::TAG_CREATION_DATETIME, activeTimeMilliSeconds));
-
- ::keymaster::AuthorizationSetBuilder hwEnforcedBuilder =
- ::keymaster::AuthorizationSetBuilder()
- .Authorization(::keymaster::TAG_PURPOSE, KM_PURPOSE_SIGN)
- .Authorization(::keymaster::TAG_KEY_SIZE, 256)
- .Authorization(::keymaster::TAG_ALGORITHM, KM_ALGORITHM_EC)
- .Authorization(::keymaster::TAG_NO_AUTH_REQUIRED)
- .Authorization(::keymaster::TAG_DIGEST, KM_DIGEST_SHA_2_256)
- .Authorization(::keymaster::TAG_EC_CURVE, KM_EC_CURVE_P_256)
- .Authorization(::keymaster::TAG_OS_VERSION, 42)
- .Authorization(::keymaster::TAG_OS_PATCHLEVEL, 43);
-
- // Only include TAG_IDENTITY_CREDENTIAL_KEY if it's not a test credential
- if (!isTestCredential) {
- hwEnforcedBuilder.Authorization(::keymaster::TAG_IDENTITY_CREDENTIAL_KEY);
+ optional<vector<vector<uint8_t>>> attestationCertChain = signAttestationCertificate(
+ context, pkey.get(), applicationId, challenge, attestationKeyBlob, *derIssuerSubject,
+ validFromMs, *notAfterMs, isTestCredential);
+ if (!attestationCertChain) {
+ LOG(ERROR) << "Error signing attestation certificate";
+ return std::nullopt;
}
- ::keymaster::AuthorizationSet hwEnforced(hwEnforcedBuilder);
-
- ::keymaster::CertificateChain cert_chain_out = generate_attestation(
- key, swEnforced, hwEnforced, auth_set, {} /* attest_key */, context, &error);
-
- if (KM_ERROR_OK != error) {
- LOG(ERROR) << "Error generating attestation from EVP key: " << error;
- return {};
- }
-
- // translate certificate format from keymaster_cert_chain_t to vector<vector<uint8_t>>.
- vector<vector<uint8_t>> attestationCertificate;
- for (std::size_t i = 0; i < cert_chain_out.entry_count; i++) {
- attestationCertificate.insert(
- attestationCertificate.end(),
- vector<uint8_t>(
- cert_chain_out.entries[i].data,
- cert_chain_out.entries[i].data + cert_chain_out.entries[i].data_length));
- }
-
- return attestationCertificate;
-}
-
-optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
- const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
- bool isTestCredential) {
- auto ec_key = ::keymaster::EC_KEY_Ptr(EC_KEY_new());
- auto pkey = ::keymaster::EVP_PKEY_Ptr(EVP_PKEY_new());
- auto group = ::keymaster::EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
-
- if (ec_key.get() == nullptr || pkey.get() == nullptr) {
- LOG(ERROR) << "Memory allocation failed";
- return {};
- }
-
- if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
- EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
- LOG(ERROR) << "Error generating key";
- return {};
- }
-
- if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
- LOG(ERROR) << "Error getting private key";
- return {};
- }
-
- uint64_t nowMs = time(nullptr) * 1000;
- uint64_t expireTimeMs = 0; // Set to same as batch certificate
-
- optional<vector<vector<uint8_t>>> attestationCert = createAttestation(
- pkey.get(), applicationId, challenge, nowMs, expireTimeMs, isTestCredential);
- if (!attestationCert) {
+ if (!attestationCertChain) {
LOG(ERROR) << "Error create attestation from key and challenge";
- return {};
+ return std::nullopt;
+ }
+ if (attestationCertChain->size() != 1) {
+ LOG(ERROR) << "Expected exactly one attestation cert, got " << attestationCertChain->size();
+ return std::nullopt;
}
- int size = i2d_PrivateKey(pkey.get(), nullptr);
- if (size == 0) {
- LOG(ERROR) << "Error generating public key encoding";
- return {};
+ optional<vector<uint8_t>> keyPair = derEncodeKeyPair(*pkey);
+ if (!keyPair) {
+ return std::nullopt;
}
- vector<uint8_t> keyPair(size);
- unsigned char* p = keyPair.data();
- i2d_PrivateKey(pkey.get(), &p);
-
- return make_pair(keyPair, attestationCert.value());
+ return make_pair(*keyPair, attestationCertChain->at(0));
}
optional<vector<vector<uint8_t>>> createAttestationForEcPublicKey(
@@ -820,12 +959,8 @@
return {};
}
- uint64_t nowMs = time(nullptr) * 1000;
- uint64_t expireTimeMs = 0; // Set to same as batch certificate
-
optional<vector<vector<uint8_t>>> attestationCert =
- createAttestation(pkey.get(), applicationId, challenge, nowMs, expireTimeMs,
- false /* isTestCredential */);
+ createAttestation(pkey.get(), applicationId, challenge, false /* isTestCredential */);
if (!attestationCert) {
LOG(ERROR) << "Error create attestation from key and challenge";
return {};
@@ -1134,6 +1269,14 @@
return {};
}
+ return ecPublicKeyGenerateCertificate(pkey.get(), privPkey.get(), serialDecimal, issuer,
+ subject, validityNotBefore, validityNotAfter, extensions);
+}
+
+optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
+ EVP_PKEY* publicKey, EVP_PKEY* signingKey, const string& serialDecimal,
+ const string& issuer, const string& subject, time_t validityNotBefore,
+ time_t validityNotAfter, const map<string, vector<uint8_t>>& extensions) {
auto x509 = X509_Ptr(X509_new());
if (!x509.get()) {
LOG(ERROR) << "Error creating X509 certificate";
@@ -1145,7 +1288,7 @@
return {};
}
- if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
+ if (X509_set_pubkey(x509.get(), publicKey) != 1) {
LOG(ERROR) << "Error setting public key";
return {};
}
@@ -1220,7 +1363,7 @@
}
}
- if (X509_sign(x509.get(), privPkey.get(), EVP_sha256()) == 0) {
+ if (X509_sign(x509.get(), signingKey, EVP_sha256()) == 0) {
LOG(ERROR) << "Error signing X509 certificate";
return {};
}
diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp
index eb28db7..9b897c4 100644
--- a/neuralnetworks/aidl/utils/src/Conversions.cpp
+++ b/neuralnetworks/aidl/utils/src/Conversions.cpp
@@ -967,6 +967,11 @@
}
nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model) {
+ if (!hal::utils::hasNoPointerData(model)) {
+ return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
+ << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
+ }
+
return Model{
.main = NN_TRY(unvalidatedConvert(model.main)),
.referenced = NN_TRY(unvalidatedConvert(model.referenced)),
@@ -982,6 +987,11 @@
}
nn::GeneralResult<Request> unvalidatedConvert(const nn::Request& request) {
+ if (!hal::utils::hasNoPointerData(request)) {
+ return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
+ << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
+ }
+
return Request{
.inputs = NN_TRY(unvalidatedConvert(request.inputs)),
.outputs = NN_TRY(unvalidatedConvert(request.outputs)),
diff --git a/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h
index ae0d092..c04294a 100644
--- a/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h
+++ b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h
@@ -20,6 +20,7 @@
#include <nnapi/Result.h>
#include <nnapi/SharedMemory.h>
#include <nnapi/Types.h>
+
#include <functional>
#include <vector>
@@ -47,81 +48,10 @@
const nn::Capabilities::PerformanceInfo& float32Performance,
const nn::Capabilities::PerformanceInfo& quantized8Performance);
-// Indicates if the object contains no pointer-based data that could be relocated to shared memory.
-bool hasNoPointerData(const nn::Model& model);
-bool hasNoPointerData(const nn::Request& request);
-
-// Relocate pointer-based data to shared memory. If `model` has no Operand::LifeTime::POINTER data,
-// the function returns with a reference to `model`. If `model` has Operand::LifeTime::POINTER data,
-// the model is copied to `maybeModelInSharedOut` with the POINTER data relocated to a memory pool,
-// and the function returns with a reference to `*maybeModelInSharedOut`.
-nn::GeneralResult<std::reference_wrapper<const nn::Model>> flushDataFromPointerToShared(
- const nn::Model* model, std::optional<nn::Model>* maybeModelInSharedOut);
-
-// Record a relocation mapping between pointer-based data and shared memory.
-// Only two specializations of this template may exist:
-// - RelocationInfo<const void*> for request inputs
-// - RelocationInfo<void*> for request outputs
-template <typename PointerType>
-struct RelocationInfo {
- PointerType data;
- size_t length;
- size_t offset;
-};
-using InputRelocationInfo = RelocationInfo<const void*>;
-using OutputRelocationInfo = RelocationInfo<void*>;
-
-// Keep track of the relocation mapping between pointer-based data and shared memory pool,
-// and provide method to copy the data between pointers and the shared memory pool.
-// Only two specializations of this template may exist:
-// - RelocationTracker<InputRelocationInfo> for request inputs
-// - RelocationTracker<OutputRelocationInfo> for request outputs
-template <typename RelocationInfoType>
-class RelocationTracker {
- public:
- static nn::GeneralResult<std::unique_ptr<RelocationTracker>> create(
- std::vector<RelocationInfoType> relocationInfos, nn::SharedMemory memory) {
- auto mapping = NN_TRY(map(memory));
- return std::make_unique<RelocationTracker<RelocationInfoType>>(
- std::move(relocationInfos), std::move(memory), std::move(mapping));
- }
-
- RelocationTracker(std::vector<RelocationInfoType> relocationInfos, nn::SharedMemory memory,
- nn::Mapping mapping)
- : kRelocationInfos(std::move(relocationInfos)),
- kMemory(std::move(memory)),
- kMapping(std::move(mapping)) {}
-
- // Specializations defined in CommonUtils.cpp.
- // For InputRelocationTracker, this method will copy pointer data to the shared memory pool.
- // For OutputRelocationTracker, this method will copy shared memory data to the pointers.
- void flush() const;
-
- private:
- const std::vector<RelocationInfoType> kRelocationInfos;
- const nn::SharedMemory kMemory;
- const nn::Mapping kMapping;
-};
-using InputRelocationTracker = RelocationTracker<InputRelocationInfo>;
-using OutputRelocationTracker = RelocationTracker<OutputRelocationInfo>;
-
-struct RequestRelocation {
- std::unique_ptr<InputRelocationTracker> input;
- std::unique_ptr<OutputRelocationTracker> output;
-};
-
-// Relocate pointer-based data to shared memory. If `request` has no
-// Request::Argument::LifeTime::POINTER data, the function returns with a reference to `request`. If
-// `request` has Request::Argument::LifeTime::POINTER data, the request is copied to
-// `maybeRequestInSharedOut` with the POINTER data relocated to a memory pool, and the function
-// returns with a reference to `*maybeRequestInSharedOut`. The `relocationOut` will be set to track
-// the input and output relocations.
-//
-// Unlike `flushDataFromPointerToShared`, this method will not copy the input pointer data to the
-// shared memory pool. Use `relocationOut` to flush the input or output data after the call.
-nn::GeneralResult<std::reference_wrapper<const nn::Request>> convertRequestFromPointerToShared(
- const nn::Request* request, uint32_t alignment, uint32_t padding,
- std::optional<nn::Request>* maybeRequestInSharedOut, RequestRelocation* relocationOut);
+using nn::convertRequestFromPointerToShared;
+using nn::flushDataFromPointerToShared;
+using nn::hasNoPointerData;
+using nn::RequestRelocation;
} // namespace android::hardware::neuralnetworks::utils
diff --git a/neuralnetworks/utils/common/src/CommonUtils.cpp b/neuralnetworks/utils/common/src/CommonUtils.cpp
index b249881..dd55add 100644
--- a/neuralnetworks/utils/common/src/CommonUtils.cpp
+++ b/neuralnetworks/utils/common/src/CommonUtils.cpp
@@ -31,59 +31,6 @@
#include <vector>
namespace android::hardware::neuralnetworks::utils {
-namespace {
-
-bool hasNoPointerData(const nn::Operand& operand);
-bool hasNoPointerData(const nn::Model::Subgraph& subgraph);
-bool hasNoPointerData(const nn::Request::Argument& argument);
-
-template <typename Type>
-bool hasNoPointerData(const std::vector<Type>& objects) {
- return std::all_of(objects.begin(), objects.end(),
- [](const auto& object) { return hasNoPointerData(object); });
-}
-
-bool hasNoPointerData(const nn::DataLocation& location) {
- return std::visit([](auto ptr) { return ptr == nullptr; }, location.pointer);
-}
-
-bool hasNoPointerData(const nn::Operand& operand) {
- return hasNoPointerData(operand.location);
-}
-
-bool hasNoPointerData(const nn::Model::Subgraph& subgraph) {
- return hasNoPointerData(subgraph.operands);
-}
-
-bool hasNoPointerData(const nn::Request::Argument& argument) {
- return hasNoPointerData(argument.location);
-}
-
-void copyPointersToSharedMemory(nn::Operand* operand, nn::ConstantMemoryBuilder* memoryBuilder) {
- CHECK(operand != nullptr);
- CHECK(memoryBuilder != nullptr);
-
- if (operand->lifetime != nn::Operand::LifeTime::POINTER) {
- return;
- }
-
- const void* data = std::visit([](auto ptr) { return static_cast<const void*>(ptr); },
- operand->location.pointer);
- CHECK(data != nullptr);
- operand->lifetime = nn::Operand::LifeTime::CONSTANT_REFERENCE;
- operand->location = memoryBuilder->append(data, operand->location.length);
-}
-
-void copyPointersToSharedMemory(nn::Model::Subgraph* subgraph,
- nn::ConstantMemoryBuilder* memoryBuilder) {
- CHECK(subgraph != nullptr);
- std::for_each(subgraph->operands.begin(), subgraph->operands.end(),
- [memoryBuilder](auto& operand) {
- copyPointersToSharedMemory(&operand, memoryBuilder);
- });
-}
-
-} // anonymous namespace
nn::Capabilities::OperandPerformanceTable makeQuantized8PerformanceConsistentWithP(
const nn::Capabilities::PerformanceInfo& float32Performance,
@@ -104,131 +51,4 @@
.value();
}
-bool hasNoPointerData(const nn::Model& model) {
- return hasNoPointerData(model.main) && hasNoPointerData(model.referenced);
-}
-
-bool hasNoPointerData(const nn::Request& request) {
- return hasNoPointerData(request.inputs) && hasNoPointerData(request.outputs);
-}
-
-nn::GeneralResult<std::reference_wrapper<const nn::Model>> flushDataFromPointerToShared(
- const nn::Model* model, std::optional<nn::Model>* maybeModelInSharedOut) {
- CHECK(model != nullptr);
- CHECK(maybeModelInSharedOut != nullptr);
-
- if (hasNoPointerData(*model)) {
- return *model;
- }
-
- // Make a copy of the model in order to make modifications. The modified model is returned to
- // the caller through `maybeModelInSharedOut` if the function succeeds.
- nn::Model modelInShared = *model;
-
- nn::ConstantMemoryBuilder memoryBuilder(modelInShared.pools.size());
- copyPointersToSharedMemory(&modelInShared.main, &memoryBuilder);
- std::for_each(modelInShared.referenced.begin(), modelInShared.referenced.end(),
- [&memoryBuilder](auto& subgraph) {
- copyPointersToSharedMemory(&subgraph, &memoryBuilder);
- });
-
- if (!memoryBuilder.empty()) {
- auto memory = NN_TRY(memoryBuilder.finish());
- modelInShared.pools.push_back(std::move(memory));
- }
-
- *maybeModelInSharedOut = modelInShared;
- return **maybeModelInSharedOut;
-}
-
-template <>
-void InputRelocationTracker::flush() const {
- // Copy from pointers to shared memory.
- uint8_t* memoryPtr = static_cast<uint8_t*>(std::get<void*>(kMapping.pointer));
- for (const auto& [data, length, offset] : kRelocationInfos) {
- std::memcpy(memoryPtr + offset, data, length);
- }
-}
-
-template <>
-void OutputRelocationTracker::flush() const {
- // Copy from shared memory to pointers.
- const uint8_t* memoryPtr = static_cast<const uint8_t*>(
- std::visit([](auto ptr) { return static_cast<const void*>(ptr); }, kMapping.pointer));
- for (const auto& [data, length, offset] : kRelocationInfos) {
- std::memcpy(data, memoryPtr + offset, length);
- }
-}
-
-nn::GeneralResult<std::reference_wrapper<const nn::Request>> convertRequestFromPointerToShared(
- const nn::Request* request, uint32_t alignment, uint32_t padding,
- std::optional<nn::Request>* maybeRequestInSharedOut, RequestRelocation* relocationOut) {
- CHECK(request != nullptr);
- CHECK(maybeRequestInSharedOut != nullptr);
- CHECK(relocationOut != nullptr);
-
- if (hasNoPointerData(*request)) {
- return *request;
- }
-
- // Make a copy of the request in order to make modifications. The modified request is returned
- // to the caller through `maybeRequestInSharedOut` if the function succeeds.
- nn::Request requestInShared = *request;
-
- RequestRelocation relocation;
-
- // Change input pointers to shared memory.
- nn::MutableMemoryBuilder inputBuilder(requestInShared.pools.size());
- std::vector<InputRelocationInfo> inputRelocationInfos;
- for (auto& input : requestInShared.inputs) {
- const auto& location = input.location;
- if (input.lifetime != nn::Request::Argument::LifeTime::POINTER) {
- continue;
- }
-
- input.lifetime = nn::Request::Argument::LifeTime::POOL;
- const void* data = std::visit([](auto ptr) { return static_cast<const void*>(ptr); },
- location.pointer);
- CHECK(data != nullptr);
- input.location = inputBuilder.append(location.length, alignment, padding);
- inputRelocationInfos.push_back({data, input.location.length, input.location.offset});
- }
-
- // Allocate input memory.
- if (!inputBuilder.empty()) {
- auto memory = NN_TRY(inputBuilder.finish());
- requestInShared.pools.push_back(memory);
- relocation.input = NN_TRY(
- InputRelocationTracker::create(std::move(inputRelocationInfos), std::move(memory)));
- }
-
- // Change output pointers to shared memory.
- nn::MutableMemoryBuilder outputBuilder(requestInShared.pools.size());
- std::vector<OutputRelocationInfo> outputRelocationInfos;
- for (auto& output : requestInShared.outputs) {
- const auto& location = output.location;
- if (output.lifetime != nn::Request::Argument::LifeTime::POINTER) {
- continue;
- }
-
- output.lifetime = nn::Request::Argument::LifeTime::POOL;
- void* data = std::get<void*>(location.pointer);
- CHECK(data != nullptr);
- output.location = outputBuilder.append(location.length, alignment, padding);
- outputRelocationInfos.push_back({data, output.location.length, output.location.offset});
- }
-
- // Allocate output memory.
- if (!outputBuilder.empty()) {
- auto memory = NN_TRY(outputBuilder.finish());
- requestInShared.pools.push_back(memory);
- relocation.output = NN_TRY(OutputRelocationTracker::create(std::move(outputRelocationInfos),
- std::move(memory)));
- }
-
- *maybeRequestInSharedOut = requestInShared;
- *relocationOut = std::move(relocation);
- return **maybeRequestInSharedOut;
-}
-
} // namespace android::hardware::neuralnetworks::utils
diff --git a/nfc/aidl/Android.bp b/nfc/aidl/Android.bp
index d390c7e..30365f6 100644
--- a/nfc/aidl/Android.bp
+++ b/nfc/aidl/Android.bp
@@ -12,6 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
aidl_interface {
name: "android.hardware.nfc",
vendor_available: true,
diff --git a/nfc/aidl/default/Android.bp b/nfc/aidl/default/Android.bp
index 907d23d..6daebe5 100644
--- a/nfc/aidl/default/Android.bp
+++ b/nfc/aidl/default/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
cc_binary {
name: "android.hardware.nfc-service.example",
relative_install_path: "hw",
diff --git a/radio/1.0/Android.bp b/radio/1.0/Android.bp
index cd64bca..8d0d782 100644
--- a/radio/1.0/Android.bp
+++ b/radio/1.0/Android.bp
@@ -23,5 +23,9 @@
interfaces: [
"android.hidl.base@1.0",
],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.bluetooth",
+ ],
gen_java: true,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
index c8efea0..02bbf21 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
@@ -53,7 +53,7 @@
boolean preferred;
boolean persistent;
boolean alwaysOn;
- @nullable android.hardware.radio.data.TrafficDescriptor trafficDescriptor;
+ android.hardware.radio.data.TrafficDescriptor trafficDescriptor;
const int ID_DEFAULT = 0;
const int ID_TETHERED = 1;
const int ID_IMS = 2;
@@ -62,6 +62,6 @@
const int ID_OEM_BASE = 1000;
const int ID_INVALID = -1;
const int TYPE_COMMON = 0;
- const int TYPE_THREE_GPP = 1;
- const int TYPE_THREE_GPP2 = 2;
+ const int TYPE_3GPP = 1;
+ const int TYPE_3GPP2 = 2;
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl
index dc6092a..7b572f1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl
@@ -44,7 +44,7 @@
oneway void setDataAllowed(in int serial, in boolean allow);
oneway void setDataProfile(in int serial, in android.hardware.radio.data.DataProfileInfo[] profiles);
oneway void setDataThrottling(in int serial, in android.hardware.radio.data.DataThrottlingAction dataThrottlingAction, in long completionDurationMillis);
- oneway void setInitialAttachApn(in int serial, in android.hardware.radio.data.DataProfileInfo dataProfileInfo);
+ oneway void setInitialAttachApn(in int serial, in @nullable android.hardware.radio.data.DataProfileInfo dataProfileInfo);
oneway void setResponseFunctions(in android.hardware.radio.data.IRadioDataResponse radioDataResponse, in android.hardware.radio.data.IRadioDataIndication radioDataIndication);
oneway void setupDataCall(in int serial, in android.hardware.radio.AccessNetwork accessNetwork, in android.hardware.radio.data.DataProfileInfo dataProfileInfo, in boolean roamingAllowed, in android.hardware.radio.data.DataRequestReason reason, in android.hardware.radio.data.LinkAddress[] addresses, in String[] dnses, in int pduSessionId, in @nullable android.hardware.radio.data.SliceInfo sliceInfo, in boolean matchAllRuleAllowed);
oneway void startHandover(in int serial, in int callId);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl
index b0fc349..dfec59a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl
@@ -37,7 +37,6 @@
oneway void acknowledgeIncomingGsmSmsWithPdu(in int serial, in boolean success, in String ackPdu);
oneway void acknowledgeLastIncomingCdmaSms(in int serial, in android.hardware.radio.messaging.CdmaSmsAck smsAck);
oneway void acknowledgeLastIncomingGsmSms(in int serial, in boolean success, in android.hardware.radio.messaging.SmsAcknowledgeFailCause cause);
- oneway void cancelPendingUssd(in int serial);
oneway void deleteSmsOnRuim(in int serial, in int index);
oneway void deleteSmsOnSim(in int serial, in int index);
oneway void getCdmaBroadcastConfig(in int serial);
@@ -50,7 +49,6 @@
oneway void sendImsSms(in int serial, in android.hardware.radio.messaging.ImsSmsMessage message);
oneway void sendSms(in int serial, in android.hardware.radio.messaging.GsmSmsMessage message);
oneway void sendSmsExpectMore(in int serial, in android.hardware.radio.messaging.GsmSmsMessage message);
- oneway void sendUssd(in int serial, in String ussd);
oneway void setCdmaBroadcastActivation(in int serial, in boolean activate);
oneway void setCdmaBroadcastConfig(in int serial, in android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[] configInfo);
oneway void setGsmBroadcastActivation(in int serial, in boolean activate);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
index 89a0f3b..8f7824f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
@@ -40,6 +40,5 @@
oneway void newSms(in android.hardware.radio.RadioIndicationType type, in byte[] pdu);
oneway void newSmsOnSim(in android.hardware.radio.RadioIndicationType type, in int recordNumber);
oneway void newSmsStatusReport(in android.hardware.radio.RadioIndicationType type, in byte[] pdu);
- oneway void onUssd(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.messaging.UssdModeType modeType, in String msg);
oneway void simSmsStorageFull(in android.hardware.radio.RadioIndicationType type);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
index 156f24b..c3af7a6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
@@ -38,7 +38,6 @@
oneway void acknowledgeLastIncomingCdmaSmsResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void acknowledgeLastIncomingGsmSmsResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void acknowledgeRequest(in int serial);
- oneway void cancelPendingUssdResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void deleteSmsOnRuimResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void deleteSmsOnSimResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void getCdmaBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[] configs);
@@ -50,7 +49,6 @@
oneway void sendImsSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
oneway void sendSmsExpectMoreResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
oneway void sendSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
- oneway void sendUssdResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void setCdmaBroadcastActivationResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void setCdmaBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void setGsmBroadcastActivationResponse(in android.hardware.radio.RadioResponseInfo info);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
index ef9c779..85cf86e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -36,6 +36,5 @@
parcelable CarrierRestrictions {
android.hardware.radio.sim.Carrier[] allowedCarriers;
android.hardware.radio.sim.Carrier[] excludedCarriers;
- boolean priority;
boolean allowedCarriersPrioritized;
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
index 34d155a..603b1d6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
@@ -35,6 +35,7 @@
@VintfStability
interface IRadioVoice {
oneway void acceptCall(in int serial);
+ oneway void cancelPendingUssd(in int serial);
oneway void conference(in int serial);
oneway void dial(in int serial, in android.hardware.radio.voice.Dial dialInfo);
oneway void emergencyDial(in int serial, in android.hardware.radio.voice.Dial dialInfo, in int categories, in String[] urns, in android.hardware.radio.voice.EmergencyCallRouting routing, in boolean hasKnownUserIntentEmergency, in boolean isTesting);
@@ -59,6 +60,7 @@
oneway void sendBurstDtmf(in int serial, in String dtmf, in int on, in int off);
oneway void sendCdmaFeatureCode(in int serial, in String featureCode);
oneway void sendDtmf(in int serial, in String s);
+ oneway void sendUssd(in int serial, in String ussd);
oneway void separateConnection(in int serial, in int gsmIndex);
oneway void setCallForward(in int serial, in android.hardware.radio.voice.CallForwardInfo callInfo);
oneway void setCallWaiting(in int serial, in boolean enable, in int serviceClass);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl
index af3417d..189ed43 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl
@@ -44,6 +44,7 @@
oneway void exitEmergencyCallbackMode(in android.hardware.radio.RadioIndicationType type);
oneway void indicateRingbackTone(in android.hardware.radio.RadioIndicationType type, in boolean start);
oneway void onSupplementaryServiceIndication(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.StkCcUnsolSsResult ss);
+ oneway void onUssd(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.UssdModeType modeType, in String msg);
oneway void resendIncallMute(in android.hardware.radio.RadioIndicationType type);
oneway void srvccStateNotify(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.SrvccState state);
oneway void stkCallControlAlphaNotify(in android.hardware.radio.RadioIndicationType type, in String alpha);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl
index a3b5e58..7acc044 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl
@@ -36,6 +36,7 @@
interface IRadioVoiceResponse {
oneway void acceptCallResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void acknowledgeRequest(in int serial);
+ oneway void cancelPendingUssdResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void conferenceResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void dialResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void emergencyDialResponse(in android.hardware.radio.RadioResponseInfo info);
@@ -59,6 +60,7 @@
oneway void sendBurstDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void sendCdmaFeatureCodeResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void sendDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void sendUssdResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void separateConnectionResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void setCallForwardResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void setCallWaitingResponse(in android.hardware.radio.RadioResponseInfo info);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/UssdModeType.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
similarity index 97%
rename from radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/UssdModeType.aidl
rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
index 5395b11..9a9d723 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/UssdModeType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
@@ -31,7 +31,7 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.radio.messaging;
+package android.hardware.radio.voice;
@Backing(type="int") @VintfStability
enum UssdModeType {
NOTIFY = 0,
diff --git a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
index 7360202..123b3ed 100644
--- a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
@@ -16,9 +16,7 @@
package android.hardware.radio.data;
-import android.hardware.radio.RadioAccessFamily;
import android.hardware.radio.data.ApnAuthType;
-import android.hardware.radio.data.ApnTypes;
import android.hardware.radio.data.PdpProtocolType;
import android.hardware.radio.data.TrafficDescriptor;
@@ -36,8 +34,8 @@
const int ID_INVALID = 0xFFFFFFFF;
const int TYPE_COMMON = 0;
- const int TYPE_THREE_GPP = 1;
- const int TYPE_THREE_GPP2 = 2;
+ const int TYPE_3GPP = 1;
+ const int TYPE_3GPP2 = 2;
/**
* ID of the data profile.
@@ -130,5 +128,5 @@
* it does not specify the end point to be used for the data call. The end point is specified by
* apn; apn must be used as the end point if one is not specified through URSP rules.
*/
- @nullable TrafficDescriptor trafficDescriptor;
+ TrafficDescriptor trafficDescriptor;
}
diff --git a/radio/aidl/android/hardware/radio/data/IRadioData.aidl b/radio/aidl/android/hardware/radio/data/IRadioData.aidl
index 54a045c..e1ba568 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioData.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioData.aidl
@@ -159,14 +159,15 @@
in long completionDurationMillis);
/**
- * Set an APN to initial attach network.
+ * Set an APN to initial attach network or clear the existing initial attach APN.
*
* @param serial Serial number of request.
- * @param dataProfileInfo data profile containing APN settings
+ * @param dataProfileInfo Data profile containing APN settings or null to clear the existing
+ * initial attach APN.
*
* Response function is IRadioDataResponse.setInitialAttachApnResponse()
*/
- void setInitialAttachApn(in int serial, in DataProfileInfo dataProfileInfo);
+ void setInitialAttachApn(in int serial, in @nullable DataProfileInfo dataProfileInfo);
/**
* Set response functions for data radio requests and indications.
diff --git a/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl b/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl
index 1dbaed3..8bd84a3 100644
--- a/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl
@@ -79,15 +79,6 @@
in int serial, in boolean success, in SmsAcknowledgeFailCause cause);
/**
- * Cancel the current USSD session if one exists.
- *
- * @param serial Serial number of request.
- *
- * Response function is IRadioMessagingResponse.cancelPendingUssdResponse()
- */
- void cancelPendingUssd(in int serial);
-
- /**
* Deletes a CDMA SMS message from RUIM memory.
*
* @param serial Serial number of request.
@@ -212,23 +203,6 @@
void sendSmsExpectMore(in int serial, in GsmSmsMessage message);
/**
- * Send a USSD message. If a USSD session already exists, the message must be sent in the
- * context of that session. Otherwise, a new session must be created. The network reply must be
- * reported via unsolOnUssd.
- *
- * Only one USSD session must exist at a time, and the session is assumed to exist until:
- * a) The android system invokes cancelUssd()
- * b) The implementation sends a unsolOnUssd() with a type code of
- * "0" (USSD-Notify/no further action) or "2" (session terminated)
- *
- * @param serial Serial number of request.
- * @param ussd string containing the USSD request in UTF-8 format
- *
- * Response function is IRadioMessagingResponse.sendUssdResponse()
- */
- void sendUssd(in int serial, in String ussd);
-
- /**
* Enable or disable the reception of CDMA Cell Broadcast SMS
*
* @param serial Serial number of request.
diff --git a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
index 4b40bfb..8834cd9 100644
--- a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
@@ -18,7 +18,6 @@
import android.hardware.radio.RadioIndicationType;
import android.hardware.radio.messaging.CdmaSmsMessage;
-import android.hardware.radio.messaging.UssdModeType;
/**
* Interface declaring unsolicited radio indications for messaging APIs.
@@ -86,16 +85,6 @@
void newSmsStatusReport(in RadioIndicationType type, in byte[] pdu);
/**
- * Indicates when a new USSD message is received. The USSD session is assumed to persist if the
- * type code is REQUEST, otherwise the current session (if any) is assumed to have terminated.
- *
- * @param type Type of radio indication
- * @param modeType USSD type code
- * @param msg Message string in UTF-8, if applicable
- */
- void onUssd(in RadioIndicationType type, in UssdModeType modeType, in String msg);
-
- /**
* Indicates that SMS storage on the SIM is full. Sent when the network attempts to deliver a
* new SMS message. Messages cannot be saved on the SIM until space is freed. In particular,
* incoming Class 2 messages must not be stored.
diff --git a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
index 75fa390..492755f 100644
--- a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
@@ -92,27 +92,6 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:SIM_BUSY
- * RadioError:OPERATION_NOT_ALLOWED
- * RadioError:MODEM_ERR
- * RadioError:INTERNAL_ERR
- * RadioError:NO_MEMORY
- * RadioError:INVALID_STATE
- * RadioError:INVALID_ARGUMENTS
- * RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
- * RadioError:INVALID_MODEM_STATE
- * RadioError:NO_RESOURCES
- * RadioError:CANCELLED
- */
- void cancelPendingUssdResponse(in RadioResponseInfo info);
-
- /**
- * @param info Response info struct containing response type, serial no. and error
- *
- * Valid errors returned:
- * RadioError:NONE
- * RadioError:RADIO_NOT_AVAILABLE
* RadioError:INVALID_ARGUMENTS
* RadioError:NO_MEMORY
* RadioError:SYSTEM_ERR
@@ -407,32 +386,6 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:FDN_CHECK_FAILURE
- * RadioError:USSD_MODIFIED_TO_DIAL
- * RadioError:USSD_MODIFIED_TO_SS
- * RadioError:USSD_MODIFIED_TO_USSD
- * RadioError:SIM_BUSY
- * RadioError:OPERATION_NOT_ALLOWED
- * RadioError:INVALID_ARGUMENTS
- * RadioError:NO_MEMORY
- * RadioError:MODEM_ERR
- * RadioError:INTERNAL_ERR
- * RadioError:ABORTED
- * RadioError:SYSTEM_ERR
- * RadioError:INVALID_STATE
- * RadioError:REQUEST_NOT_SUPPORTED
- * RadioError:INVALID_MODEM_STATE
- * RadioError:NO_RESOURCES
- * RadioError:CANCELLED
- */
- void sendUssdResponse(in RadioResponseInfo info);
-
- /**
- * @param info Response info struct containing response type, serial no. and error
- *
- * Valid errors returned:
- * RadioError:NONE
- * RadioError:RADIO_NOT_AVAILABLE
* RadioError:INVALID_ARGUMENTS
* RadioError:INVALID_STATE
* RadioError:NO_MEMORY
diff --git a/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl b/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
index 9bd5f21..96b9d0d 100644
--- a/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
+++ b/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
@@ -16,8 +16,6 @@
package android.hardware.radio.modem;
-import android.hardware.radio.RadioAccessFamily;
-
@VintfStability
parcelable RadioCapability {
/**
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index 7a22a9a..cce52ff 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -17,7 +17,6 @@
package android.hardware.radio.network;
import android.hardware.radio.AccessNetwork;
-import android.hardware.radio.RadioAccessFamily;
import android.hardware.radio.network.CdmaRoamingType;
import android.hardware.radio.network.IRadioNetworkIndication;
import android.hardware.radio.network.IRadioNetworkResponse;
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
index 6863ac3..f471433 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -21,7 +21,6 @@
import android.hardware.radio.network.BarringInfo;
import android.hardware.radio.network.CellIdentity;
import android.hardware.radio.network.CellInfo;
-import android.hardware.radio.network.Domain;
import android.hardware.radio.network.LinkCapacityEstimate;
import android.hardware.radio.network.NetworkScanResult;
import android.hardware.radio.network.PhoneRestrictedState;
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
index e650321..dcf0004 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -16,7 +16,6 @@
package android.hardware.radio.network;
-import android.hardware.radio.RadioAccessFamily;
import android.hardware.radio.RadioResponseInfo;
import android.hardware.radio.RadioTechnology;
import android.hardware.radio.RadioTechnologyFamily;
@@ -24,8 +23,6 @@
import android.hardware.radio.network.CdmaRoamingType;
import android.hardware.radio.network.CellIdentity;
import android.hardware.radio.network.CellInfo;
-import android.hardware.radio.network.LceDataInfo;
-import android.hardware.radio.network.NeighboringCell;
import android.hardware.radio.network.OperatorInfo;
import android.hardware.radio.network.RadioAccessSpecifier;
import android.hardware.radio.network.RadioBandMode;
diff --git a/radio/aidl/android/hardware/radio/network/NeighboringCell.aidl b/radio/aidl/android/hardware/radio/network/NeighboringCell.aidl
deleted file mode 100644
index 270bdee..0000000
--- a/radio/aidl/android/hardware/radio/network/NeighboringCell.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.radio.network;
-
-@VintfStability
-parcelable NeighboringCell {
- /**
- * Combination of LAC and cell ID in 32 bits in GSM. Upper 16 bits is LAC and lower 16 bits is
- * CID (as described in TS 27.005).
- */
- String cid;
- /**
- * Received RSSI in GSM, level index of CPICH Received Signal Code Power in UMTS
- */
- int rssi;
-}
diff --git a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
index 12df138..ef38fdc 100644
--- a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -31,11 +31,6 @@
*/
Carrier[] excludedCarriers;
/**
- * Whether this is a carrier restriction with priority or not.
- * If this is false, allowedCarriersPrioritized is not applicable.
- */
- boolean priority;
- /**
* True means that only carriers included in the allowed list and not in the excluded list
* are permitted. Eg. allowedCarriers match mcc/mnc, excludedCarriers has same mcc/mnc and
* gid1 is ABCD. It means except the carrier whose gid1 is ABCD, all carriers with the
diff --git a/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl b/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
index ddc5d76..9fed78e 100644
--- a/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
+++ b/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
@@ -16,8 +16,6 @@
package android.hardware.radio.voice;
-import android.hardware.radio.voice.EmergencyServiceCategory;
-
/**
* Emergency number contains information of number, one or more service category(s), zero or more
* emergency uniform resource names, mobile country code (mcc), mobile network country (mnc) and
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
index b25e63d..c05d237 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
@@ -19,7 +19,6 @@
import android.hardware.radio.voice.CallForwardInfo;
import android.hardware.radio.voice.Dial;
import android.hardware.radio.voice.EmergencyCallRouting;
-import android.hardware.radio.voice.EmergencyServiceCategory;
import android.hardware.radio.voice.IRadioVoiceIndication;
import android.hardware.radio.voice.IRadioVoiceResponse;
import android.hardware.radio.voice.TtyMode;
@@ -45,6 +44,15 @@
void acceptCall(in int serial);
/**
+ * Cancel the current USSD session if one exists.
+ *
+ * @param serial Serial number of request.
+ *
+ * Response function is IRadioVoiceResponse.cancelPendingUssdResponse()
+ */
+ void cancelPendingUssd(in int serial);
+
+ /**
* Conference holding and active (like AT+CHLD=3)
*
* @param serial Serial number of request.
@@ -325,6 +333,23 @@
void sendDtmf(in int serial, in String s);
/**
+ * Send a USSD message. If a USSD session already exists, the message must be sent in the
+ * context of that session. Otherwise, a new session must be created. The network reply must be
+ * reported via unsolOnUssd.
+ *
+ * Only one USSD session must exist at a time, and the session is assumed to exist until:
+ * a) The android system invokes cancelUssd()
+ * b) The implementation sends a unsolOnUssd() with a type code of
+ * "0" (USSD-Notify/no further action) or "2" (session terminated)
+ *
+ * @param serial Serial number of request.
+ * @param ussd string containing the USSD request in UTF-8 format
+ *
+ * Response function is IRadioVoiceResponse.sendUssdResponse()
+ */
+ void sendUssd(in int serial, in String ussd);
+
+ /**
* Separate a party from a multiparty call placing the multiparty call (less the specified
* party) on hold and leaving the specified party as the only other member of the current
* (active) call. Like AT+CHLD=2x.
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
index 25e87b3..437fef6 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
@@ -24,6 +24,7 @@
import android.hardware.radio.voice.EmergencyNumber;
import android.hardware.radio.voice.SrvccState;
import android.hardware.radio.voice.StkCcUnsolSsResult;
+import android.hardware.radio.voice.UssdModeType;
/**
* Interface declaring unsolicited radio indications for voice APIs.
@@ -138,6 +139,16 @@
void onSupplementaryServiceIndication(in RadioIndicationType type, in StkCcUnsolSsResult ss);
/**
+ * Indicates when a new USSD message is received. The USSD session is assumed to persist if the
+ * type code is REQUEST, otherwise the current session (if any) is assumed to have terminated.
+ *
+ * @param type Type of radio indication
+ * @param modeType USSD type code
+ * @param msg Message string in UTF-8, if applicable
+ */
+ void onUssd(in RadioIndicationType type, in UssdModeType modeType, in String msg);
+
+ /**
* Indicates that framework/application must reset the uplink mute state.
*
* @param type Type of radio indication
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
index d126fc1..cf1b953 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
@@ -62,6 +62,27 @@
*
* Valid errors returned:
* RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:SIM_BUSY
+ * RadioError:OPERATION_NOT_ALLOWED
+ * RadioError:MODEM_ERR
+ * RadioError:INTERNAL_ERR
+ * RadioError:NO_MEMORY
+ * RadioError:INVALID_STATE
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:SYSTEM_ERR
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:INVALID_MODEM_STATE
+ * RadioError:NO_RESOURCES
+ * RadioError:CANCELLED
+ */
+ void cancelPendingUssdResponse(in RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE (radio resetting)
* RadioError:NO_MEMORY
* RadioError:MODEM_ERR
@@ -569,6 +590,32 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:FDN_CHECK_FAILURE
+ * RadioError:USSD_MODIFIED_TO_DIAL
+ * RadioError:USSD_MODIFIED_TO_SS
+ * RadioError:USSD_MODIFIED_TO_USSD
+ * RadioError:SIM_BUSY
+ * RadioError:OPERATION_NOT_ALLOWED
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:NO_MEMORY
+ * RadioError:MODEM_ERR
+ * RadioError:INTERNAL_ERR
+ * RadioError:ABORTED
+ * RadioError:SYSTEM_ERR
+ * RadioError:INVALID_STATE
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:INVALID_MODEM_STATE
+ * RadioError:NO_RESOURCES
+ * RadioError:CANCELLED
+ */
+ void sendUssdResponse(in RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
* RadioError:INVALID_ARGUMENTS
* RadioError:INVALID_STATE
* RadioError:NO_RESOURCES
diff --git a/radio/aidl/android/hardware/radio/messaging/UssdModeType.aidl b/radio/aidl/android/hardware/radio/voice/UssdModeType.aidl
similarity index 95%
rename from radio/aidl/android/hardware/radio/messaging/UssdModeType.aidl
rename to radio/aidl/android/hardware/radio/voice/UssdModeType.aidl
index c3c111e..48d1fca 100644
--- a/radio/aidl/android/hardware/radio/messaging/UssdModeType.aidl
+++ b/radio/aidl/android/hardware/radio/voice/UssdModeType.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.radio.messaging;
+package android.hardware.radio.voice;
@VintfStability
@Backing(type="int")
diff --git a/radio/aidl/compat/libradiocompat/data/RadioData.cpp b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
index d2f3687..51f5543 100644
--- a/radio/aidl/compat/libradiocompat/data/RadioData.cpp
+++ b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
@@ -122,9 +122,10 @@
return ok();
}
-ScopedAStatus RadioData::setInitialAttachApn(int32_t serial, const aidl::DataProfileInfo& info) {
+ScopedAStatus RadioData::setInitialAttachApn(int32_t serial,
+ const std::optional<aidl::DataProfileInfo>& info) {
LOG_CALL << serial;
- mHal1_5->setInitialAttachApn_1_5(serial, toHidl(info));
+ mHal1_5->setInitialAttachApn_1_5(serial, toHidl(info.value()));
return ok();
}
@@ -136,14 +137,15 @@
return ok();
}
-ScopedAStatus RadioData::setupDataCall( //
- int32_t serial, aidlCommon::AccessNetwork accessNetwork,
- const aidl::DataProfileInfo& dataProfileInfo, bool roamingAllowed,
- aidl::DataRequestReason reason, const std::vector<aidl::LinkAddress>& addresses,
- const std::vector<std::string>& dnses, int32_t pduSessId,
- const std::optional<aidl::SliceInfo>& sliceInfo, bool matchAllRuleAllowed) {
+ScopedAStatus RadioData::setupDataCall(int32_t serial, aidlCommon::AccessNetwork accessNetwork,
+ const aidl::DataProfileInfo& dataProfileInfo,
+ bool roamingAllowed, aidl::DataRequestReason reason,
+ const std::vector<aidl::LinkAddress>& addresses,
+ const std::vector<std::string>& dnses, int32_t pduSessId,
+ const std::optional<aidl::SliceInfo>& sliceInfo,
+ bool matchAllRuleAllowed) {
if (mHal1_6) {
- mHal1_6->setupDataCall_1_6( //
+ mHal1_6->setupDataCall_1_6(
serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
V1_2::DataRequestReason(reason), toHidl(addresses), toHidl(dnses), pduSessId,
toHidl<V1_6::OptionalSliceInfo>(sliceInfo),
@@ -151,7 +153,7 @@
matchAllRuleAllowed);
mContext->addDataProfile(dataProfileInfo);
} else {
- mHal1_5->setupDataCall_1_5( //
+ mHal1_5->setupDataCall_1_5(
serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
V1_2::DataRequestReason(reason), toHidl(addresses), toHidl(dnses));
}
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
index c617ec2..c2c0de3 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
@@ -44,7 +44,8 @@
int64_t completionDurationMillis) override;
::ndk::ScopedAStatus setInitialAttachApn(
int32_t serial,
- const ::aidl::android::hardware::radio::data::DataProfileInfo& dpInfo) override;
+ const std::optional<::aidl::android::hardware::radio::data::DataProfileInfo>& dpInfo)
+ override;
::ndk::ScopedAStatus setResponseFunctions(
const std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse>&
radioDataResponse,
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
index 419e9fb..047f836 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
@@ -33,7 +33,6 @@
::ndk::ScopedAStatus acknowledgeLastIncomingGsmSms(
int32_t serial, bool success,
::aidl::android::hardware::radio::messaging::SmsAcknowledgeFailCause cause) override;
- ::ndk::ScopedAStatus cancelPendingUssd(int32_t serial) override;
::ndk::ScopedAStatus deleteSmsOnRuim(int32_t serial, int32_t index) override;
::ndk::ScopedAStatus deleteSmsOnSim(int32_t serial, int32_t index) override;
::ndk::ScopedAStatus getCdmaBroadcastConfig(int32_t serial) override;
@@ -56,7 +55,6 @@
::ndk::ScopedAStatus sendSmsExpectMore(
int32_t serial,
const ::aidl::android::hardware::radio::messaging::GsmSmsMessage& message) override;
- ::ndk::ScopedAStatus sendUssd(int32_t serial, const std::string& ussd) override;
::ndk::ScopedAStatus setCdmaBroadcastActivation(int32_t serial, bool activate) override;
::ndk::ScopedAStatus setCdmaBroadcastConfig(
int32_t serial,
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
index a0e1e82..0f1d5fd 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
@@ -26,6 +26,7 @@
std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> respond();
::ndk::ScopedAStatus acceptCall(int32_t serial) override;
+ ::ndk::ScopedAStatus cancelPendingUssd(int32_t serial) override;
::ndk::ScopedAStatus conference(int32_t serial) override;
::ndk::ScopedAStatus dial(
int32_t serial, const ::aidl::android::hardware::radio::voice::Dial& dialInfo) override;
@@ -58,6 +59,7 @@
int32_t off) override;
::ndk::ScopedAStatus sendCdmaFeatureCode(int32_t serial, const std::string& fcode) override;
::ndk::ScopedAStatus sendDtmf(int32_t serial, const std::string& s) override;
+ ::ndk::ScopedAStatus sendUssd(int32_t serial, const std::string& ussd) override;
::ndk::ScopedAStatus separateConnection(int32_t serial, int32_t gsmIndex) override;
::ndk::ScopedAStatus setCallForward(
int32_t serial,
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
index e5c33b3..eb87828 100644
--- a/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
@@ -73,13 +73,6 @@
return {};
}
-Return<void> RadioIndication::onUssd(V1_0::RadioIndicationType type, V1_0::UssdModeType modeType,
- const hidl_string& msg) {
- LOG_CALL << type;
- messagingCb()->onUssd(toAidl(type), aidl::UssdModeType(modeType), msg);
- return {};
-}
-
Return<void> RadioIndication::simSmsStorageFull(V1_0::RadioIndicationType type) {
LOG_CALL << type;
messagingCb()->simSmsStorageFull(toAidl(type));
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
index 4d94e17..56d49f1 100644
--- a/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
@@ -54,12 +54,6 @@
return ok();
}
-ScopedAStatus RadioMessaging::cancelPendingUssd(int32_t serial) {
- LOG_CALL << serial;
- mHal1_5->cancelPendingUssd(serial);
- return ok();
-}
-
ScopedAStatus RadioMessaging::deleteSmsOnRuim(int32_t serial, int32_t index) {
LOG_CALL << serial << ' ' << index;
mHal1_5->deleteSmsOnRuim(serial, index);
@@ -148,12 +142,6 @@
return ok();
}
-ScopedAStatus RadioMessaging::sendUssd(int32_t serial, const std::string& ussd) {
- LOG_CALL << serial << ' ' << ussd;
- mHal1_5->sendUssd(serial, ussd);
- return ok();
-}
-
ScopedAStatus RadioMessaging::setCdmaBroadcastActivation(int32_t serial, bool activate) {
LOG_CALL << serial << ' ' << activate;
mHal1_5->setCdmaBroadcastActivation(serial, activate);
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
index 24ad3d7..7a9273f 100644
--- a/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
@@ -57,12 +57,6 @@
return {};
}
-Return<void> RadioResponse::cancelPendingUssdResponse(const V1_0::RadioResponseInfo& info) {
- LOG_CALL << info.serial;
- messagingCb()->cancelPendingUssdResponse(toAidl(info));
- return {};
-}
-
Return<void> RadioResponse::deleteSmsOnRuimResponse(const V1_0::RadioResponseInfo& info) {
LOG_CALL << info.serial;
messagingCb()->deleteSmsOnRuimResponse(toAidl(info));
@@ -166,12 +160,6 @@
return {};
}
-Return<void> RadioResponse::sendUssdResponse(const V1_0::RadioResponseInfo& info) {
- LOG_CALL << info.serial;
- messagingCb()->sendUssdResponse(toAidl(info));
- return {};
-}
-
Return<void> RadioResponse::setCdmaBroadcastActivationResponse(
const V1_0::RadioResponseInfo& info) {
LOG_CALL << info.serial;
diff --git a/radio/aidl/compat/libradiocompat/network/structs.cpp b/radio/aidl/compat/libradiocompat/network/structs.cpp
index 87a021f..c1d9b35 100644
--- a/radio/aidl/compat/libradiocompat/network/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/network/structs.cpp
@@ -650,13 +650,6 @@
};
}
-aidl::NeighboringCell toAidl(const V1_0::NeighboringCell& cell) {
- return {
- .cid = cell.cid,
- .rssi = cell.rssi,
- };
-}
-
aidl::LceDataInfo toAidl(const V1_0::LceDataInfo& info) {
return {
.lastHopCapacityKbps = static_cast<int32_t>(info.lastHopCapacityKbps),
diff --git a/radio/aidl/compat/libradiocompat/network/structs.h b/radio/aidl/compat/libradiocompat/network/structs.h
index 854cb38..aaa49a0 100644
--- a/radio/aidl/compat/libradiocompat/network/structs.h
+++ b/radio/aidl/compat/libradiocompat/network/structs.h
@@ -20,7 +20,6 @@
#include <aidl/android/hardware/radio/network/CellInfo.h>
#include <aidl/android/hardware/radio/network/LceDataInfo.h>
#include <aidl/android/hardware/radio/network/LinkCapacityEstimate.h>
-#include <aidl/android/hardware/radio/network/NeighboringCell.h>
#include <aidl/android/hardware/radio/network/NetworkScanRequest.h>
#include <aidl/android/hardware/radio/network/NetworkScanResult.h>
#include <aidl/android/hardware/radio/network/OperatorInfo.h>
@@ -92,8 +91,6 @@
::aidl::android::hardware::radio::network::RegStateResult toAidl(const V1_5::RegStateResult& res);
::aidl::android::hardware::radio::network::RegStateResult toAidl(const V1_6::RegStateResult& res);
-::aidl::android::hardware::radio::network::NeighboringCell toAidl(const V1_0::NeighboringCell& c);
-
::aidl::android::hardware::radio::network::LceDataInfo toAidl(const V1_0::LceDataInfo& info);
} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
index 359fce0..23878ed 100644
--- a/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
@@ -102,6 +102,13 @@
return {};
}
+Return<void> RadioIndication::onUssd(V1_0::RadioIndicationType type, V1_0::UssdModeType modeType,
+ const hidl_string& msg) {
+ LOG_CALL << type;
+ voiceCb()->onUssd(toAidl(type), aidl::UssdModeType(modeType), msg);
+ return {};
+}
+
Return<void> RadioIndication::resendIncallMute(V1_0::RadioIndicationType type) {
LOG_CALL << type;
voiceCb()->resendIncallMute(toAidl(type));
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
index d233548..5307e11 100644
--- a/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
@@ -42,6 +42,12 @@
return {};
}
+Return<void> RadioResponse::cancelPendingUssdResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ voiceCb()->cancelPendingUssdResponse(toAidl(info));
+ return {};
+}
+
Return<void> RadioResponse::conferenceResponse(const V1_0::RadioResponseInfo& info) {
LOG_CALL << info.serial;
voiceCb()->conferenceResponse(toAidl(info));
@@ -198,6 +204,12 @@
return {};
}
+Return<void> RadioResponse::sendUssdResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ voiceCb()->sendUssdResponse(toAidl(info));
+ return {};
+}
+
Return<void> RadioResponse::separateConnectionResponse(const V1_0::RadioResponseInfo& info) {
LOG_CALL << info.serial;
voiceCb()->separateConnectionResponse(toAidl(info));
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
index 71d1a56..9088f01 100644
--- a/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
@@ -40,6 +40,12 @@
return ok();
}
+ScopedAStatus RadioVoice::cancelPendingUssd(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->cancelPendingUssd(serial);
+ return ok();
+}
+
ScopedAStatus RadioVoice::conference(int32_t serial) {
LOG_CALL << serial;
mHal1_5->conference(serial);
@@ -201,6 +207,12 @@
return ok();
}
+ScopedAStatus RadioVoice::sendUssd(int32_t serial, const std::string& ussd) {
+ LOG_CALL << serial << ' ' << ussd;
+ mHal1_5->sendUssd(serial, ussd);
+ return ok();
+}
+
ScopedAStatus RadioVoice::separateConnection(int32_t serial, int32_t gsmIndex) {
LOG_CALL << serial;
mHal1_5->separateConnection(serial, gsmIndex);
diff --git a/radio/aidl/vts/OWNERS b/radio/aidl/vts/OWNERS
new file mode 100644
index 0000000..e75c6c8
--- /dev/null
+++ b/radio/aidl/vts/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 20868
+include ../../1.0/vts/OWNERS
+
diff --git a/radio/aidl/vts/radio_config_response.cpp b/radio/aidl/vts/radio_config_response.cpp
index 1a152fb..8d81605 100644
--- a/radio/aidl/vts/radio_config_response.cpp
+++ b/radio/aidl/vts/radio_config_response.cpp
@@ -19,12 +19,15 @@
RadioConfigResponse::RadioConfigResponse(RadioServiceTest& parent) : parent_config(parent) {}
ndk::ScopedAStatus RadioConfigResponse::getSimSlotsStatusResponse(
- const RadioResponseInfo& /* info */, const std::vector<SimSlotStatus>& /* slotStatus */) {
+ const RadioResponseInfo& info, const std::vector<SimSlotStatus>& /* slotStatus */) {
+ rspInfo = info;
+ parent_config.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioConfigResponse::setSimSlotsMappingResponse(
- const RadioResponseInfo& /* info */) {
+ndk::ScopedAStatus RadioConfigResponse::setSimSlotsMappingResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_config.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -37,22 +40,28 @@
}
ndk::ScopedAStatus RadioConfigResponse::setPreferredDataModemResponse(
- const RadioResponseInfo& /* info */) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_config.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioConfigResponse::getNumOfLiveModemsResponse(
- const RadioResponseInfo& /* info */, const int8_t /* numOfLiveModems */) {
+ const RadioResponseInfo& info, const int8_t /* numOfLiveModems */) {
+ rspInfo = info;
+ parent_config.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioConfigResponse::setNumOfLiveModemsResponse(
- const RadioResponseInfo& /* info */) {
+ndk::ScopedAStatus RadioConfigResponse::setNumOfLiveModemsResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_config.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioConfigResponse::getHalDeviceCapabilitiesResponse(
const RadioResponseInfo& info, bool modemReducedFeatures) {
+ rspInfo = info;
modemReducedFeatureSet1 = modemReducedFeatures;
parent_config.notify(info.serial);
return ndk::ScopedAStatus::ok();
diff --git a/radio/aidl/vts/radio_config_test.cpp b/radio/aidl/vts/radio_config_test.cpp
index 2d7fe01..a271b8a 100644
--- a/radio/aidl/vts/radio_config_test.cpp
+++ b/radio/aidl/vts/radio_config_test.cpp
@@ -54,3 +54,102 @@
ALOGI("getHalDeviceCapabilities, rspInfo.error = %s\n",
toString(radioRsp_config->rspInfo.error).c_str());
}
+
+/*
+ * Test IRadioConfig.getSimSlotsStatus() for the response returned.
+ */
+TEST_P(RadioConfigTest, getSimSlotsStatus) {
+ serial = GetRandomSerialNumber();
+ ndk::ScopedAStatus res = radio_config->getSimSlotsStatus(serial);
+ ASSERT_OK(res);
+ ALOGI("getSimSlotsStatus, rspInfo.error = %s\n",
+ toString(radioRsp_config->rspInfo.error).c_str());
+}
+
+/*
+ * Test IRadioConfig.getPhoneCapability() for the response returned.
+ */
+TEST_P(RadioConfigTest, getPhoneCapability) {
+ serial = GetRandomSerialNumber();
+ ndk::ScopedAStatus res = radio_config->getPhoneCapability(serial);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
+ ALOGI("getPhoneCapability, rspInfo.error = %s\n",
+ toString(radioRsp_config->rspInfo.error).c_str());
+
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_config->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR}));
+
+ if (radioRsp_config->rspInfo.error == RadioError ::NONE) {
+ // maxActiveData should be greater than or equal to maxActiveInternetData.
+ EXPECT_GE(radioRsp_config->phoneCap.maxActiveData,
+ radioRsp_config->phoneCap.maxActiveInternetData);
+ // maxActiveData and maxActiveInternetData should be 0 or positive numbers.
+ EXPECT_GE(radioRsp_config->phoneCap.maxActiveInternetData, 0);
+ }
+}
+
+/*
+ * Test IRadioConfig.setPreferredDataModem() for the response returned.
+ */
+TEST_P(RadioConfigTest, setPreferredDataModem) {
+ serial = GetRandomSerialNumber();
+ ndk::ScopedAStatus res = radio_config->getPhoneCapability(serial);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
+ ALOGI("getPhoneCapability, rspInfo.error = %s\n",
+ toString(radioRsp_config->rspInfo.error).c_str());
+
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_config->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR}));
+
+ if (radioRsp_config->rspInfo.error != RadioError ::NONE) {
+ return;
+ }
+
+ if (radioRsp_config->phoneCap.logicalModemIds.size() == 0) {
+ return;
+ }
+
+ // We get phoneCapability. Send setPreferredDataModem command
+ serial = GetRandomSerialNumber();
+ uint8_t modemId = radioRsp_config->phoneCap.logicalModemIds[0];
+ res = radio_config->setPreferredDataModem(serial, modemId);
+
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
+ ALOGI("setPreferredDataModem, rspInfo.error = %s\n",
+ toString(radioRsp_config->rspInfo.error).c_str());
+
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_config->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR}));
+}
+
+/*
+ * Test IRadioConfig.setPreferredDataModem() with invalid arguments.
+ */
+TEST_P(RadioConfigTest, setPreferredDataModem_invalidArgument) {
+ serial = GetRandomSerialNumber();
+ uint8_t modemId = -1;
+ ndk::ScopedAStatus res = radio_config->setPreferredDataModem(serial, modemId);
+
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
+ ALOGI("setPreferredDataModem, rspInfo.error = %s\n",
+ toString(radioRsp_config->rspInfo.error).c_str());
+
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_config->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::INTERNAL_ERR}));
+}
diff --git a/radio/aidl/vts/radio_data_response.cpp b/radio/aidl/vts/radio_data_response.cpp
index 9b17bfb..8d51760 100644
--- a/radio/aidl/vts/radio_data_response.cpp
+++ b/radio/aidl/vts/radio_data_response.cpp
@@ -36,8 +36,9 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioDataResponse::deactivateDataCallResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioDataResponse::deactivateDataCallResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_data.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -61,11 +62,15 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioDataResponse::setDataAllowedResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioDataResponse::setDataAllowedResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_data.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioDataResponse::setDataProfileResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioDataResponse::setDataProfileResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_data.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -75,8 +80,9 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioDataResponse::setInitialAttachApnResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioDataResponse::setInitialAttachApnResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_data.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -94,11 +100,15 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioDataResponse::startKeepaliveResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioDataResponse::startKeepaliveResponse(const RadioResponseInfo& info,
const KeepaliveStatus& /*status*/) {
+ rspInfo = info;
+ parent_data.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioDataResponse::stopKeepaliveResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioDataResponse::stopKeepaliveResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_data.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
diff --git a/radio/aidl/vts/radio_data_test.cpp b/radio/aidl/vts/radio_data_test.cpp
index 8547e9d..f38a958 100644
--- a/radio/aidl/vts/radio_data_test.cpp
+++ b/radio/aidl/vts/radio_data_test.cpp
@@ -83,7 +83,7 @@
dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
dataProfileInfo.user = std::string("username");
dataProfileInfo.password = std::string("password");
- dataProfileInfo.type = DataProfileInfo::TYPE_THREE_GPP;
+ dataProfileInfo.type = DataProfileInfo::TYPE_3GPP;
dataProfileInfo.maxConnsTime = 300;
dataProfileInfo.maxConns = 20;
dataProfileInfo.waitTime = 0;
@@ -157,7 +157,7 @@
dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
dataProfileInfo.user = std::string("username");
dataProfileInfo.password = std::string("password");
- dataProfileInfo.type = DataProfileInfo::TYPE_THREE_GPP;
+ dataProfileInfo.type = DataProfileInfo::TYPE_3GPP;
dataProfileInfo.maxConnsTime = 300;
dataProfileInfo.maxConns = 20;
dataProfileInfo.waitTime = 0;
@@ -309,3 +309,280 @@
sleep(1);
}
+
+/*
+ * Test IRadioData.setInitialAttachApn() for the response returned.
+ */
+TEST_P(RadioDataTest, setInitialAttachApn) {
+ serial = GetRandomSerialNumber();
+
+ // Create a dataProfileInfo
+ DataProfileInfo dataProfileInfo;
+ memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+ dataProfileInfo.profileId = DataProfileInfo::ID_DEFAULT;
+ dataProfileInfo.apn = std::string("internet");
+ dataProfileInfo.protocol = PdpProtocolType::IPV4V6;
+ dataProfileInfo.roamingProtocol = PdpProtocolType::IPV4V6;
+ dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+ dataProfileInfo.user = std::string("username");
+ dataProfileInfo.password = std::string("password");
+ dataProfileInfo.type = DataProfileInfo::TYPE_3GPP;
+ dataProfileInfo.maxConnsTime = 300;
+ dataProfileInfo.maxConns = 20;
+ dataProfileInfo.waitTime = 0;
+ dataProfileInfo.enabled = true;
+ dataProfileInfo.supportedApnTypesBitmap = 320;
+ dataProfileInfo.bearerBitmap = 161543;
+ dataProfileInfo.mtuV4 = 0;
+ dataProfileInfo.mtuV6 = 0;
+ dataProfileInfo.preferred = true;
+ dataProfileInfo.persistent = false;
+
+ radio_data->setInitialAttachApn(serial, dataProfileInfo);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE}));
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE}));
+ }
+}
+
+/*
+ * Test IRadioData.setDataProfile() for the response returned.
+ */
+TEST_P(RadioDataTest, setDataProfile) {
+ serial = GetRandomSerialNumber();
+
+ // Create a dataProfileInfo
+ DataProfileInfo dataProfileInfo;
+ memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+ dataProfileInfo.profileId = DataProfileInfo::ID_DEFAULT;
+ dataProfileInfo.apn = std::string("internet");
+ dataProfileInfo.protocol = PdpProtocolType::IPV4V6;
+ dataProfileInfo.roamingProtocol = PdpProtocolType::IPV4V6;
+ dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+ dataProfileInfo.user = std::string("username");
+ dataProfileInfo.password = std::string("password");
+ dataProfileInfo.type = DataProfileInfo::TYPE_3GPP;
+ dataProfileInfo.maxConnsTime = 300;
+ dataProfileInfo.maxConns = 20;
+ dataProfileInfo.waitTime = 0;
+ dataProfileInfo.enabled = true;
+ dataProfileInfo.supportedApnTypesBitmap = 320;
+ dataProfileInfo.bearerBitmap = 161543;
+ dataProfileInfo.mtuV4 = 0;
+ dataProfileInfo.mtuV6 = 0;
+ dataProfileInfo.preferred = true;
+ dataProfileInfo.persistent = true;
+
+ // Create a dataProfileInfoList
+ std::vector<DataProfileInfo> dataProfileInfoList = {dataProfileInfo};
+
+ radio_data->setDataProfile(serial, dataProfileInfoList);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE}));
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE}));
+ }
+}
+
+/*
+ * Test IRadioData.deactivateDataCall() for the response returned.
+ */
+TEST_P(RadioDataTest, deactivateDataCall) {
+ serial = GetRandomSerialNumber();
+ int cid = 1;
+ DataRequestReason reason = DataRequestReason::NORMAL;
+
+ ndk::ScopedAStatus res = radio_data->deactivateDataCall(serial, cid, reason);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::INVALID_CALL_ID, RadioError::INVALID_STATE,
+ RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED,
+ RadioError::CANCELLED, RadioError::SIM_ABSENT}));
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_data->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_CALL_ID,
+ RadioError::INVALID_STATE, RadioError::INVALID_ARGUMENTS,
+ RadioError::REQUEST_NOT_SUPPORTED, RadioError::CANCELLED}));
+ }
+}
+
+/*
+ * Test IRadioData.startKeepalive() for the response returned.
+ */
+TEST_P(RadioDataTest, startKeepalive) {
+ std::vector<KeepaliveRequest> requests = {
+ {
+ // Invalid IPv4 source address
+ KeepaliveRequest::TYPE_NATT_IPV4,
+ {192, 168, 0 /*, 100*/},
+ 1234,
+ {8, 8, 4, 4},
+ 4500,
+ 20000,
+ 0xBAD,
+ },
+ {
+ // Invalid IPv4 destination address
+ KeepaliveRequest::TYPE_NATT_IPV4,
+ {192, 168, 0, 100},
+ 1234,
+ {8, 8, 4, 4, 1, 2, 3, 4},
+ 4500,
+ 20000,
+ 0xBAD,
+ },
+ {
+ // Invalid Keepalive Type
+ -1,
+ {192, 168, 0, 100},
+ 1234,
+ {8, 8, 4, 4},
+ 4500,
+ 20000,
+ 0xBAD,
+ },
+ {
+ // Invalid IPv6 source address
+ KeepaliveRequest::TYPE_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
+ KeepaliveRequest::TYPE_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
+ KeepaliveRequest::TYPE_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
+ KeepaliveRequest::TYPE_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++) {
+ serial = GetRandomSerialNumber();
+ radio_data->startKeepalive(serial, *req);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_data->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_ARGUMENTS,
+ RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadioData.stopKeepalive() for the response returned.
+ */
+TEST_P(RadioDataTest, stopKeepalive) {
+ serial = GetRandomSerialNumber();
+
+ radio_data->stopKeepalive(serial, 0xBAD);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioData.getDataCallList() for the response returned.
+ */
+TEST_P(RadioDataTest, getDataCallList) {
+ LOG(DEBUG) << "getDataCallList";
+ serial = GetRandomSerialNumber();
+
+ radio_data->getDataCallList(serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_data->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::SIM_ABSENT}));
+ }
+ LOG(DEBUG) << "getDataCallList finished";
+}
+
+/*
+ * Test IRadioData.setDataAllowed() for the response returned.
+ */
+TEST_P(RadioDataTest, setDataAllowed) {
+ LOG(DEBUG) << "setDataAllowed";
+ serial = GetRandomSerialNumber();
+ bool allow = true;
+
+ radio_data->setDataAllowed(serial, allow);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp_data->rspInfo.error);
+ }
+ LOG(DEBUG) << "setDataAllowed finished";
+}
diff --git a/radio/aidl/vts/radio_messaging_indication.cpp b/radio/aidl/vts/radio_messaging_indication.cpp
index c69611f..481239e 100644
--- a/radio/aidl/vts/radio_messaging_indication.cpp
+++ b/radio/aidl/vts/radio_messaging_indication.cpp
@@ -48,12 +48,6 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioMessagingIndication::onUssd(RadioIndicationType /*type*/,
- UssdModeType /*modeType*/,
- const std::string& /*msg*/) {
- return ndk::ScopedAStatus::ok();
-}
-
ndk::ScopedAStatus RadioMessagingIndication::simSmsStorageFull(RadioIndicationType /*type*/) {
return ndk::ScopedAStatus::ok();
}
diff --git a/radio/aidl/vts/radio_messaging_response.cpp b/radio/aidl/vts/radio_messaging_response.cpp
index 718df7e..49c0806 100644
--- a/radio/aidl/vts/radio_messaging_response.cpp
+++ b/radio/aidl/vts/radio_messaging_response.cpp
@@ -20,17 +20,23 @@
: parent_messaging(parent) {}
ndk::ScopedAStatus RadioMessagingResponse::acknowledgeIncomingGsmSmsWithPduResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioMessagingResponse::acknowledgeLastIncomingCdmaSmsResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioMessagingResponse::acknowledgeLastIncomingGsmSmsResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -38,40 +44,43 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioMessagingResponse::cancelPendingUssdResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioMessagingResponse::deleteSmsOnRuimResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioMessagingResponse::deleteSmsOnRuimResponse(
- const RadioResponseInfo& /*info*/) {
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus RadioMessagingResponse::deleteSmsOnSimResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioMessagingResponse::deleteSmsOnSimResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioMessagingResponse::getCdmaBroadcastConfigResponse(
- const RadioResponseInfo& /*info*/,
- const std::vector<CdmaBroadcastSmsConfigInfo>& /*configs*/) {
+ const RadioResponseInfo& info, const std::vector<CdmaBroadcastSmsConfigInfo>& /*configs*/) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioMessagingResponse::getGsmBroadcastConfigResponse(
- const RadioResponseInfo& /*info*/,
- const std::vector<GsmBroadcastSmsConfigInfo>& /*configs*/) {
+ const RadioResponseInfo& info, const std::vector<GsmBroadcastSmsConfigInfo>& /*configs*/) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioMessagingResponse::getSmscAddressResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioMessagingResponse::getSmscAddressResponse(const RadioResponseInfo& info,
const std::string& /*smsc*/) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioMessagingResponse::reportSmsMemoryStatusResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -91,8 +100,10 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioMessagingResponse::sendImsSmsResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioMessagingResponse::sendImsSmsResponse(const RadioResponseInfo& info,
const SendSmsResult& /*sms*/) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -112,41 +123,50 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioMessagingResponse::sendUssdResponse(const RadioResponseInfo& /*info*/) {
- return ndk::ScopedAStatus::ok();
-}
-
ndk::ScopedAStatus RadioMessagingResponse::setCdmaBroadcastActivationResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioMessagingResponse::setCdmaBroadcastConfigResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioMessagingResponse::setGsmBroadcastActivationResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioMessagingResponse::setGsmBroadcastConfigResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioMessagingResponse::setSmscAddressResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioMessagingResponse::setSmscAddressResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioMessagingResponse::writeSmsToRuimResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioMessagingResponse::writeSmsToRuimResponse(const RadioResponseInfo& info,
int32_t /*index*/) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioMessagingResponse::writeSmsToSimResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioMessagingResponse::writeSmsToSimResponse(const RadioResponseInfo& info,
int32_t /*index*/) {
+ rspInfo = info;
+ parent_messaging.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
diff --git a/radio/aidl/vts/radio_messaging_test.cpp b/radio/aidl/vts/radio_messaging_test.cpp
index 8abd91d..9f1718b 100644
--- a/radio/aidl/vts/radio_messaging_test.cpp
+++ b/radio/aidl/vts/radio_messaging_test.cpp
@@ -197,3 +197,535 @@
CHECK_GENERAL_ERROR));
}
}
+
+/*
+ * Test IRadioMessaging.setGsmBroadcastConfig() for the response returned.
+ */
+TEST_P(RadioMessagingTest, setGsmBroadcastConfig) {
+ LOG(DEBUG) << "setGsmBroadcastConfig";
+ serial = GetRandomSerialNumber();
+
+ // Create GsmBroadcastSmsConfigInfo #1
+ GsmBroadcastSmsConfigInfo gbSmsConfig1;
+ gbSmsConfig1.fromServiceId = 4352;
+ gbSmsConfig1.toServiceId = 4354;
+ gbSmsConfig1.fromCodeScheme = 0;
+ gbSmsConfig1.toCodeScheme = 255;
+ gbSmsConfig1.selected = true;
+
+ // Create GsmBroadcastSmsConfigInfo #2
+ GsmBroadcastSmsConfigInfo gbSmsConfig2;
+ gbSmsConfig2.fromServiceId = 4356;
+ gbSmsConfig2.toServiceId = 4356;
+ gbSmsConfig2.fromCodeScheme = 0;
+ gbSmsConfig2.toCodeScheme = 255;
+ gbSmsConfig2.selected = true;
+
+ // Create GsmBroadcastSmsConfigInfo #3
+ GsmBroadcastSmsConfigInfo gbSmsConfig3;
+ gbSmsConfig3.fromServiceId = 4370;
+ gbSmsConfig3.toServiceId = 4379;
+ gbSmsConfig3.fromCodeScheme = 0;
+ gbSmsConfig3.toCodeScheme = 255;
+ gbSmsConfig3.selected = true;
+
+ // Create GsmBroadcastSmsConfigInfo #4
+ GsmBroadcastSmsConfigInfo gbSmsConfig4;
+ gbSmsConfig4.fromServiceId = 4383;
+ gbSmsConfig4.toServiceId = 4391;
+ gbSmsConfig4.fromCodeScheme = 0;
+ gbSmsConfig4.toCodeScheme = 255;
+ gbSmsConfig4.selected = true;
+
+ // Create GsmBroadcastSmsConfigInfo #5
+ GsmBroadcastSmsConfigInfo gbSmsConfig5;
+ gbSmsConfig5.fromServiceId = 4392;
+ gbSmsConfig5.toServiceId = 4392;
+ gbSmsConfig5.fromCodeScheme = 0;
+ gbSmsConfig5.toCodeScheme = 255;
+ gbSmsConfig5.selected = true;
+
+ std::vector<GsmBroadcastSmsConfigInfo> gsmBroadcastSmsConfigsInfoList = {
+ gbSmsConfig1, gbSmsConfig2, gbSmsConfig3, gbSmsConfig4, gbSmsConfig5};
+
+ radio_messaging->setGsmBroadcastConfig(serial, gsmBroadcastSmsConfigsInfoList);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+ RadioError::INVALID_MODEM_STATE, RadioError::INVALID_STATE},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "setGsmBroadcastConfig finished";
+}
+
+/*
+ * Test IRadioMessaging.getGsmBroadcastConfig() for the response returned.
+ */
+TEST_P(RadioMessagingTest, getGsmBroadcastConfig) {
+ LOG(DEBUG) << "getGsmBroadcastConfig";
+ serial = GetRandomSerialNumber();
+
+ radio_messaging->getGsmBroadcastConfig(serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_messaging->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_MODEM_STATE, RadioError::INVALID_STATE},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "getGsmBroadcastConfig finished";
+}
+
+/*
+ * Test IRadioMessaging.setCdmaBroadcastConfig() for the response returned.
+ */
+TEST_P(RadioMessagingTest, setCdmaBroadcastConfig) {
+ LOG(DEBUG) << "setCdmaBroadcastConfig";
+ serial = GetRandomSerialNumber();
+
+ CdmaBroadcastSmsConfigInfo cbSmsConfig;
+ cbSmsConfig.serviceCategory = 4096;
+ cbSmsConfig.language = 1;
+ cbSmsConfig.selected = true;
+
+ std::vector<CdmaBroadcastSmsConfigInfo> cdmaBroadcastSmsConfigInfoList = {cbSmsConfig};
+
+ radio_messaging->setCdmaBroadcastConfig(serial, cdmaBroadcastSmsConfigInfoList);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_MODEM_STATE},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "setCdmaBroadcastConfig finished";
+}
+
+/*
+ * Test IRadioMessaging.getCdmaBroadcastConfig() for the response returned.
+ */
+TEST_P(RadioMessagingTest, getCdmaBroadcastConfig) {
+ LOG(DEBUG) << "getCdmaBroadcastConfig";
+ serial = GetRandomSerialNumber();
+
+ radio_messaging->getCdmaBroadcastConfig(serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error, {RadioError::NONE},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "getCdmaBroadcastConfig finished";
+}
+
+/*
+ * Test IRadioMessaging.setCdmaBroadcastActivation() for the response returned.
+ */
+TEST_P(RadioMessagingTest, setCdmaBroadcastActivation) {
+ LOG(DEBUG) << "setCdmaBroadcastActivation";
+ serial = GetRandomSerialNumber();
+ bool activate = false;
+
+ radio_messaging->setCdmaBroadcastActivation(serial, activate);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "setCdmaBroadcastActivation finished";
+}
+
+/*
+ * Test IRadioMessaging.setGsmBroadcastActivation() for the response returned.
+ */
+TEST_P(RadioMessagingTest, setGsmBroadcastActivation) {
+ LOG(DEBUG) << "setGsmBroadcastActivation";
+ serial = GetRandomSerialNumber();
+ bool activate = false;
+
+ radio_messaging->setGsmBroadcastActivation(serial, activate);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_messaging->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INVALID_MODEM_STATE,
+ RadioError::INVALID_STATE, RadioError::OPERATION_NOT_ALLOWED},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "setGsmBroadcastActivation finished";
+}
+
+/*
+ * Test IRadioMessaging.acknowledgeLastIncomingGsmSms() for the response returned.
+ */
+TEST_P(RadioMessagingTest, acknowledgeLastIncomingGsmSms) {
+ LOG(DEBUG) << "acknowledgeLastIncomingGsmSms";
+ serial = GetRandomSerialNumber();
+ bool success = true;
+
+ radio_messaging->acknowledgeLastIncomingGsmSms(
+ serial, success, SmsAcknowledgeFailCause::MEMORY_CAPACITY_EXCEEDED);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "acknowledgeLastIncomingGsmSms finished";
+}
+
+/*
+ * Test IRadioMessaging.acknowledgeIncomingGsmSmsWithPdu() for the response returned.
+ */
+TEST_P(RadioMessagingTest, acknowledgeIncomingGsmSmsWithPdu) {
+ LOG(DEBUG) << "acknowledgeIncomingGsmSmsWithPdu";
+ serial = GetRandomSerialNumber();
+ bool success = true;
+ std::string ackPdu = "";
+
+ radio_messaging->acknowledgeIncomingGsmSmsWithPdu(serial, success, ackPdu);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::NO_SMS_TO_ACK},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "acknowledgeIncomingGsmSmsWithPdu finished";
+}
+
+/*
+ * Test IRadioMessaging.acknowledgeLastIncomingCdmaSms() for the response returned.
+ */
+TEST_P(RadioMessagingTest, acknowledgeLastIncomingCdmaSms) {
+ LOG(DEBUG) << "acknowledgeLastIncomingCdmaSms";
+ serial = GetRandomSerialNumber();
+
+ // Create a CdmaSmsAck
+ CdmaSmsAck cdmaSmsAck;
+ cdmaSmsAck.errorClass = false;
+ cdmaSmsAck.smsCauseCode = 1;
+
+ radio_messaging->acknowledgeLastIncomingCdmaSms(serial, cdmaSmsAck);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::NO_SMS_TO_ACK},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "acknowledgeLastIncomingCdmaSms finished";
+}
+
+/*
+ * Test IRadioMessaging.sendImsSms() for the response returned.
+ */
+TEST_P(RadioMessagingTest, sendImsSms) {
+ LOG(DEBUG) << "sendImsSms";
+ serial = GetRandomSerialNumber();
+
+ // Create a CdmaSmsAddress
+ CdmaSmsAddress cdmaSmsAddress;
+ cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
+ cdmaSmsAddress.isNumberModeDataNetwork = false;
+ cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
+ cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
+ cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
+
+ // Create a CdmaSmsSubAddress
+ CdmaSmsSubaddress cdmaSmsSubaddress;
+ cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
+ cdmaSmsSubaddress.odd = false;
+ cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
+
+ // Create a CdmaSmsMessage
+ CdmaSmsMessage cdmaSmsMessage;
+ cdmaSmsMessage.teleserviceId = 4098;
+ cdmaSmsMessage.isServicePresent = false;
+ cdmaSmsMessage.serviceCategory = 0;
+ cdmaSmsMessage.address = cdmaSmsAddress;
+ cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
+ cdmaSmsMessage.bearerData =
+ (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
+
+ // Creata an ImsSmsMessage
+ ImsSmsMessage msg;
+ msg.tech = RadioTechnologyFamily::THREE_GPP2;
+ msg.retry = false;
+ msg.messageRef = 0;
+ msg.cdmaMessage = (std::vector<CdmaSmsMessage>){cdmaSmsMessage};
+ msg.gsmMessage = (std::vector<GsmSmsMessage>){};
+
+ radio_messaging->sendImsSms(serial, msg);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS}, CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "sendImsSms finished";
+}
+
+/*
+ * Test IRadioMessaging.getSmscAddress() for the response returned.
+ */
+TEST_P(RadioMessagingTest, getSmscAddress) {
+ LOG(DEBUG) << "getSmscAddress";
+ serial = GetRandomSerialNumber();
+
+ radio_messaging->getSmscAddress(serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
+ {RadioError::INVALID_MODEM_STATE, RadioError::INVALID_STATE,
+ RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "getSmscAddress finished";
+}
+
+/*
+ * Test IRadioMessaging.setSmscAddress() for the response returned.
+ */
+TEST_P(RadioMessagingTest, setSmscAddress) {
+ LOG(DEBUG) << "setSmscAddress";
+ serial = GetRandomSerialNumber();
+ std::string address = std::string("smscAddress");
+
+ radio_messaging->setSmscAddress(serial, address);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_SMS_FORMAT,
+ RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "setSmscAddress finished";
+}
+
+/*
+ * Test IRadioMessaging.writeSmsToSim() for the response returned.
+ */
+TEST_P(RadioMessagingTest, writeSmsToSim) {
+ LOG(DEBUG) << "writeSmsToSim";
+ serial = GetRandomSerialNumber();
+ SmsWriteArgs smsWriteArgs;
+ smsWriteArgs.status = SmsWriteArgs::STATUS_REC_UNREAD;
+ smsWriteArgs.smsc = "";
+ smsWriteArgs.pdu = "01000b916105770203f3000006d4f29c3e9b01";
+
+ radio_messaging->writeSmsToSim(serial, smsWriteArgs);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_messaging->rspInfo.error,
+ {RadioError::NONE, RadioError::ENCODING_ERR, RadioError::INVALID_ARGUMENTS,
+ RadioError::INVALID_SMSC_ADDRESS, RadioError::MODEM_ERR,
+ RadioError::NETWORK_NOT_READY, RadioError::NO_RESOURCES, RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "writeSmsToSim finished";
+}
+
+/*
+ * Test IRadioMessaging.deleteSmsOnSim() for the response returned.
+ */
+TEST_P(RadioMessagingTest, deleteSmsOnSim) {
+ LOG(DEBUG) << "deleteSmsOnSim";
+ serial = GetRandomSerialNumber();
+ int index = 1;
+
+ radio_messaging->deleteSmsOnSim(serial, index);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_messaging->rspInfo.error,
+ {RadioError::NONE, RadioError::ENCODING_ERR, RadioError::INVALID_ARGUMENTS,
+ RadioError::INVALID_MODEM_STATE, RadioError::NO_SUCH_ENTRY, RadioError::MODEM_ERR,
+ RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "deleteSmsOnSim finished";
+}
+
+/*
+ * Test IRadioMessaging.writeSmsToRuim() for the response returned.
+ */
+TEST_P(RadioMessagingTest, writeSmsToRuim) {
+ LOG(DEBUG) << "writeSmsToRuim";
+ serial = GetRandomSerialNumber();
+
+ // Create a CdmaSmsAddress
+ CdmaSmsAddress cdmaSmsAddress;
+ cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
+ cdmaSmsAddress.isNumberModeDataNetwork = false;
+ cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
+ cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
+ cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
+
+ // Create a CdmaSmsSubAddress
+ CdmaSmsSubaddress cdmaSmsSubaddress;
+ cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
+ cdmaSmsSubaddress.odd = false;
+ cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
+
+ // Create a CdmaSmsMessage
+ CdmaSmsMessage cdmaSmsMessage;
+ cdmaSmsMessage.teleserviceId = 4098;
+ cdmaSmsMessage.isServicePresent = false;
+ cdmaSmsMessage.serviceCategory = 0;
+ cdmaSmsMessage.address = cdmaSmsAddress;
+ cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
+ cdmaSmsMessage.bearerData =
+ (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
+
+ // Create a CdmaSmsWriteArgs
+ CdmaSmsWriteArgs cdmaSmsWriteArgs;
+ cdmaSmsWriteArgs.status = CdmaSmsWriteArgs::STATUS_REC_UNREAD;
+ cdmaSmsWriteArgs.message = cdmaSmsMessage;
+
+ radio_messaging->writeSmsToRuim(serial, cdmaSmsWriteArgs);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_messaging->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INVALID_SMS_FORMAT,
+ RadioError::INVALID_SMSC_ADDRESS, RadioError::INVALID_STATE, RadioError::MODEM_ERR,
+ RadioError::NO_SUCH_ENTRY, RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "writeSmsToRuim finished";
+}
+
+/*
+ * Test IRadioMessaging.deleteSmsOnRuim() for the response returned.
+ */
+TEST_P(RadioMessagingTest, deleteSmsOnRuim) {
+ LOG(DEBUG) << "deleteSmsOnRuim";
+ serial = GetRandomSerialNumber();
+ int index = 1;
+
+ // Create a CdmaSmsAddress
+ CdmaSmsAddress cdmaSmsAddress;
+ cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
+ cdmaSmsAddress.isNumberModeDataNetwork = false;
+ cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
+ cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
+ cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
+
+ // Create a CdmaSmsSubAddress
+ CdmaSmsSubaddress cdmaSmsSubaddress;
+ cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
+ cdmaSmsSubaddress.odd = false;
+ cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
+
+ // Create a CdmaSmsMessage
+ CdmaSmsMessage cdmaSmsMessage;
+ cdmaSmsMessage.teleserviceId = 4098;
+ cdmaSmsMessage.isServicePresent = false;
+ cdmaSmsMessage.serviceCategory = 0;
+ cdmaSmsMessage.address = cdmaSmsAddress;
+ cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
+ cdmaSmsMessage.bearerData =
+ (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
+
+ // Create a CdmaSmsWriteArgs
+ CdmaSmsWriteArgs cdmaSmsWriteArgs;
+ cdmaSmsWriteArgs.status = CdmaSmsWriteArgs::STATUS_REC_UNREAD;
+ cdmaSmsWriteArgs.message = cdmaSmsMessage;
+
+ radio_messaging->deleteSmsOnRuim(serial, index);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_messaging->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INVALID_MODEM_STATE,
+ RadioError::MODEM_ERR, RadioError::NO_SUCH_ENTRY, RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "deleteSmsOnRuim finished";
+}
+
+/*
+ * Test IRadioMessaging.reportSmsMemoryStatus() for the response returned.
+ */
+TEST_P(RadioMessagingTest, reportSmsMemoryStatus) {
+ LOG(DEBUG) << "reportSmsMemoryStatus";
+ serial = GetRandomSerialNumber();
+ bool available = true;
+
+ radio_messaging->reportSmsMemoryStatus(serial, available);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE,
+ RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "reportSmsMemoryStatus finished";
+}
diff --git a/radio/aidl/vts/radio_messaging_utils.h b/radio/aidl/vts/radio_messaging_utils.h
index 7bb99cd..7b66192 100644
--- a/radio/aidl/vts/radio_messaging_utils.h
+++ b/radio/aidl/vts/radio_messaging_utils.h
@@ -49,8 +49,6 @@
virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
- virtual ndk::ScopedAStatus cancelPendingUssdResponse(const RadioResponseInfo& info) override;
-
virtual ndk::ScopedAStatus deleteSmsOnRuimResponse(const RadioResponseInfo& info) override;
virtual ndk::ScopedAStatus deleteSmsOnSimResponse(const RadioResponseInfo& info) override;
@@ -84,8 +82,6 @@
virtual ndk::ScopedAStatus sendSmsResponse(const RadioResponseInfo& info,
const SendSmsResult& sms) override;
- virtual ndk::ScopedAStatus sendUssdResponse(const RadioResponseInfo& info) override;
-
virtual ndk::ScopedAStatus setCdmaBroadcastActivationResponse(
const RadioResponseInfo& info) override;
@@ -132,9 +128,6 @@
virtual ndk::ScopedAStatus newSmsStatusReport(RadioIndicationType type,
const std::vector<uint8_t>& pdu) override;
- virtual ndk::ScopedAStatus onUssd(RadioIndicationType type, UssdModeType modeType,
- const std::string& msg) override;
-
virtual ndk::ScopedAStatus simSmsStorageFull(RadioIndicationType type) override;
};
diff --git a/radio/aidl/vts/radio_modem_response.cpp b/radio/aidl/vts/radio_modem_response.cpp
index 53bfab4..d2715a8 100644
--- a/radio/aidl/vts/radio_modem_response.cpp
+++ b/radio/aidl/vts/radio_modem_response.cpp
@@ -22,70 +22,99 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioModemResponse::enableModemResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioModemResponse::enableModemResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_modem.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioModemResponse::getBasebandVersionResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioModemResponse::getBasebandVersionResponse(const RadioResponseInfo& info,
const std::string& /*version*/) {
+ rspInfo = info;
+ parent_modem.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioModemResponse::getDeviceIdentityResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioModemResponse::getDeviceIdentityResponse(const RadioResponseInfo& info,
const std::string& /*imei*/,
const std::string& /*imeisv*/,
const std::string& /*esn*/,
const std::string& /*meid*/) {
+ rspInfo = info;
+ parent_modem.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioModemResponse::getHardwareConfigResponse(
- const RadioResponseInfo& /*info*/, const std::vector<HardwareConfig>& /*config*/) {
+ const RadioResponseInfo& info, const std::vector<HardwareConfig>& /*config*/) {
+ rspInfo = info;
+ parent_modem.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioModemResponse::getModemActivityInfoResponse(
- const RadioResponseInfo& /*info*/, const ActivityStatsInfo& /*activityInfo*/) {
+ const RadioResponseInfo& info, const ActivityStatsInfo& /*activityInfo*/) {
+ rspInfo = info;
+ parent_modem.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioModemResponse::getModemStackStatusResponse(
- const RadioResponseInfo& /*info*/, const bool /*enabled*/) {
+ndk::ScopedAStatus RadioModemResponse::getModemStackStatusResponse(const RadioResponseInfo& info,
+ const bool enabled) {
+ rspInfo = info;
+ isModemEnabled = enabled;
+ parent_modem.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioModemResponse::getRadioCapabilityResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioModemResponse::getRadioCapabilityResponse(const RadioResponseInfo& info,
const RadioCapability& /*rc*/) {
+ rspInfo = info;
+ parent_modem.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioModemResponse::nvReadItemResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioModemResponse::nvReadItemResponse(const RadioResponseInfo& info,
const std::string& /*result*/) {
+ rspInfo = info;
+ parent_modem.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioModemResponse::nvResetConfigResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioModemResponse::nvResetConfigResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_modem.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioModemResponse::nvWriteCdmaPrlResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioModemResponse::nvWriteCdmaPrlResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_modem.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioModemResponse::nvWriteItemResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioModemResponse::nvWriteItemResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_modem.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioModemResponse::requestShutdownResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioModemResponse::requestShutdownResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_modem.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioModemResponse::sendDeviceStateResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioModemResponse::sendDeviceStateResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_modem.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioModemResponse::setRadioCapabilityResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioModemResponse::setRadioCapabilityResponse(const RadioResponseInfo& info,
const RadioCapability& /*rc*/) {
+ rspInfo = info;
+ parent_modem.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
diff --git a/radio/aidl/vts/radio_modem_test.cpp b/radio/aidl/vts/radio_modem_test.cpp
index b40bb7b..f88da13 100644
--- a/radio/aidl/vts/radio_modem_test.cpp
+++ b/radio/aidl/vts/radio_modem_test.cpp
@@ -87,3 +87,301 @@
EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error);
}
+
+/*
+ * Test IRadioModem.enableModem() for the response returned.
+ */
+TEST_P(RadioModemTest, enableModem) {
+ serial = GetRandomSerialNumber();
+
+ if (isSsSsEnabled()) {
+ ALOGI("enableModem, no need to test in single SIM mode");
+ return;
+ }
+
+ bool responseToggle = radioRsp_modem->enableModemResponseToggle;
+ ndk::ScopedAStatus res = radio_modem->enableModem(serial, true);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+ ALOGI("getModemStackStatus, rspInfo.error = %s\n",
+ toString(radioRsp_modem->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::INVALID_STATE}));
+
+ // checking if getModemStackStatus returns true, as modem was enabled above
+ if (RadioError::NONE == radioRsp_modem->rspInfo.error) {
+ // wait until modem enabling is finished
+ while (responseToggle == radioRsp_modem->enableModemResponseToggle) {
+ sleep(1);
+ }
+ ndk::ScopedAStatus resEnabled = radio_modem->getModemStackStatus(serial);
+ ASSERT_OK(resEnabled);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+ ALOGI("getModemStackStatus, rspInfo.error = %s\n",
+ toString(radioRsp_modem->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::INVALID_STATE}));
+ // verify that enableModem did set isEnabled correctly
+ EXPECT_EQ(true, radioRsp_modem->isModemEnabled);
+ }
+}
+
+/*
+ * Test IRadioModem.getModemStackStatus() for the response returned.
+ */
+TEST_P(RadioModemTest, getModemStackStatus) {
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res = radio_modem->getModemStackStatus(serial);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+ ALOGI("getModemStackStatus, rspInfo.error = %s\n",
+ toString(radioRsp_modem->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_modem->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+}
+
+/*
+ * Test IRadioModem.getBasebandVersion() for the response returned.
+ */
+TEST_P(RadioModemTest, getBasebandVersion) {
+ LOG(DEBUG) << "getBasebandVersion";
+ serial = GetRandomSerialNumber();
+
+ radio_modem->getBasebandVersion(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error);
+ }
+ LOG(DEBUG) << "getBasebandVersion finished";
+}
+
+/*
+ * Test IRadioModem.getDeviceIdentity() for the response returned.
+ */
+TEST_P(RadioModemTest, getDeviceIdentity) {
+ LOG(DEBUG) << "getDeviceIdentity";
+ serial = GetRandomSerialNumber();
+
+ radio_modem->getDeviceIdentity(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+ {RadioError::NONE, RadioError::EMPTY_RECORD}));
+ }
+ LOG(DEBUG) << "getDeviceIdentity finished";
+}
+
+/*
+ * Test IRadioModem.nvReadItem() for the response returned.
+ */
+TEST_P(RadioModemTest, nvReadItem) {
+ LOG(DEBUG) << "nvReadItem";
+ serial = GetRandomSerialNumber();
+
+ radio_modem->nvReadItem(serial, NvItem::LTE_BAND_ENABLE_25);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "nvReadItem finished";
+}
+
+/*
+ * Test IRadioModem.nvWriteItem() for the response returned.
+ */
+TEST_P(RadioModemTest, nvWriteItem) {
+ LOG(DEBUG) << "nvWriteItem";
+ serial = GetRandomSerialNumber();
+ NvWriteItem item;
+ memset(&item, 0, sizeof(item));
+ item.value = std::string();
+
+ radio_modem->nvWriteItem(serial, item);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "nvWriteItem finished";
+}
+
+/*
+ * Test IRadioModem.nvWriteCdmaPrl() for the response returned.
+ */
+TEST_P(RadioModemTest, nvWriteCdmaPrl) {
+ LOG(DEBUG) << "nvWriteCdmaPrl";
+ serial = GetRandomSerialNumber();
+ std::vector<uint8_t> prl = {1, 2, 3, 4, 5};
+
+ radio_modem->nvWriteCdmaPrl(serial, std::vector<uint8_t>(prl));
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "nvWriteCdmaPrl finished";
+}
+
+/*
+ * Test IRadioModem.nvResetConfig() for the response returned.
+ */
+TEST_P(RadioModemTest, nvResetConfig) {
+ LOG(DEBUG) << "nvResetConfig";
+ serial = GetRandomSerialNumber();
+
+ radio_modem->nvResetConfig(serial, ResetNvType::FACTORY_RESET);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+ LOG(DEBUG) << "nvResetConfig finished";
+}
+
+/*
+ * Test IRadioModem.getHardwareConfig() for the response returned.
+ */
+TEST_P(RadioModemTest, getHardwareConfig) {
+ LOG(DEBUG) << "getHardwareConfig";
+ serial = GetRandomSerialNumber();
+
+ radio_modem->getHardwareConfig(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "getHardwareConfig finished";
+}
+
+/*
+ * The following test is disabled due to b/64734869
+ *
+ * Test IRadioModem.requestShutdown() for the response returned.
+ */
+TEST_P(RadioModemTest, DISABLED_requestShutdown) {
+ serial = GetRandomSerialNumber();
+
+ radio_modem->requestShutdown(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
+ CHECK_GENERAL_ERROR));
+ }
+}
+
+/*
+ * Test IRadioModem.getRadioCapability() for the response returned.
+ */
+TEST_P(RadioModemTest, getRadioCapability) {
+ LOG(DEBUG) << "getRadioCapability";
+ serial = GetRandomSerialNumber();
+
+ radio_modem->getRadioCapability(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error);
+ }
+ LOG(DEBUG) << "getRadioCapability finished";
+}
+
+/*
+ * Test IRadioModem.setRadioCapability() for the response returned.
+ */
+TEST_P(RadioModemTest, setRadioCapability) {
+ LOG(DEBUG) << "setRadioCapability";
+ serial = GetRandomSerialNumber();
+ RadioCapability rc;
+ memset(&rc, 0, sizeof(rc));
+ rc.logicalModemUuid = std::string();
+
+ radio_modem->setRadioCapability(serial, rc);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "setRadioCapability finished";
+}
+
+/*
+ * Test IRadioModem.getModemActivityInfo() for the response returned.
+ */
+TEST_P(RadioModemTest, getModemActivityInfo) {
+ LOG(DEBUG) << "getModemActivityInfo";
+ serial = GetRandomSerialNumber();
+
+ radio_modem->getModemActivityInfo(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+ LOG(DEBUG) << "getModemActivityInfo finished";
+}
+
+/*
+ * Test IRadioModem.sendDeviceState() for the response returned.
+ */
+TEST_P(RadioModemTest, sendDeviceState) {
+ LOG(DEBUG) << "sendDeviceState";
+ serial = GetRandomSerialNumber();
+
+ radio_modem->sendDeviceState(serial, DeviceStateType::POWER_SAVE_MODE, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+ std::cout << static_cast<int>(radioRsp_modem->rspInfo.error) << std::endl;
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+ LOG(DEBUG) << "sendDeviceState finished";
+}
diff --git a/radio/aidl/vts/radio_network_response.cpp b/radio/aidl/vts/radio_network_response.cpp
index 9df1db4..666d617 100644
--- a/radio/aidl/vts/radio_network_response.cpp
+++ b/radio/aidl/vts/radio_network_response.cpp
@@ -31,7 +31,10 @@
}
ndk::ScopedAStatus RadioNetworkResponse::getAvailableBandModesResponse(
- const RadioResponseInfo& /*info*/, const std::vector<RadioBandMode>& /*bandModes*/) {
+ const RadioResponseInfo& info, const std::vector<RadioBandMode>& bandModes) {
+ rspInfo = info;
+ radioBandModes = bandModes;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -44,48 +47,64 @@
}
ndk::ScopedAStatus RadioNetworkResponse::getBarringInfoResponse(
- const RadioResponseInfo& /*info*/, const CellIdentity& /*cellIdentity*/,
- const std::vector<BarringInfo>& /*barringInfos*/) {
+ const RadioResponseInfo& info, const CellIdentity& cellIdentity,
+ const std::vector<BarringInfo>& barringInfos) {
+ rspInfo = info;
+ barringCellIdentity = cellIdentity;
+ barringInfoList = barringInfos;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioNetworkResponse::getCdmaRoamingPreferenceResponse(
- const RadioResponseInfo& /*info*/, CdmaRoamingType /*type*/) {
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus RadioNetworkResponse::getCellInfoListResponse(
- const RadioResponseInfo& /*info*/, const std::vector<CellInfo>& /*cellInfo*/) {
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus RadioNetworkResponse::getDataRegistrationStateResponse(
- const RadioResponseInfo& info, const RegStateResult& /*regResponse*/) {
+ const RadioResponseInfo& info, CdmaRoamingType /*type*/) {
rspInfo = info;
parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus RadioNetworkResponse::getCellInfoListResponse(
+ const RadioResponseInfo& info, const std::vector<CellInfo>& /*cellInfo*/) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getDataRegistrationStateResponse(
+ const RadioResponseInfo& info, const RegStateResult& regResponse) {
+ rspInfo = info;
+ dataRegResp = regResponse;
+ parent_network.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus RadioNetworkResponse::getImsRegistrationStateResponse(
- const RadioResponseInfo& /*info*/, bool /*isRegistered*/,
- RadioTechnologyFamily /*ratFamily*/) {
+ const RadioResponseInfo& info, bool /*isRegistered*/, RadioTechnologyFamily /*ratFamily*/) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioNetworkResponse::getNetworkSelectionModeResponse(
- const RadioResponseInfo& /*info*/, bool /*manual*/) {
+ const RadioResponseInfo& info, bool /*manual*/) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioNetworkResponse::getOperatorResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioNetworkResponse::getOperatorResponse(const RadioResponseInfo& info,
const std::string& /*longName*/,
const std::string& /*shortName*/,
const std::string& /*numeric*/) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioNetworkResponse::getSignalStrengthResponse(
- const RadioResponseInfo& /*info*/, const SignalStrength& /*sig_strength*/) {
+ const RadioResponseInfo& info, const SignalStrength& /*sig_strength*/) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -96,20 +115,25 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioNetworkResponse::getUsageSettingResponse(
- const RadioResponseInfo& /*info*/, const UsageSetting /*usageSetting*/) {
+ndk::ScopedAStatus RadioNetworkResponse::getUsageSettingResponse(const RadioResponseInfo& info,
+ const UsageSetting usageSetting) {
+ rspInfo = info;
+ this->usageSetting = usageSetting;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioNetworkResponse::getVoiceRadioTechnologyResponse(
- const RadioResponseInfo& /*info*/, RadioTechnology /*rat*/) {
+ const RadioResponseInfo& info, RadioTechnology /*rat*/) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioNetworkResponse::getVoiceRegistrationStateResponse(
const RadioResponseInfo& info, const RegStateResult& regResponse) {
rspInfo = info;
- voiceRegResp.regState = regResponse.regState;
+ voiceRegResp = regResponse;
parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -129,47 +153,63 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioNetworkResponse::setBandModeResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioNetworkResponse::setBandModeResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioNetworkResponse::setBarringPasswordResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioNetworkResponse::setBarringPasswordResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioNetworkResponse::setCdmaRoamingPreferenceResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioNetworkResponse::setCellInfoListRateResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioNetworkResponse::setIndicationFilterResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioNetworkResponse::setLinkCapacityReportingCriteriaResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioNetworkResponse::setLocationUpdatesResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioNetworkResponse::setLocationUpdatesResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioNetworkResponse::setNetworkSelectionModeAutomaticResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioNetworkResponse::setNetworkSelectionModeManualResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -181,36 +221,47 @@
}
ndk::ScopedAStatus RadioNetworkResponse::setSignalStrengthReportingCriteriaResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioNetworkResponse::setSuppServiceNotificationsResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioNetworkResponse::setSystemSelectionChannelsResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioNetworkResponse::setUsageSettingResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioNetworkResponse::setUsageSettingResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioNetworkResponse::startNetworkScanResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioNetworkResponse::startNetworkScanResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioNetworkResponse::stopNetworkScanResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioNetworkResponse::stopNetworkScanResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioNetworkResponse::supplyNetworkDepersonalizationResponse(
- const RadioResponseInfo& /*info*/, int32_t /*remainingRetries*/) {
+ const RadioResponseInfo& info, int32_t /*remainingRetries*/) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 64d8eec..e1d508d 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -16,6 +16,7 @@
#include <aidl/android/hardware/radio/RadioAccessFamily.h>
#include <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <aidl/android/hardware/radio/network/IndicationFilter.h>
#include <android-base/logging.h>
#include <android/binder_manager.h>
@@ -58,6 +59,12 @@
ASSERT_NE(nullptr, radio_config.get());
}
+void RadioNetworkTest::stopNetworkScan() {
+ serial = GetRandomSerialNumber();
+ radio_network->stopNetworkScan(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+}
+
/*
* Test IRadioNetwork.setAllowedNetworkTypesBitmap for the response returned.
*/
@@ -152,4 +159,1578 @@
radioRsp_network->rspInfo.error,
{RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR, RadioError::NONE}));
}
-}
\ No newline at end of file
+}
+
+void RadioNetworkTest::invokeAndExpectResponse(
+ std::function<ndk::ScopedAStatus(int32_t serial)> request,
+ std::vector<RadioError> errors_to_check) {
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res = request(serial);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, errors_to_check));
+}
+
+/*
+ * Test IRadioNetwork.getUsageSetting()
+ *
+ * Verify that the usage setting can be retrieved.
+ */
+TEST_P(RadioNetworkTest, getUsageSetting) {
+ invokeAndExpectResponse([&](int serial) { return radio_network->getUsageSetting(serial); },
+ {RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_STATE,
+ RadioError::SIM_ABSENT, RadioError::INTERNAL_ERR, RadioError::NONE});
+
+ ASSERT_TRUE(radioRsp_network->usageSetting == UsageSetting::VOICE_CENTRIC ||
+ radioRsp_network->usageSetting == UsageSetting::DATA_CENTRIC);
+}
+
+void RadioNetworkTest::testSetUsageSetting_InvalidValues(std::vector<RadioError> errors) {
+ invokeAndExpectResponse(
+ [&](int serial) {
+ return radio_network->setUsageSetting(serial,
+ UsageSetting(0) /*below valid range*/);
+ },
+ errors);
+ invokeAndExpectResponse(
+ [&](int serial) {
+ return radio_network->setUsageSetting(serial, UsageSetting(-1) /*negative*/);
+ },
+ errors);
+ invokeAndExpectResponse(
+ [&](int serial) {
+ return radio_network->setUsageSetting(serial,
+ UsageSetting(3) /*above valid range*/);
+ },
+ errors);
+}
+
+/*
+ * Test IRadioNetwork.setUsageSetting() and IRadioNetwork.getUsageSetting()
+ *
+ * Verify the following:
+ * -That the usage setting can be retrieved.
+ * -That the usage setting can be successfully set to allowed values.
+ * -That the usage setting cannot be set to invalid values.
+ */
+TEST_P(RadioNetworkTest, setUsageSetting) {
+ invokeAndExpectResponse([&](int serial) { return radio_network->getUsageSetting(serial); },
+ {RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_STATE,
+ RadioError::SIM_ABSENT, RadioError::INTERNAL_ERR, RadioError::NONE});
+
+ if (radioRsp_network->rspInfo.error != RadioError::NONE) {
+ // Test only for invalid values, with the only allowable response being the same error
+ // that was previously provided, or an error indicating invalid arguments.
+ testSetUsageSetting_InvalidValues(
+ {radioRsp_network->rspInfo.error, RadioError::INVALID_ARGUMENTS});
+ // It is unsafe to proceed with setting valid values without knowing the starting value, but
+ // we expect errors anyway, so not necessary.
+ return;
+ } else {
+ // Because querying succeeded, the device is in a valid state to test for invalid values
+ // and the only thing that can change is that we expect to have an EINVAL return each time.
+ testSetUsageSetting_InvalidValues({RadioError::INVALID_ARGUMENTS});
+ }
+
+ // Store the original setting value to reset later.
+ const UsageSetting originalSetting = radioRsp_network->usageSetting;
+
+ // Choose the "other" value that is not the current value for test.
+ const UsageSetting testSetting = radioRsp_network->usageSetting == UsageSetting::VOICE_CENTRIC
+ ? UsageSetting::DATA_CENTRIC
+ : UsageSetting::VOICE_CENTRIC;
+
+ // Set an alternative setting; it may either succeed or be disallowed as out of range for
+ // the current device (if the device only supports its current mode).
+ invokeAndExpectResponse(
+ [&](int serial) { return radio_network->setUsageSetting(serial, testSetting); },
+ {RadioError::INVALID_ARGUMENTS, RadioError::NONE});
+
+ // If there was no error, then we expect the test setting to be set, or if there is an error
+ // we expect the original setting to be maintained.
+ const UsageSetting expectedSetting =
+ radioRsp_network->rspInfo.error == RadioError::NONE ? testSetting : originalSetting;
+ invokeAndExpectResponse([&](int serial) { return radio_network->getUsageSetting(serial); },
+ {RadioError::NONE});
+
+ const UsageSetting updatedSetting = radioRsp_network->usageSetting;
+
+ // Re-set the original setting, which must always succeed.
+ invokeAndExpectResponse(
+ [&](int serial) { return radio_network->setUsageSetting(serial, originalSetting); },
+ {RadioError::NONE});
+
+ // After resetting the value to its original value, update the local cache, which must
+ // always succeed.
+ invokeAndExpectResponse([&](int serial) { return radio_network->getUsageSetting(serial); },
+ {RadioError::NONE});
+
+ // Check that indeed the updated setting was set. We do this after resetting to original
+ // conditions to avoid early-exiting the test and leaving the device in a modified state.
+ EXPECT_EQ(expectedSetting, updatedSetting);
+ // Check that indeed the original setting was reset.
+ EXPECT_EQ(originalSetting, radioRsp_network->usageSetting);
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() with invalid hysteresisDb
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_invalidHysteresisDb) {
+ serial = GetRandomSerialNumber();
+
+ SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
+ signalThresholdInfo.hysteresisMs = 5000;
+ signalThresholdInfo.hysteresisDb = 10; // hysteresisDb too large given threshold list deltas
+ signalThresholdInfo.thresholds = {-109, -103, -97, -89};
+ signalThresholdInfo.isEnabled = true;
+ signalThresholdInfo.ran = AccessNetwork::GERAN;
+
+ ndk::ScopedAStatus res =
+ radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_invalidHysteresisDb, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() with empty thresholds
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_EmptyThresholds) {
+ serial = GetRandomSerialNumber();
+
+ SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
+ signalThresholdInfo.hysteresisMs = 0;
+ signalThresholdInfo.hysteresisDb = 0;
+ signalThresholdInfo.isEnabled = true;
+ signalThresholdInfo.ran = AccessNetwork::GERAN;
+
+ ndk::ScopedAStatus res =
+ radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_EmptyParams, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for GERAN
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Geran) {
+ serial = GetRandomSerialNumber();
+
+ SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
+ signalThresholdInfo.hysteresisMs = 5000;
+ signalThresholdInfo.hysteresisDb = 2;
+ signalThresholdInfo.thresholds = {-109, -103, -97, -89};
+ signalThresholdInfo.isEnabled = true;
+ signalThresholdInfo.ran = AccessNetwork::GERAN;
+
+ ndk::ScopedAStatus res =
+ radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_Geran, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for UTRAN
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Utran) {
+ serial = GetRandomSerialNumber();
+
+ SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSCP;
+ signalThresholdInfo.hysteresisMs = 5000;
+ signalThresholdInfo.hysteresisDb = 2;
+ signalThresholdInfo.thresholds = {-110, -97, -73, -49, -25};
+ signalThresholdInfo.isEnabled = true;
+ signalThresholdInfo.ran = AccessNetwork::UTRAN;
+
+ ndk::ScopedAStatus res =
+ radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_Utran, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for EUTRAN
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Eutran_RSRP) {
+ serial = GetRandomSerialNumber();
+
+ SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSRP;
+ signalThresholdInfo.hysteresisMs = 5000;
+ signalThresholdInfo.hysteresisDb = 2;
+ signalThresholdInfo.thresholds = {-128, -108, -88, -68};
+ signalThresholdInfo.isEnabled = true;
+ signalThresholdInfo.ran = AccessNetwork::EUTRAN;
+
+ ndk::ScopedAStatus res =
+ radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_Eutran, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for EUTRAN
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Eutran_RSRQ) {
+ serial = GetRandomSerialNumber();
+
+ SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSRQ;
+ signalThresholdInfo.hysteresisMs = 5000;
+ signalThresholdInfo.hysteresisDb = 2;
+ signalThresholdInfo.thresholds = {-27, -20, -13, -6};
+ signalThresholdInfo.isEnabled = true;
+ signalThresholdInfo.ran = AccessNetwork::EUTRAN;
+
+ ndk::ScopedAStatus res =
+ radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_Eutran, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for EUTRAN
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Eutran_RSSNR) {
+ serial = GetRandomSerialNumber();
+
+ SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSNR;
+ signalThresholdInfo.hysteresisMs = 5000;
+ signalThresholdInfo.hysteresisDb = 2;
+ signalThresholdInfo.thresholds = {-10, 0, 10, 20};
+ signalThresholdInfo.isEnabled = true;
+ signalThresholdInfo.ran = AccessNetwork::EUTRAN;
+
+ ndk::ScopedAStatus res =
+ radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for CDMA2000
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Cdma2000) {
+ serial = GetRandomSerialNumber();
+
+ SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
+ signalThresholdInfo.hysteresisMs = 5000;
+ signalThresholdInfo.hysteresisDb = 2;
+ signalThresholdInfo.thresholds = {-105, -90, -75, -65};
+ signalThresholdInfo.isEnabled = true;
+ signalThresholdInfo.ran = AccessNetwork::CDMA2000;
+
+ ndk::ScopedAStatus res =
+ radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_Cdma2000, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for NGRAN_SSRSRP
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_NGRAN_SSRSRP) {
+ serial = GetRandomSerialNumber();
+
+ SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_SSRSRP;
+ signalThresholdInfo.hysteresisMs = 5000;
+ signalThresholdInfo.hysteresisDb = 0;
+ signalThresholdInfo.thresholds = {-105, -90, -75, -65};
+ signalThresholdInfo.isEnabled = true;
+ signalThresholdInfo.ran = AccessNetwork::NGRAN;
+
+ ndk::ScopedAStatus res =
+ radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_NGRAN_SSRSRP, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+
+ // Allow REQUEST_NOT_SUPPORTED because some non-5G device may not support NGRAN for
+ // setSignalStrengthReportingCriteria()
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for NGRAN_SSRSRQ
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_NGRAN_SSRSRQ) {
+ serial = GetRandomSerialNumber();
+
+ SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_SSRSRQ;
+ signalThresholdInfo.hysteresisMs = 5000;
+ signalThresholdInfo.hysteresisDb = 0;
+ signalThresholdInfo.thresholds = {-43, -20, 0, 20};
+ signalThresholdInfo.isEnabled = true;
+ signalThresholdInfo.ran = AccessNetwork::NGRAN;
+
+ ndk::ScopedAStatus res =
+ radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_NGRAN_SSRSRQ, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+
+ // Allow REQUEST_NOT_SUPPORTED because some non-5G device may not support NGRAN for
+ // setSignalStrengthReportingCriteria()
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for EUTRAN
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Disable_RSSNR) {
+ serial = GetRandomSerialNumber();
+
+ SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSNR;
+ signalThresholdInfo.hysteresisMs = 5000;
+ signalThresholdInfo.hysteresisDb = 2;
+ signalThresholdInfo.thresholds = {-10, 0, 10, 20};
+ signalThresholdInfo.isEnabled = false;
+ signalThresholdInfo.ran = AccessNetwork::EUTRAN;
+
+ ndk::ScopedAStatus res =
+ radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for NGRAN_SSSINR
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_NGRAN_SSSINR) {
+ serial = GetRandomSerialNumber();
+
+ SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_SSSINR;
+ signalThresholdInfo.hysteresisMs = 5000;
+ signalThresholdInfo.hysteresisDb = 0;
+ signalThresholdInfo.thresholds = {-10, 3, 16, 18};
+ signalThresholdInfo.isEnabled = true;
+ signalThresholdInfo.ran = AccessNetwork::NGRAN;
+
+ ndk::ScopedAStatus res =
+ radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_NGRAN_SSSINR, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+
+ // Allow REQUEST_NOT_SUPPORTED because some non-5G device may not support NGRAN for
+ // setSignalStrengthReportingCriteria()
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setLinkCapacityReportingCriteria() invalid hysteresisDlKbps
+ */
+TEST_P(RadioNetworkTest, setLinkCapacityReportingCriteria_invalidHysteresisDlKbps) {
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res = radio_network->setLinkCapacityReportingCriteria(
+ serial, 5000,
+ 5000, // hysteresisDlKbps too big for thresholds delta
+ 100, {1000, 5000, 10000, 20000}, {500, 1000, 5000, 10000}, AccessNetwork::GERAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setLinkCapacityReportingCriteria_invalidHysteresisDlKbps, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ // Allow REQUEST_NOT_SUPPORTED as setLinkCapacityReportingCriteria() may not be supported
+ // for GERAN
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setLinkCapacityReportingCriteria() invalid hysteresisUlKbps
+ */
+TEST_P(RadioNetworkTest, setLinkCapacityReportingCriteria_invalidHysteresisUlKbps) {
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res = radio_network->setLinkCapacityReportingCriteria(
+ serial, 5000, 500, 1000, // hysteresisUlKbps too big for thresholds delta
+ {1000, 5000, 10000, 20000}, {500, 1000, 5000, 10000}, AccessNetwork::GERAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setLinkCapacityReportingCriteria_invalidHysteresisUlKbps, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ // Allow REQUEST_NOT_SUPPORTED as setLinkCapacityReportingCriteria() may not be supported
+ // for GERAN
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setLinkCapacityReportingCriteria() empty params
+ */
+TEST_P(RadioNetworkTest, setLinkCapacityReportingCriteria_emptyParams) {
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res = radio_network->setLinkCapacityReportingCriteria(
+ serial, 0, 0, 0, {}, {}, AccessNetwork::GERAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setLinkCapacityReportingCriteria_emptyParams, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ // Allow REQUEST_NOT_SUPPORTED as setLinkCapacityReportingCriteria() may not be supported
+ // for GERAN
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setLinkCapacityReportingCriteria() for GERAN
+ */
+TEST_P(RadioNetworkTest, setLinkCapacityReportingCriteria_Geran) {
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res = radio_network->setLinkCapacityReportingCriteria(
+ serial, 5000, 500, 100, {1000, 5000, 10000, 20000}, {500, 1000, 5000, 10000},
+ AccessNetwork::GERAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setLinkCapacityReportingCriteria_Geran, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ // Allow REQUEST_NOT_SUPPORTED as setLinkCapacityReportingCriteria() may not be supported
+ // for GERAN
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setSystemSelectionChannels() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setSystemSelectionChannels) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifierBands bandP900 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_P900});
+ RadioAccessSpecifierBands band850 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_850});
+ RadioAccessSpecifier specifierP900 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+ RadioAccessSpecifier specifier850 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+ ndk::ScopedAStatus res =
+ radio_network->setSystemSelectionChannels(serial, true, {specifierP900, specifier850});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ALOGI("setSystemSelectionChannels, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR}));
+
+ if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+ serial = GetRandomSerialNumber();
+ ndk::ScopedAStatus res = radio_network->setSystemSelectionChannels(
+ serial, false, {specifierP900, specifier850});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ALOGI("setSystemSelectionChannels, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() for the response returned.
+ */
+TEST_P(RadioNetworkTest, startNetworkScan) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifierBands bandP900 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_P900});
+ RadioAccessSpecifierBands band850 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_850});
+ RadioAccessSpecifier specifierP900 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+ RadioAccessSpecifier specifier850 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+ NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifierP900, specifier850},
+ .maxSearchTime = 60,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ALOGI("startNetworkScan, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::SIM_ABSENT}));
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ // OPERATION_NOT_ALLOWED should not be allowed; however, some vendors do
+ // not support the required manual GSM search functionality. This is
+ // tracked in b/112206766. Modems have "GSM" rat scan need to
+ // support scanning requests combined with some parameters.
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED}));
+ }
+
+ if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+ ALOGI("Stop Network Scan");
+ stopNetworkScan();
+ }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with invalid specifier.
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_InvalidArgument) {
+ serial = GetRandomSerialNumber();
+
+ NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT, .interval = 60};
+
+ ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidArgument, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with invalid interval (lower boundary).
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_InvalidInterval1) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifierBands bandP900 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_P900});
+ RadioAccessSpecifierBands band850 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_850});
+ RadioAccessSpecifier specifierP900 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+ RadioAccessSpecifier specifier850 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+ NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+ .interval = 4,
+ .specifiers = {specifierP900, specifier850},
+ .maxSearchTime = 60,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidInterval1, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with invalid interval (upper boundary).
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_InvalidInterval2) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifierBands bandP900 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_P900});
+ RadioAccessSpecifierBands band850 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_850});
+ RadioAccessSpecifier specifierP900 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+ RadioAccessSpecifier specifier850 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+ NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+ .interval = 301,
+ .specifiers = {specifierP900, specifier850},
+ .maxSearchTime = 60,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidInterval2, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with invalid max search time (lower boundary).
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_InvalidMaxSearchTime1) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifierBands bandP900 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_P900});
+ RadioAccessSpecifierBands band850 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_850});
+ RadioAccessSpecifier specifierP900 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+ RadioAccessSpecifier specifier850 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+ NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifierP900, specifier850},
+ .maxSearchTime = 59,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidMaxSearchTime1, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with invalid max search time (upper boundary).
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_InvalidMaxSearchTime2) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifierBands bandP900 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_P900});
+ RadioAccessSpecifierBands band850 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_850});
+ RadioAccessSpecifier specifierP900 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+ RadioAccessSpecifier specifier850 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+ NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifierP900, specifier850},
+ .maxSearchTime = 3601,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidMaxSearchTime2, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with invalid periodicity (lower boundary).
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_InvalidPeriodicity1) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifierBands bandP900 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_P900});
+ RadioAccessSpecifierBands band850 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_850});
+ RadioAccessSpecifier specifierP900 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+ RadioAccessSpecifier specifier850 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+ NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifierP900, specifier850},
+ .maxSearchTime = 600,
+ .incrementalResults = true,
+ .incrementalResultsPeriodicity = 0};
+
+ ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidPeriodicity1, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with invalid periodicity (upper boundary).
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_InvalidPeriodicity2) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifierBands bandP900 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_P900});
+ RadioAccessSpecifierBands band850 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_850});
+ RadioAccessSpecifier specifierP900 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+ RadioAccessSpecifier specifier850 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+ NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifierP900, specifier850},
+ .maxSearchTime = 600,
+ .incrementalResults = true,
+ .incrementalResultsPeriodicity = 11};
+
+ ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidPeriodicity2, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with valid periodicity
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_GoodRequest1) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifierBands bandP900 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_P900});
+ RadioAccessSpecifierBands band850 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_850});
+ RadioAccessSpecifier specifierP900 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+ RadioAccessSpecifier specifier850 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+ NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifierP900, specifier850},
+ .maxSearchTime = 360,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 10};
+
+ ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ALOGI("startNetworkScan_GoodRequest1, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT}));
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+ RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+
+ if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+ ALOGI("Stop Network Scan");
+ stopNetworkScan();
+ }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with valid periodicity and plmns
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_GoodRequest2) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifierBands bandP900 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_P900});
+ RadioAccessSpecifierBands band850 =
+ RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+ {GeranBands::BAND_850});
+ RadioAccessSpecifier specifierP900 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+ RadioAccessSpecifier specifier850 = {
+ .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+ NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifierP900, specifier850},
+ .maxSearchTime = 360,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 10,
+ .mccMncs = {"310410"}};
+
+ ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ALOGI("startNetworkScan_GoodRequest2, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT}));
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+ RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+
+ if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+ ALOGI("Stop Network Scan");
+ stopNetworkScan();
+ }
+}
+
+/*
+ * Test IRadioNetwork.setNetworkSelectionModeManual() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setNetworkSelectionModeManual) {
+ serial = GetRandomSerialNumber();
+
+ // can't camp on nonexistent MCCMNC, so we expect this to fail.
+ ndk::ScopedAStatus res =
+ radio_network->setNetworkSelectionModeManual(serial, "123456", AccessNetwork::GERAN);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::ILLEGAL_SIM_OR_ME,
+ RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE},
+ CHECK_GENERAL_ERROR));
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE},
+ CHECK_GENERAL_ERROR));
+ }
+}
+
+/*
+ * Test IRadioNetwork.getBarringInfo() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getBarringInfo) {
+ serial = GetRandomSerialNumber();
+ ndk::ScopedAStatus res = radio_network->getBarringInfo(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ASSERT_TRUE(radioRsp_network->barringInfoList.size() > 0);
+
+ std::set<int> reportedServices;
+
+ // validate that the service types are in range
+ for (const auto& info : radioRsp_network->barringInfoList) {
+ ASSERT_TRUE((info.serviceType >= BarringInfo::SERVICE_TYPE_CS_SERVICE &&
+ info.serviceType <= BarringInfo::SERVICE_TYPE_SMS) ||
+ (info.serviceType >= BarringInfo::SERVICE_TYPE_OPERATOR_1 &&
+ info.serviceType <= BarringInfo::SERVICE_TYPE_OPERATOR_32));
+ reportedServices.insert(info.serviceType);
+
+ // Any type that is "conditional" must have valid values for conditional barring
+ // factor and time.
+ switch (info.barringType) {
+ case BarringInfo::BARRING_TYPE_NONE: // fall through
+ case BarringInfo::BARRING_TYPE_UNCONDITIONAL:
+ break;
+ case BarringInfo::BARRING_TYPE_CONDITIONAL: {
+ const int32_t barringFactor = info.barringTypeSpecificInfo->factor;
+ ASSERT_TRUE(barringFactor >= 0 && barringFactor <= 100);
+ ASSERT_TRUE(info.barringTypeSpecificInfo->timeSeconds > 0);
+ break;
+ }
+ default:
+ FAIL();
+ }
+ }
+
+ // Certain types of barring are relevant for certain RANs. Ensure that only the right
+ // types are reported. Note that no types are required, simply that for a given technology
+ // only certain types are valid. This is one way to check that implementations are
+ // not providing information that they don't have.
+ static const std::set<int> UTRA_SERVICES{
+ BarringInfo::SERVICE_TYPE_CS_SERVICE, BarringInfo::SERVICE_TYPE_PS_SERVICE,
+ BarringInfo::SERVICE_TYPE_CS_VOICE, BarringInfo::SERVICE_TYPE_EMERGENCY,
+ BarringInfo::SERVICE_TYPE_SMS,
+ };
+
+ static const std::set<int> EUTRA_SERVICES{
+ BarringInfo::SERVICE_TYPE_MO_SIGNALLING, BarringInfo::SERVICE_TYPE_MO_DATA,
+ BarringInfo::SERVICE_TYPE_CS_FALLBACK, BarringInfo::SERVICE_TYPE_MMTEL_VOICE,
+ BarringInfo::SERVICE_TYPE_MMTEL_VIDEO, BarringInfo::SERVICE_TYPE_EMERGENCY,
+ BarringInfo::SERVICE_TYPE_SMS,
+ };
+
+ static const std::set<int> NGRA_SERVICES = {
+ BarringInfo::SERVICE_TYPE_MO_SIGNALLING, BarringInfo::SERVICE_TYPE_MO_DATA,
+ BarringInfo::SERVICE_TYPE_CS_FALLBACK, BarringInfo::SERVICE_TYPE_MMTEL_VOICE,
+ BarringInfo::SERVICE_TYPE_MMTEL_VIDEO, BarringInfo::SERVICE_TYPE_EMERGENCY,
+ BarringInfo::SERVICE_TYPE_SMS, BarringInfo::SERVICE_TYPE_OPERATOR_1,
+ BarringInfo::SERVICE_TYPE_OPERATOR_2, BarringInfo::SERVICE_TYPE_OPERATOR_3,
+ BarringInfo::SERVICE_TYPE_OPERATOR_4, BarringInfo::SERVICE_TYPE_OPERATOR_5,
+ BarringInfo::SERVICE_TYPE_OPERATOR_6, BarringInfo::SERVICE_TYPE_OPERATOR_7,
+ BarringInfo::SERVICE_TYPE_OPERATOR_8, BarringInfo::SERVICE_TYPE_OPERATOR_9,
+ BarringInfo::SERVICE_TYPE_OPERATOR_10, BarringInfo::SERVICE_TYPE_OPERATOR_11,
+ BarringInfo::SERVICE_TYPE_OPERATOR_12, BarringInfo::SERVICE_TYPE_OPERATOR_13,
+ BarringInfo::SERVICE_TYPE_OPERATOR_14, BarringInfo::SERVICE_TYPE_OPERATOR_15,
+ BarringInfo::SERVICE_TYPE_OPERATOR_16, BarringInfo::SERVICE_TYPE_OPERATOR_17,
+ BarringInfo::SERVICE_TYPE_OPERATOR_18, BarringInfo::SERVICE_TYPE_OPERATOR_19,
+ BarringInfo::SERVICE_TYPE_OPERATOR_20, BarringInfo::SERVICE_TYPE_OPERATOR_21,
+ BarringInfo::SERVICE_TYPE_OPERATOR_22, BarringInfo::SERVICE_TYPE_OPERATOR_23,
+ BarringInfo::SERVICE_TYPE_OPERATOR_24, BarringInfo::SERVICE_TYPE_OPERATOR_25,
+ BarringInfo::SERVICE_TYPE_OPERATOR_26, BarringInfo::SERVICE_TYPE_OPERATOR_27,
+ BarringInfo::SERVICE_TYPE_OPERATOR_28, BarringInfo::SERVICE_TYPE_OPERATOR_29,
+ BarringInfo::SERVICE_TYPE_OPERATOR_30, BarringInfo::SERVICE_TYPE_OPERATOR_31,
+ };
+
+ const std::set<int>* compareTo = nullptr;
+
+ switch (radioRsp_network->barringCellIdentity.getTag()) {
+ case CellIdentity::Tag::wcdma:
+ // fall through
+ case CellIdentity::Tag::tdscdma:
+ compareTo = &UTRA_SERVICES;
+ break;
+ case CellIdentity::Tag::lte:
+ compareTo = &EUTRA_SERVICES;
+ break;
+ case CellIdentity::Tag::nr:
+ compareTo = &NGRA_SERVICES;
+ break;
+ case CellIdentity::Tag::cdma:
+ // fall through
+ default:
+ FAIL();
+ break;
+ }
+
+ std::set<int> diff;
+
+ std::set_difference(reportedServices.begin(), reportedServices.end(), compareTo->begin(),
+ compareTo->end(), std::inserter(diff, diff.begin()));
+}
+
+/*
+ * Test IRadioNetwork.getSignalStrength() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getSignalStrength) {
+ serial = GetRandomSerialNumber();
+
+ radio_network->getSignalStrength(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error);
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE}));
+ }
+}
+
+/*
+ * Test IRadioNetwork.getCellInfoList() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getCellInfoList) {
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res = radio_network->getCellInfoList(serial);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("getCellInfoList, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::NO_NETWORK_FOUND}));
+}
+
+/*
+ * Test IRadioNetwork.getVoiceRegistrationState() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getVoiceRegistrationState) {
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res = radio_network->getVoiceRegistrationState(serial);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("getVoiceRegistrationStateResponse, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE}));
+}
+
+/*
+ * Test IRadioNetwork.getDataRegistrationState() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getDataRegistrationState) {
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res = radio_network->getDataRegistrationState(serial);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("getDataRegistrationStateResponse, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::NOT_PROVISIONED}));
+
+ // Check the mcc [0, 999] and mnc [0, 999].
+ std::string mcc;
+ std::string mnc;
+ bool checkMccMnc = true;
+ CellIdentity cellIdentity = radioRsp_network->dataRegResp.cellIdentity;
+ switch (cellIdentity.getTag()) {
+ case CellIdentity::noinit: {
+ checkMccMnc = false;
+ break;
+ }
+ case CellIdentity::gsm: {
+ CellIdentityGsm cig = cellIdentity.get<CellIdentity::gsm>();
+ mcc = cig.mcc;
+ mnc = cig.mnc;
+ break;
+ }
+ case CellIdentity::wcdma: {
+ CellIdentityWcdma ciw = cellIdentity.get<CellIdentity::wcdma>();
+ mcc = ciw.mcc;
+ mnc = ciw.mnc;
+ break;
+ }
+ case CellIdentity::tdscdma: {
+ CellIdentityTdscdma cit = cellIdentity.get<CellIdentity::tdscdma>();
+ mcc = cit.mcc;
+ mnc = cit.mnc;
+ break;
+ }
+ case CellIdentity::cdma: {
+ // CellIdentityCdma has no mcc/mnc
+ CellIdentityCdma cic = cellIdentity.get<CellIdentity::cdma>();
+ checkMccMnc = false;
+ break;
+ }
+ case CellIdentity::lte: {
+ CellIdentityLte cil = cellIdentity.get<CellIdentity::lte>();
+ mcc = cil.mcc;
+ mnc = cil.mnc;
+ break;
+ }
+ case CellIdentity::nr: {
+ CellIdentityNr cin = cellIdentity.get<CellIdentity::nr>();
+ mcc = cin.mcc;
+ mnc = cin.mnc;
+ break;
+ }
+ }
+
+ // 32 bit system might return invalid mcc and mnc string "\xff\xff..."
+ if (checkMccMnc && mcc.size() < 4 && mnc.size() < 4) {
+ int mcc_int = stoi(mcc);
+ int mnc_int = stoi(mnc);
+ EXPECT_TRUE(mcc_int >= 0 && mcc_int <= 999);
+ EXPECT_TRUE(mnc_int >= 0 && mnc_int <= 999);
+ }
+
+ // Check for access technology specific info
+ AccessTechnologySpecificInfo info = radioRsp_network->dataRegResp.accessTechnologySpecificInfo;
+ RadioTechnology rat = radioRsp_network->dataRegResp.rat;
+ // TODO: add logic for cdmaInfo
+ if (rat == RadioTechnology::LTE || rat == RadioTechnology::LTE_CA) {
+ ASSERT_EQ(info.getTag(), AccessTechnologySpecificInfo::eutranInfo);
+ } else if (rat == RadioTechnology::NR) {
+ ASSERT_EQ(info.getTag(), AccessTechnologySpecificInfo::ngranNrVopsInfo);
+ }
+}
+
+/*
+ * Test IRadioNetwork.getAvailableBandModes() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getAvailableBandModes) {
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res = radio_network->getAvailableBandModes(serial);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ALOGI("getAvailableBandModes, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::INTERNAL_ERR,
+ // If REQUEST_NOT_SUPPORTED is returned, then it should also be
+ // returned for setBandMode().
+ RadioError::REQUEST_NOT_SUPPORTED}));
+ bool hasUnspecifiedBandMode = false;
+ if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+ for (const RadioBandMode& mode : radioRsp_network->radioBandModes) {
+ // Automatic mode selection must be supported
+ if (mode == RadioBandMode::BAND_MODE_UNSPECIFIED) hasUnspecifiedBandMode = true;
+ }
+ ASSERT_TRUE(hasUnspecifiedBandMode);
+ }
+}
+
+/*
+ * Test IRadioNetwork.setIndicationFilter()
+ */
+TEST_P(RadioNetworkTest, setIndicationFilter) {
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res =
+ radio_network->setIndicationFilter(serial, static_cast<int>(IndicationFilter::ALL));
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setIndicationFilter, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadioNetwork.setBarringPassword() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setBarringPassword) {
+ serial = GetRandomSerialNumber();
+ std::string facility = "";
+ std::string oldPassword = "";
+ std::string newPassword = "";
+
+ radio_network->setBarringPassword(serial, facility, oldPassword, newPassword);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::FDN_CHECK_FAILURE,
+ RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+}
+
+/*
+ * Test IRadioNetwork.setSuppServiceNotifications() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setSuppServiceNotifications) {
+ serial = GetRandomSerialNumber();
+ bool enable = false;
+
+ radio_network->setSuppServiceNotifications(serial, enable);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT}));
+ }
+}
+
+/*
+ * Test IRadioNetwork.getImsRegistrationState() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getImsRegistrationState) {
+ serial = GetRandomSerialNumber();
+
+ radio_network->getImsRegistrationState(serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::MODEM_ERR, RadioError::INVALID_MODEM_STATE},
+ CHECK_GENERAL_ERROR));
+ }
+}
+
+/*
+ * Test IRadioNetwork.getOperator() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getOperator) {
+ LOG(DEBUG) << "getOperator";
+ serial = GetRandomSerialNumber();
+
+ radio_network->getOperator(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error);
+ }
+ LOG(DEBUG) << "getOperator finished";
+}
+
+/*
+ * Test IRadioNetwork.getNetworkSelectionMode() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getNetworkSelectionMode) {
+ LOG(DEBUG) << "getNetworkSelectionMode";
+ serial = GetRandomSerialNumber();
+
+ radio_network->getNetworkSelectionMode(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error);
+ }
+ LOG(DEBUG) << "getNetworkSelectionMode finished";
+}
+
+/*
+ * Test IRadioNetwork.setNetworkSelectionModeAutomatic() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setNetworkSelectionModeAutomatic) {
+ LOG(DEBUG) << "setNetworkSelectionModeAutomatic";
+ serial = GetRandomSerialNumber();
+
+ radio_network->setNetworkSelectionModeAutomatic(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::ILLEGAL_SIM_OR_ME,
+ RadioError::OPERATION_NOT_ALLOWED},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "setNetworkSelectionModeAutomatic finished";
+}
+
+/*
+ * Test IRadioNetwork.getAvailableNetworks() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getAvailableNetworks) {
+ LOG(DEBUG) << "getAvailableNetworks";
+ serial = GetRandomSerialNumber();
+
+ radio_network->getAvailableNetworks(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ASSERT_TRUE(radioRsp_network->rspInfo.type == RadioResponseType::SOLICITED ||
+ radioRsp_network->rspInfo.type == RadioResponseType::SOLICITED_ACK_EXP);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::CANCELLED, RadioError::DEVICE_IN_USE,
+ RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "getAvailableNetworks finished";
+}
+
+/*
+ * Test IRadioNetwork.setBandMode() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setBandMode) {
+ LOG(DEBUG) << "setBandMode";
+ serial = GetRandomSerialNumber();
+
+ radio_network->setBandMode(serial, RadioBandMode::BAND_MODE_USA);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "setBandMode finished";
+}
+
+/*
+ * Test IRadioNetwork.setLocationUpdates() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setLocationUpdates) {
+ LOG(DEBUG) << "setLocationUpdates";
+ serial = GetRandomSerialNumber();
+
+ radio_network->setLocationUpdates(serial, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT}));
+ }
+ LOG(DEBUG) << "setLocationUpdates finished";
+}
+
+/*
+ * Test IRadioNetwork.setCdmaRoamingPreference() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setCdmaRoamingPreference) {
+ LOG(DEBUG) << "setCdmaRoamingPreference";
+ serial = GetRandomSerialNumber();
+
+ radio_network->setCdmaRoamingPreference(serial, CdmaRoamingType::HOME_NETWORK);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+ LOG(DEBUG) << "setCdmaRoamingPreference finished";
+}
+
+/*
+ * Test IRadioNetwork.getCdmaRoamingPreference() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getCdmaRoamingPreference) {
+ LOG(DEBUG) << "getCdmaRoamingPreference";
+ serial = GetRandomSerialNumber();
+
+ radio_network->getCdmaRoamingPreference(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "getCdmaRoamingPreference finished";
+}
+
+/*
+ * Test IRadioNetwork.getVoiceRadioTechnology() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getVoiceRadioTechnology) {
+ LOG(DEBUG) << "getVoiceRadioTechnology";
+ serial = GetRandomSerialNumber();
+
+ radio_network->getVoiceRadioTechnology(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error);
+ }
+ LOG(DEBUG) << "getVoiceRadioTechnology finished";
+}
+
+/*
+ * Test IRadioNetwork.setCellInfoListRate() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setCellInfoListRate) {
+ LOG(DEBUG) << "setCellInfoListRate";
+ serial = GetRandomSerialNumber();
+
+ radio_network->setCellInfoListRate(serial, 10);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+ LOG(DEBUG) << "setCellInfoListRate finished";
+}
+
+/*
+ * Test IRadioNetwork.supplyNetworkDepersonalization() for the response returned.
+ */
+TEST_P(RadioNetworkTest, supplyNetworkDepersonalization) {
+ LOG(DEBUG) << "supplyNetworkDepersonalization";
+ serial = GetRandomSerialNumber();
+
+ radio_network->supplyNetworkDepersonalization(serial, std::string("test"));
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INTERNAL_ERR,
+ RadioError::INVALID_SIM_STATE, RadioError::MODEM_ERR, RadioError::NO_MEMORY,
+ RadioError::PASSWORD_INCORRECT, RadioError::SIM_ABSENT, RadioError::SYSTEM_ERR}));
+ }
+ LOG(DEBUG) << "supplyNetworkDepersonalization finished";
+}
diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h
index c26d7c3..29ba2f2 100644
--- a/radio/aidl/vts/radio_network_utils.h
+++ b/radio/aidl/vts/radio_network_utils.h
@@ -41,8 +41,10 @@
bool isNrDualConnectivityEnabled;
int networkTypeBitmapResponse;
RegStateResult voiceRegResp;
+ RegStateResult dataRegResp;
CellIdentity barringCellIdentity;
- std::vector<BarringInfo> barringInfos;
+ std::vector<BarringInfo> barringInfoList;
+ UsageSetting usageSetting;
virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
@@ -211,4 +213,12 @@
std::shared_ptr<RadioNetworkResponse> radioRsp_network;
/* radio network indication handle */
std::shared_ptr<RadioNetworkIndication> radioInd_network;
+
+ void invokeAndExpectResponse(std::function<ndk::ScopedAStatus(int32_t serial)> request,
+ std::vector<RadioError> errors_to_check);
+
+ // Helper function to reduce copy+paste
+ void testSetUsageSetting_InvalidValues(std::vector<RadioError> errors);
+
+ void stopNetworkScan();
};
diff --git a/radio/aidl/vts/radio_sim_response.cpp b/radio/aidl/vts/radio_sim_response.cpp
index a783f43..391c9cb 100644
--- a/radio/aidl/vts/radio_sim_response.cpp
+++ b/radio/aidl/vts/radio_sim_response.cpp
@@ -23,44 +23,62 @@
}
ndk::ScopedAStatus RadioSimResponse::areUiccApplicationsEnabledResponse(
- const RadioResponseInfo& /*info*/, bool /*enabled*/) {
+ const RadioResponseInfo& info, bool enabled) {
+ rspInfo = info;
+ areUiccApplicationsEnabled = enabled;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::changeIccPin2ForAppResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::changeIccPin2ForAppResponse(const RadioResponseInfo& info,
int32_t /*remainingRetries*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::changeIccPinForAppResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::changeIccPinForAppResponse(const RadioResponseInfo& info,
int32_t /*remainingRetries*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::enableUiccApplicationsResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioSimResponse::enableUiccApplicationsResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioSimResponse::getAllowedCarriersResponse(
- const RadioResponseInfo& /*info*/, const CarrierRestrictions& /*carriers*/,
- SimLockMultiSimPolicy /*multiSimPolicy*/) {
+ const RadioResponseInfo& info, const CarrierRestrictions& carriers,
+ SimLockMultiSimPolicy multiSimPolicy) {
+ rspInfo = info;
+ carrierRestrictionsResp = carriers;
+ multiSimPolicyResp = multiSimPolicy;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioSimResponse::getCdmaSubscriptionResponse(
- const RadioResponseInfo& /*info*/, const std::string& /*mdn*/, const std::string& /*hSid*/,
+ const RadioResponseInfo& info, const std::string& /*mdn*/, const std::string& /*hSid*/,
const std::string& /*hNid*/, const std::string& /*min*/, const std::string& /*prl*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioSimResponse::getCdmaSubscriptionSourceResponse(
- const RadioResponseInfo& /*info*/, CdmaSubscriptionSource /*source*/) {
+ const RadioResponseInfo& info, CdmaSubscriptionSource /*source*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::getFacilityLockForAppResponse(
- const RadioResponseInfo& /*info*/, int32_t /*response*/) {
+ndk::ScopedAStatus RadioSimResponse::getFacilityLockForAppResponse(const RadioResponseInfo& info,
+ int32_t /*response*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -72,8 +90,11 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::getImsiForAppResponse(const RadioResponseInfo& /*info*/,
- const std::string& /*imsi*/) {
+ndk::ScopedAStatus RadioSimResponse::getImsiForAppResponse(const RadioResponseInfo& info,
+ const std::string& imsi_str) {
+ rspInfo = info;
+ imsi = imsi_str;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -91,58 +112,79 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::iccCloseLogicalChannelResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioSimResponse::iccCloseLogicalChannelResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::iccIoForAppResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::iccIoForAppResponse(const RadioResponseInfo& info,
const IccIoResult& /*iccIo*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioSimResponse::iccOpenLogicalChannelResponse(
- const RadioResponseInfo& /*info*/, int32_t /*channelId*/,
+ const RadioResponseInfo& info, int32_t /*channelId*/,
const std::vector<uint8_t>& /*selectResponse*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioSimResponse::iccTransmitApduBasicChannelResponse(
- const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+ const RadioResponseInfo& info, const IccIoResult& /*result*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioSimResponse::iccTransmitApduLogicalChannelResponse(
- const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+ const RadioResponseInfo& info, const IccIoResult& /*result*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioSimResponse::reportStkServiceIsRunningResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioSimResponse::requestIccSimAuthenticationResponse(
- const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+ const RadioResponseInfo& info, const IccIoResult& /*result*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::sendEnvelopeResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::sendEnvelopeResponse(const RadioResponseInfo& info,
const std::string& /*commandResponse*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::sendEnvelopeWithStatusResponse(
- const RadioResponseInfo& /*info*/, const IccIoResult& /*iccIo*/) {
+ndk::ScopedAStatus RadioSimResponse::sendEnvelopeWithStatusResponse(const RadioResponseInfo& info,
+ const IccIoResult& /*iccIo*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioSimResponse::sendTerminalResponseToSimResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::setAllowedCarriersResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioSimResponse::setAllowedCarriersResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -154,12 +196,16 @@
}
ndk::ScopedAStatus RadioSimResponse::setCdmaSubscriptionSourceResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::setFacilityLockForAppResponse(
- const RadioResponseInfo& /*info*/, int32_t /*retry*/) {
+ndk::ScopedAStatus RadioSimResponse::setFacilityLockForAppResponse(const RadioResponseInfo& info,
+ int32_t /*retry*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -169,34 +215,44 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::setUiccSubscriptionResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioSimResponse::setUiccSubscriptionResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::supplyIccPin2ForAppResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::supplyIccPin2ForAppResponse(const RadioResponseInfo& info,
int32_t /*remainingRetries*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::supplyIccPinForAppResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::supplyIccPinForAppResponse(const RadioResponseInfo& info,
int32_t /*remainingRetries*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::supplyIccPuk2ForAppResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::supplyIccPuk2ForAppResponse(const RadioResponseInfo& info,
int32_t /*remainingRetries*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioSimResponse::supplyIccPukForAppResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::supplyIccPukForAppResponse(const RadioResponseInfo& info,
int32_t /*remainingRetries*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioSimResponse::supplySimDepersonalizationResponse(
- const RadioResponseInfo& /*info*/, PersoSubstate /*persoType*/,
- int32_t /*remainingRetries*/) {
+ const RadioResponseInfo& info, PersoSubstate /*persoType*/, int32_t /*remainingRetries*/) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
index 5db77f6..64474c9 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <aidl/android/hardware/radio/RadioConst.h>
#include <aidl/android/hardware/radio/config/IRadioConfig.h>
#include <android-base/logging.h>
#include <android/binder_manager.h>
@@ -260,3 +261,764 @@
}
}
}
+
+/*
+ * Test IRadioSim.enableUiccApplications() for the response returned.
+ * For SIM ABSENT case.
+ */
+TEST_P(RadioSimTest, togglingUiccApplicationsSimAbsent) {
+ // This test case only test SIM ABSENT case.
+ if (cardStatus.cardState != CardStatus::STATE_ABSENT) return;
+
+ // Disable Uicc applications.
+ serial = GetRandomSerialNumber();
+ radio_sim->enableUiccApplications(serial, false);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ // As SIM is absent, RadioError::SIM_ABSENT should be thrown.
+ EXPECT_EQ(RadioError::SIM_ABSENT, radioRsp_sim->rspInfo.error);
+
+ // Query Uicc application enablement.
+ serial = GetRandomSerialNumber();
+ radio_sim->areUiccApplicationsEnabled(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ // As SIM is absent, RadioError::SIM_ABSENT should be thrown.
+ EXPECT_EQ(RadioError::SIM_ABSENT, radioRsp_sim->rspInfo.error);
+}
+
+/*
+ * Test IRadioSim.enableUiccApplications() for the response returned.
+ * For SIM PRESENT case.
+ */
+TEST_P(RadioSimTest, togglingUiccApplicationsSimPresent) {
+ // This test case only test SIM ABSENT case.
+ if (cardStatus.cardState != CardStatus::STATE_PRESENT) return;
+ if (cardStatus.applications.size() == 0) return;
+
+ // Disable Uicc applications.
+ serial = GetRandomSerialNumber();
+ radio_sim->enableUiccApplications(serial, false);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ // As SIM is present, there shouldn't be error.
+ EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+
+ // Query Uicc application enablement.
+ serial = GetRandomSerialNumber();
+ radio_sim->areUiccApplicationsEnabled(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ // As SIM is present, there shouldn't be error.
+ EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+ ASSERT_FALSE(radioRsp_sim->areUiccApplicationsEnabled);
+
+ // Enable Uicc applications.
+ serial = GetRandomSerialNumber();
+ radio_sim->enableUiccApplications(serial, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ // As SIM is present, there shouldn't be error.
+ EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+
+ // Query Uicc application enablement.
+ serial = GetRandomSerialNumber();
+ radio_sim->areUiccApplicationsEnabled(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ // As SIM is present, there shouldn't be error.
+ EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+ ASSERT_TRUE(radioRsp_sim->areUiccApplicationsEnabled);
+}
+
+/*
+ * Test IRadioSim.areUiccApplicationsEnabled() for the response returned.
+ */
+TEST_P(RadioSimTest, areUiccApplicationsEnabled) {
+ // Disable Uicc applications.
+ serial = GetRandomSerialNumber();
+ radio_sim->areUiccApplicationsEnabled(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ // If SIM is absent, RadioError::SIM_ABSENT should be thrown. Otherwise there shouldn't be any
+ // error.
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ EXPECT_EQ(RadioError::SIM_ABSENT, radioRsp_sim->rspInfo.error);
+ } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadioSim.getAllowedCarriers() for the response returned.
+ */
+TEST_P(RadioSimTest, getAllowedCarriers) {
+ serial = GetRandomSerialNumber();
+
+ radio_sim->getAllowedCarriers(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/**
+ * Test IRadioSim.setAllowedCarriers() for the response returned.
+ */
+TEST_P(RadioSimTest, setAllowedCarriers) {
+ // TODO (b/210712359): remove once shim supports 1.4 or alternative is found
+ GTEST_SKIP();
+ serial = GetRandomSerialNumber();
+ CarrierRestrictions carrierRestrictions;
+ memset(&carrierRestrictions, 0, sizeof(carrierRestrictions));
+ carrierRestrictions.allowedCarriers.resize(1);
+ carrierRestrictions.excludedCarriers.resize(0);
+ carrierRestrictions.allowedCarriers[0].mcc = std::string("123");
+ carrierRestrictions.allowedCarriers[0].mnc = std::string("456");
+ carrierRestrictions.allowedCarriers[0].matchType = Carrier::MATCH_TYPE_ALL;
+ carrierRestrictions.allowedCarriers[0].matchData = std::string();
+ carrierRestrictions.allowedCarriersPrioritized = true;
+ SimLockMultiSimPolicy multisimPolicy = SimLockMultiSimPolicy::NO_MULTISIM_POLICY;
+
+ radio_sim->setAllowedCarriers(serial, carrierRestrictions, multisimPolicy);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+
+ if (radioRsp_sim->rspInfo.error == RadioError::NONE) {
+ /* Verify the update of the SIM status. This might need some time */
+ if (cardStatus.cardState != CardStatus::STATE_ABSENT) {
+ updateSimCardStatus();
+ auto startTime = std::chrono::system_clock::now();
+ while (cardStatus.cardState != CardStatus::STATE_RESTRICTED &&
+ std::chrono::duration_cast<std::chrono::seconds>(
+ std::chrono::system_clock::now() - startTime)
+ .count() < 30) {
+ /* Set 2 seconds as interval to check card status */
+ sleep(2);
+ updateSimCardStatus();
+ }
+ EXPECT_EQ(CardStatus::STATE_RESTRICTED, cardStatus.cardState);
+ }
+
+ /* Verify that configuration was set correctly, retrieving it from the modem */
+ serial = GetRandomSerialNumber();
+
+ radio_sim->getAllowedCarriers(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+
+ EXPECT_EQ(1, radioRsp_sim->carrierRestrictionsResp.allowedCarriers.size());
+ EXPECT_EQ(0, radioRsp_sim->carrierRestrictionsResp.excludedCarriers.size());
+ ASSERT_TRUE(std::string("123") ==
+ radioRsp_sim->carrierRestrictionsResp.allowedCarriers[0].mcc);
+ ASSERT_TRUE(std::string("456") ==
+ radioRsp_sim->carrierRestrictionsResp.allowedCarriers[0].mnc);
+ EXPECT_EQ(Carrier::MATCH_TYPE_ALL,
+ radioRsp_sim->carrierRestrictionsResp.allowedCarriers[0].matchType);
+ ASSERT_TRUE(radioRsp_sim->carrierRestrictionsResp.allowedCarriersPrioritized);
+ EXPECT_EQ(SimLockMultiSimPolicy::NO_MULTISIM_POLICY, radioRsp_sim->multiSimPolicyResp);
+
+ sleep(10);
+
+ /**
+ * Another test case of the API to cover to allow carrier.
+ * If the API is supported, this is also used to reset to no carrier restriction
+ * status for cardStatus.
+ */
+ memset(&carrierRestrictions, 0, sizeof(carrierRestrictions));
+ carrierRestrictions.allowedCarriers.resize(0);
+ carrierRestrictions.excludedCarriers.resize(0);
+ carrierRestrictions.allowedCarriersPrioritized = false;
+
+ serial = GetRandomSerialNumber();
+ radio_sim->setAllowedCarriers(serial, carrierRestrictions, multisimPolicy);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+
+ if (cardStatus.cardState != CardStatus::STATE_ABSENT) {
+ /* Resetting back to no carrier restriction needs some time */
+ updateSimCardStatus();
+ auto startTime = std::chrono::system_clock::now();
+ while (cardStatus.cardState == CardStatus::STATE_RESTRICTED &&
+ std::chrono::duration_cast<std::chrono::seconds>(
+ std::chrono::system_clock::now() - startTime)
+ .count() < 10) {
+ /* Set 2 seconds as interval to check card status */
+ sleep(2);
+ updateSimCardStatus();
+ }
+ EXPECT_NE(CardStatus::STATE_RESTRICTED, cardStatus.cardState);
+ sleep(10);
+ }
+ }
+}
+
+/*
+ * Test IRadioSim.getIccCardStatus() for the response returned.
+ */
+TEST_P(RadioSimTest, getIccCardStatus) {
+ LOG(DEBUG) << "getIccCardStatus";
+ EXPECT_LE(cardStatus.applications.size(), RadioConst::CARD_MAX_APPS);
+ EXPECT_LT(cardStatus.gsmUmtsSubscriptionAppIndex, RadioConst::CARD_MAX_APPS);
+ EXPECT_LT(cardStatus.cdmaSubscriptionAppIndex, RadioConst::CARD_MAX_APPS);
+ EXPECT_LT(cardStatus.imsSubscriptionAppIndex, RadioConst::CARD_MAX_APPS);
+ LOG(DEBUG) << "getIccCardStatus finished";
+}
+
+/*
+ * Test IRadioSim.supplyIccPinForApp() for the response returned
+ */
+TEST_P(RadioSimTest, supplyIccPinForApp) {
+ LOG(DEBUG) << "supplyIccPinForApp";
+ 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 == AppStatus::APP_TYPE_SIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_USIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_RUIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_CSIM) {
+ radio_sim->supplyIccPinForApp(serial, std::string("test1"),
+ cardStatus.applications[i].aidPtr);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_sim->rspInfo.error,
+ {RadioError::PASSWORD_INCORRECT, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+ }
+ LOG(DEBUG) << "supplyIccPinForApp finished";
+}
+
+/*
+ * Test IRadioSim.supplyIccPukForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, supplyIccPukForApp) {
+ LOG(DEBUG) << "supplyIccPukForApp";
+ 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 == AppStatus::APP_TYPE_SIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_USIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_RUIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_CSIM) {
+ radio_sim->supplyIccPukForApp(serial, std::string("test1"), std::string("test2"),
+ cardStatus.applications[i].aidPtr);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_sim->rspInfo.error,
+ {RadioError::PASSWORD_INCORRECT, RadioError::INVALID_SIM_STATE}));
+ }
+ }
+ LOG(DEBUG) << "supplyIccPukForApp finished";
+}
+
+/*
+ * Test IRadioSim.supplyIccPin2ForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, supplyIccPin2ForApp) {
+ LOG(DEBUG) << "supplyIccPin2ForApp";
+ 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 == AppStatus::APP_TYPE_SIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_USIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_RUIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_CSIM) {
+ radio_sim->supplyIccPin2ForApp(serial, std::string("test1"),
+ cardStatus.applications[i].aidPtr);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+ {RadioError::PASSWORD_INCORRECT,
+ RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_PUK2}));
+ }
+ }
+ LOG(DEBUG) << "supplyIccPin2ForApp finished";
+}
+
+/*
+ * Test IRadioSim.supplyIccPuk2ForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, supplyIccPuk2ForApp) {
+ LOG(DEBUG) << "supplyIccPuk2ForApp";
+ 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 == AppStatus::APP_TYPE_SIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_USIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_RUIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_CSIM) {
+ radio_sim->supplyIccPuk2ForApp(serial, std::string("test1"), std::string("test2"),
+ cardStatus.applications[i].aidPtr);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_sim->rspInfo.error,
+ {RadioError::PASSWORD_INCORRECT, RadioError::INVALID_SIM_STATE}));
+ }
+ }
+ LOG(DEBUG) << "supplyIccPuk2ForApp finished";
+}
+
+/*
+ * Test IRadioSim.changeIccPinForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, changeIccPinForApp) {
+ LOG(DEBUG) << "changeIccPinForApp";
+ 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 == AppStatus::APP_TYPE_SIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_USIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_RUIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_CSIM) {
+ radio_sim->changeIccPinForApp(serial, std::string("test1"), std::string("test2"),
+ cardStatus.applications[i].aidPtr);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_sim->rspInfo.error,
+ {RadioError::PASSWORD_INCORRECT, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+ }
+ LOG(DEBUG) << "changeIccPinForApp finished";
+}
+
+/*
+ * Test IRadioSim.changeIccPin2ForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, changeIccPin2ForApp) {
+ LOG(DEBUG) << "changeIccPin2ForApp";
+ 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 == AppStatus::APP_TYPE_SIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_USIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_RUIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_CSIM) {
+ radio_sim->changeIccPin2ForApp(serial, std::string("test1"), std::string("test2"),
+ cardStatus.applications[i].aidPtr);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+ {RadioError::PASSWORD_INCORRECT,
+ RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_PUK2}));
+ }
+ }
+ LOG(DEBUG) << "changeIccPin2ForApp finished";
+}
+
+/*
+ * Test IRadioSim.getImsiForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, getImsiForApp) {
+ LOG(DEBUG) << "getImsiForApp";
+ 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 == AppStatus::APP_TYPE_SIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_USIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_RUIM ||
+ cardStatus.applications[i].appType == AppStatus::APP_TYPE_CSIM) {
+ radio_sim->getImsiForApp(serial, cardStatus.applications[i].aidPtr);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error, {RadioError::NONE},
+ CHECK_GENERAL_ERROR));
+
+ // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more than 15
+ if (radioRsp_sim->rspInfo.error == RadioError::NONE) {
+ EXPECT_NE(radioRsp_sim->imsi, std::string());
+ EXPECT_GE((int)(radioRsp_sim->imsi).size(), 6);
+ EXPECT_LE((int)(radioRsp_sim->imsi).size(), 15);
+ }
+ }
+ }
+ LOG(DEBUG) << "getImsiForApp finished";
+}
+
+/*
+ * Test IRadioSim.iccIoForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, iccIoForApp) {
+ LOG(DEBUG) << "iccIoForApp";
+ serial = GetRandomSerialNumber();
+
+ for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+ IccIo iccIo;
+ iccIo.command = 0xc0;
+ iccIo.fileId = 0x6f11;
+ iccIo.path = std::string("3F007FFF");
+ iccIo.p1 = 0;
+ iccIo.p2 = 0;
+ iccIo.p3 = 0;
+ iccIo.data = std::string();
+ iccIo.pin2 = std::string();
+ iccIo.aid = cardStatus.applications[i].aidPtr;
+
+ radio_sim->iccIoForApp(serial, iccIo);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ }
+ LOG(DEBUG) << "iccIoForApp finished";
+}
+
+/*
+ * Test IRadioSim.iccTransmitApduBasicChannel() for the response returned.
+ */
+TEST_P(RadioSimTest, iccTransmitApduBasicChannel) {
+ LOG(DEBUG) << "iccTransmitApduBasicChannel";
+ serial = GetRandomSerialNumber();
+ SimApdu msg;
+ memset(&msg, 0, sizeof(msg));
+ msg.data = std::string();
+
+ radio_sim->iccTransmitApduBasicChannel(serial, msg);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ LOG(DEBUG) << "iccTransmitApduBasicChannel finished";
+}
+
+/*
+ * Test IRadioSim.iccOpenLogicalChannel() for the response returned.
+ */
+TEST_P(RadioSimTest, iccOpenLogicalChannel) {
+ LOG(DEBUG) << "iccOpenLogicalChannel";
+ 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_sim->iccOpenLogicalChannel(serial, cardStatus.applications[i].aidPtr, p2);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ }
+ LOG(DEBUG) << "iccOpenLogicalChannel finished";
+}
+
+/*
+ * Test IRadioSim.iccCloseLogicalChannel() for the response returned.
+ */
+TEST_P(RadioSimTest, iccCloseLogicalChannel) {
+ LOG(DEBUG) << "iccCloseLogicalChannel";
+ serial = GetRandomSerialNumber();
+ // Try closing invalid channel and check INVALID_ARGUMENTS returned as error
+ radio_sim->iccCloseLogicalChannel(serial, 0);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp_sim->rspInfo.error);
+ LOG(DEBUG) << "iccCloseLogicalChannel finished";
+}
+
+/*
+ * Test IRadioSim.iccTransmitApduLogicalChannel() for the response returned.
+ */
+TEST_P(RadioSimTest, iccTransmitApduLogicalChannel) {
+ LOG(DEBUG) << "iccTransmitApduLogicalChannel";
+ serial = GetRandomSerialNumber();
+ SimApdu msg;
+ memset(&msg, 0, sizeof(msg));
+ msg.data = std::string();
+
+ radio_sim->iccTransmitApduLogicalChannel(serial, msg);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ LOG(DEBUG) << "iccTransmitApduLogicalChannel finished";
+}
+
+/*
+ * Test IRadioSim.requestIccSimAuthentication() for the response returned.
+ */
+TEST_P(RadioSimTest, requestIccSimAuthentication) {
+ LOG(DEBUG) << "requestIccSimAuthentication";
+ serial = GetRandomSerialNumber();
+
+ // Pass wrong challenge string and check RadioError::INVALID_ARGUMENTS
+ // or REQUEST_NOT_SUPPORTED returned as error.
+ for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+ radio_sim->requestIccSimAuthentication(serial, 0, std::string("test"),
+ cardStatus.applications[i].aidPtr);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_sim->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+ LOG(DEBUG) << "requestIccSimAuthentication finished";
+}
+
+/*
+ * Test IRadioSim.getFacilityLockForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, getFacilityLockForApp) {
+ serial = GetRandomSerialNumber();
+ std::string facility = "";
+ std::string password = "";
+ int32_t serviceClass = 1;
+ std::string appId = "";
+
+ radio_sim->getFacilityLockForApp(serial, facility, password, serviceClass, appId);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+}
+
+/*
+ * Test IRadioSim.setFacilityLockForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, setFacilityLockForApp) {
+ serial = GetRandomSerialNumber();
+ std::string facility = "";
+ bool lockState = false;
+ std::string password = "";
+ int32_t serviceClass = 1;
+ std::string appId = "";
+
+ radio_sim->setFacilityLockForApp(serial, facility, lockState, password, serviceClass, appId);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+}
+
+/*
+ * Test IRadioSim.getCdmaSubscription() for the response returned.
+ */
+TEST_P(RadioSimTest, getCdmaSubscription) {
+ LOG(DEBUG) << "getCdmaSubscription";
+ serial = GetRandomSerialNumber();
+
+ radio_sim->getCdmaSubscription(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_sim->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
+ }
+ LOG(DEBUG) << "getCdmaSubscription finished";
+}
+
+/*
+ * Test IRadioSim.getCdmaSubscriptionSource() for the response returned.
+ */
+TEST_P(RadioSimTest, getCdmaSubscriptionSource) {
+ LOG(DEBUG) << "getCdmaSubscriptionSource";
+ serial = GetRandomSerialNumber();
+
+ radio_sim->getCdmaSubscriptionSource(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_sim->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
+ }
+ LOG(DEBUG) << "getCdmaSubscriptionSource finished";
+}
+
+/*
+ * Test IRadioSim.setCdmaSubscriptionSource() for the response returned.
+ */
+TEST_P(RadioSimTest, setCdmaSubscriptionSource) {
+ LOG(DEBUG) << "setCdmaSubscriptionSource";
+ serial = GetRandomSerialNumber();
+
+ radio_sim->setCdmaSubscriptionSource(serial, CdmaSubscriptionSource::RUIM_SIM);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_sim->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::SUBSCRIPTION_NOT_AVAILABLE},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "setCdmaSubscriptionSource finished";
+}
+
+/*
+ * Test IRadioSim.setUiccSubscription() for the response returned.
+ */
+TEST_P(RadioSimTest, setUiccSubscription) {
+ LOG(DEBUG) << "setUiccSubscription";
+ serial = GetRandomSerialNumber();
+ SelectUiccSub item;
+ memset(&item, 0, sizeof(item));
+
+ radio_sim->setUiccSubscription(serial, item);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+ RadioError::MODEM_ERR, RadioError::SUBSCRIPTION_NOT_SUPPORTED},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "setUiccSubscription finished";
+}
+
+/*
+ * Test IRadioSim.sendEnvelope() for the response returned.
+ */
+TEST_P(RadioSimTest, sendEnvelope) {
+ LOG(DEBUG) << "sendEnvelope";
+ serial = GetRandomSerialNumber();
+
+ // Test with sending empty string
+ std::string content = "";
+
+ radio_sim->sendEnvelope(serial, content);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+ RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "sendEnvelope finished";
+}
+
+/*
+ * Test IRadioSim.sendTerminalResponseToSim() for the response returned.
+ */
+TEST_P(RadioSimTest, sendTerminalResponseToSim) {
+ LOG(DEBUG) << "sendTerminalResponseToSim";
+ serial = GetRandomSerialNumber();
+
+ // Test with sending empty string
+ std::string commandResponse = "";
+
+ radio_sim->sendTerminalResponseToSim(serial, commandResponse);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_sim->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "sendTerminalResponseToSim finished";
+}
+
+/*
+ * Test IRadioSim.reportStkServiceIsRunning() for the response returned.
+ */
+TEST_P(RadioSimTest, reportStkServiceIsRunning) {
+ LOG(DEBUG) << "reportStkServiceIsRunning";
+ serial = GetRandomSerialNumber();
+
+ radio_sim->reportStkServiceIsRunning(serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error, {RadioError::NONE},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "reportStkServiceIsRunning finished";
+}
+
+/*
+ * Test IRadioSim.sendEnvelopeWithStatus() for the response returned with empty
+ * string.
+ */
+TEST_P(RadioSimTest, sendEnvelopeWithStatus) {
+ LOG(DEBUG) << "sendEnvelopeWithStatus";
+ serial = GetRandomSerialNumber();
+
+ // Test with sending empty string
+ std::string contents = "";
+
+ radio_sim->sendEnvelopeWithStatus(serial, contents);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_sim->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "sendEnvelopeWithStatus finished";
+}
diff --git a/radio/aidl/vts/radio_sim_utils.h b/radio/aidl/vts/radio_sim_utils.h
index b5e365d..83f1cbc 100644
--- a/radio/aidl/vts/radio_sim_utils.h
+++ b/radio/aidl/vts/radio_sim_utils.h
@@ -42,6 +42,7 @@
bool areUiccApplicationsEnabled;
PhonebookCapacity capacity;
int32_t updatedRecordIndex;
+ std::string imsi;
virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
diff --git a/radio/aidl/vts/radio_voice_indication.cpp b/radio/aidl/vts/radio_voice_indication.cpp
index d814c18..3fee326 100644
--- a/radio/aidl/vts/radio_voice_indication.cpp
+++ b/radio/aidl/vts/radio_voice_indication.cpp
@@ -65,6 +65,12 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus RadioVoiceIndication::onUssd(RadioIndicationType /*type*/,
+ UssdModeType /*modeType*/,
+ const std::string& /*msg*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus RadioVoiceIndication::resendIncallMute(RadioIndicationType /*type*/) {
return ndk::ScopedAStatus::ok();
}
diff --git a/radio/aidl/vts/radio_voice_response.cpp b/radio/aidl/vts/radio_voice_response.cpp
index a491613..dd7b1bf 100644
--- a/radio/aidl/vts/radio_voice_response.cpp
+++ b/radio/aidl/vts/radio_voice_response.cpp
@@ -18,7 +18,9 @@
RadioVoiceResponse::RadioVoiceResponse(RadioServiceTest& parent) : parent_voice(parent) {}
-ndk::ScopedAStatus RadioVoiceResponse::acceptCallResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::acceptCallResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -26,11 +28,21 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::conferenceResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::cancelPendingUssdResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::dialResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::conferenceResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::dialResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -41,34 +53,44 @@
}
ndk::ScopedAStatus RadioVoiceResponse::exitEmergencyCallbackModeResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::explicitCallTransferResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::explicitCallTransferResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioVoiceResponse::getCallForwardStatusResponse(
- const RadioResponseInfo& /*info*/,
- const std::vector<CallForwardInfo>& /*callForwardInfos*/) {
+ const RadioResponseInfo& info, const std::vector<CallForwardInfo>& /*callForwardInfos*/) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::getCallWaitingResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioVoiceResponse::getCallWaitingResponse(const RadioResponseInfo& info,
bool /*enable*/,
int32_t /*serviceClass*/) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::getClipResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioVoiceResponse::getClipResponse(const RadioResponseInfo& info,
ClipStatus /*status*/) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::getClirResponse(const RadioResponseInfo& /*info*/,
- int32_t /*n*/, int32_t /*m*/) {
+ndk::ScopedAStatus RadioVoiceResponse::getClirResponse(const RadioResponseInfo& info, int32_t /*n*/,
+ int32_t /*m*/) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -81,27 +103,37 @@
}
ndk::ScopedAStatus RadioVoiceResponse::getLastCallFailCauseResponse(
- const RadioResponseInfo& /*info*/, const LastCallFailCauseInfo& /*failCauseInfo*/) {
+ const RadioResponseInfo& info, const LastCallFailCauseInfo& /*failCauseInfo*/) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::getMuteResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioVoiceResponse::getMuteResponse(const RadioResponseInfo& info,
bool /*enable*/) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioVoiceResponse::getPreferredVoicePrivacyResponse(
- const RadioResponseInfo& /*info*/, bool /*enable*/) {
+ const RadioResponseInfo& info, bool /*enable*/) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::getTtyModeResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioVoiceResponse::getTtyModeResponse(const RadioResponseInfo& info,
TtyMode /*mode*/) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioVoiceResponse::handleStkCallSetupRequestFromSimResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
@@ -112,80 +144,120 @@
}
ndk::ScopedAStatus RadioVoiceResponse::hangupForegroundResumeBackgroundResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioVoiceResponse::hangupWaitingOrBackgroundResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::isVoNrEnabledResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioVoiceResponse::isVoNrEnabledResponse(const RadioResponseInfo& info,
bool /*enabled*/) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::rejectCallResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::rejectCallResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::sendBurstDtmfResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::sendBurstDtmfResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::sendCdmaFeatureCodeResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::sendCdmaFeatureCodeResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::sendDtmfResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::sendDtmfResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::separateConnectionResponse(
- const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::sendUssdResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::setCallForwardResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::separateConnectionResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::setCallWaitingResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::setCallForwardResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::setClirResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::setCallWaitingResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::setMuteResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::setClirResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setMuteResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioVoiceResponse::setPreferredVoicePrivacyResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::setTtyModeResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::setTtyModeResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::setVoNrEnabledResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::setVoNrEnabledResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::startDtmfResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::startDtmfResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus RadioVoiceResponse::stopDtmfResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::stopDtmfResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus RadioVoiceResponse::switchWaitingOrHoldingAndActiveResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_voice.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
diff --git a/radio/aidl/vts/radio_voice_test.cpp b/radio/aidl/vts/radio_voice_test.cpp
index 717f3f0..eec28b1 100644
--- a/radio/aidl/vts/radio_voice_test.cpp
+++ b/radio/aidl/vts/radio_voice_test.cpp
@@ -265,3 +265,681 @@
EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
}
+
+/*
+ * Test IRadioVoice.getClir() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getClir) {
+ serial = GetRandomSerialNumber();
+
+ radio_voice->getClir(serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error, {RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+}
+
+/*
+ * Test IRadioVoice.setClir() for the response returned.
+ */
+TEST_P(RadioVoiceTest, setClir) {
+ serial = GetRandomSerialNumber();
+ int32_t status = 1;
+
+ radio_voice->setClir(serial, status);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadioVoice.getClip() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getClip) {
+ serial = GetRandomSerialNumber();
+
+ radio_voice->getClip(serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error, {RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+}
+
+/*
+ * Test IRadioVoice.getTtyMode() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getTtyMode) {
+ LOG(DEBUG) << "getTtyMode";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->getTtyMode(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
+ }
+ LOG(DEBUG) << "getTtyMode finished";
+}
+
+/*
+ * Test IRadioVoice.setTtyMode() for the response returned.
+ */
+TEST_P(RadioVoiceTest, setTtyMode) {
+ LOG(DEBUG) << "setTtyMode";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->setTtyMode(serial, TtyMode::OFF);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
+ }
+ LOG(DEBUG) << "setTtyMode finished";
+}
+
+/*
+ * Test IRadioVoice.setPreferredVoicePrivacy() for the response returned.
+ */
+TEST_P(RadioVoiceTest, setPreferredVoicePrivacy) {
+ LOG(DEBUG) << "setPreferredVoicePrivacy";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->setPreferredVoicePrivacy(serial, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+ LOG(DEBUG) << "setPreferredVoicePrivacy finished";
+}
+
+/*
+ * Test IRadioVoice.getPreferredVoicePrivacy() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getPreferredVoicePrivacy) {
+ LOG(DEBUG) << "getPreferredVoicePrivacy";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->getPreferredVoicePrivacy(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+ LOG(DEBUG) << "getPreferredVoicePrivacy finished";
+}
+
+/*
+ * Test IRadioVoice.exitEmergencyCallbackMode() for the response returned.
+ */
+TEST_P(RadioVoiceTest, exitEmergencyCallbackMode) {
+ LOG(DEBUG) << "exitEmergencyCallbackMode";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->exitEmergencyCallbackMode(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_voice->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
+ }
+ LOG(DEBUG) << "exitEmergencyCallbackMode finished";
+}
+
+/*
+ * Test IRadioVoice.handleStkCallSetupRequestFromSim() for the response returned.
+ */
+TEST_P(RadioVoiceTest, handleStkCallSetupRequestFromSim) {
+ LOG(DEBUG) << "handleStkCallSetupRequestFromSim";
+ serial = GetRandomSerialNumber();
+ bool accept = false;
+
+ radio_voice->handleStkCallSetupRequestFromSim(serial, accept);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+ RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "handleStkCallSetupRequestFromSim finished";
+}
+
+/*
+ * Test IRadioVoice.dial() for the response returned.
+ */
+TEST_P(RadioVoiceTest, dial) {
+ LOG(DEBUG) << "dial";
+ serial = GetRandomSerialNumber();
+
+ Dial dialInfo;
+ memset(&dialInfo, 0, sizeof(dialInfo));
+ dialInfo.address = std::string("123456789");
+
+ radio_voice->dial(serial, dialInfo);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_voice->rspInfo.error,
+ {RadioError::CANCELLED, RadioError::DEVICE_IN_USE, RadioError::FDN_CHECK_FAILURE,
+ RadioError::INVALID_ARGUMENTS, RadioError::INVALID_CALL_ID,
+ RadioError::INVALID_MODEM_STATE, RadioError::INVALID_STATE, RadioError::MODEM_ERR,
+ RadioError::NO_NETWORK_FOUND, RadioError::NO_SUBSCRIPTION,
+ RadioError::OPERATION_NOT_ALLOWED},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "dial finished";
+}
+
+/*
+ * Test IRadioVoice.hangup() for the response returned.
+ */
+TEST_P(RadioVoiceTest, hangup) {
+ LOG(DEBUG) << "hangup";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->hangup(serial, 1);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_voice->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "hangup finished";
+}
+
+/*
+ * Test IRadioVoice.hangupWaitingOrBackground() for the response returned.
+ */
+TEST_P(RadioVoiceTest, hangupWaitingOrBackground) {
+ LOG(DEBUG) << "hangupWaitingOrBackground";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->hangupWaitingOrBackground(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "hangupWaitingOrBackground finished";
+}
+
+/*
+ * Test IRadioVoice.hangupForegroundResumeBackground() for the response returned.
+ */
+TEST_P(RadioVoiceTest, hangupForegroundResumeBackground) {
+ LOG(DEBUG) << "hangupForegroundResumeBackground";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->hangupForegroundResumeBackground(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "hangupForegroundResumeBackground finished";
+}
+
+/*
+ * Test IRadioVoice.switchWaitingOrHoldingAndActive() for the response returned.
+ */
+TEST_P(RadioVoiceTest, switchWaitingOrHoldingAndActive) {
+ LOG(DEBUG) << "switchWaitingOrHoldingAndActive";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->switchWaitingOrHoldingAndActive(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "switchWaitingOrHoldingAndActive finished";
+}
+
+/*
+ * Test IRadioVoice.conference() for the response returned.
+ */
+TEST_P(RadioVoiceTest, conference) {
+ LOG(DEBUG) << "conference";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->conference(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "conference finished";
+}
+
+/*
+ * Test IRadioVoice.rejectCall() for the response returned.
+ */
+TEST_P(RadioVoiceTest, rejectCall) {
+ LOG(DEBUG) << "rejectCall";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->rejectCall(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "rejectCall finished";
+}
+
+/*
+ * Test IRadioVoice.getLastCallFailCause() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getLastCallFailCause) {
+ LOG(DEBUG) << "getLastCallFailCause";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->getLastCallFailCause(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error, {RadioError::NONE},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "getLastCallFailCause finished";
+}
+
+/*
+ * Test IRadioVoice.getCallForwardStatus() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getCallForwardStatus) {
+ LOG(DEBUG) << "getCallForwardStatus";
+ serial = GetRandomSerialNumber();
+ CallForwardInfo callInfo;
+ memset(&callInfo, 0, sizeof(callInfo));
+ callInfo.number = std::string();
+
+ radio_voice->getCallForwardStatus(serial, callInfo);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_voice->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "getCallForwardStatus finished";
+}
+
+/*
+ * Test IRadioVoice.setCallForward() for the response returned.
+ */
+TEST_P(RadioVoiceTest, setCallForward) {
+ LOG(DEBUG) << "setCallForward";
+ serial = GetRandomSerialNumber();
+ CallForwardInfo callInfo;
+ memset(&callInfo, 0, sizeof(callInfo));
+ callInfo.number = std::string();
+
+ radio_voice->setCallForward(serial, callInfo);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_voice->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "setCallForward finished";
+}
+
+/*
+ * Test IRadioVoice.getCallWaiting() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getCallWaiting) {
+ LOG(DEBUG) << "getCallWaiting";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->getCallWaiting(serial, 1);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_voice->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "getCallWaiting finished";
+}
+
+/*
+ * Test IRadioVoice.setCallWaiting() for the response returned.
+ */
+TEST_P(RadioVoiceTest, setCallWaiting) {
+ LOG(DEBUG) << "setCallWaiting";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->setCallWaiting(serial, true, 1);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_voice->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "setCallWaiting finished";
+}
+
+/*
+ * Test IRadioVoice.acceptCall() for the response returned.
+ */
+TEST_P(RadioVoiceTest, acceptCall) {
+ LOG(DEBUG) << "acceptCall";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->acceptCall(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "acceptCall finished";
+}
+
+/*
+ * Test IRadioVoice.separateConnection() for the response returned.
+ */
+TEST_P(RadioVoiceTest, separateConnection) {
+ LOG(DEBUG) << "separateConnection";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->separateConnection(serial, 1);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_voice->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "separateConnection finished";
+}
+
+/*
+ * Test IRadioVoice.explicitCallTransfer() for the response returned.
+ */
+TEST_P(RadioVoiceTest, explicitCallTransfer) {
+ LOG(DEBUG) << "explicitCallTransfer";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->explicitCallTransfer(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "explicitCallTransfer finished";
+}
+
+/*
+ * Test IRadioVoice.sendCdmaFeatureCode() for the response returned.
+ */
+TEST_P(RadioVoiceTest, sendCdmaFeatureCode) {
+ LOG(DEBUG) << "sendCdmaFeatureCode";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->sendCdmaFeatureCode(serial, std::string());
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+ RadioError::INVALID_CALL_ID, RadioError::INVALID_MODEM_STATE,
+ RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "sendCdmaFeatureCode finished";
+}
+
+/*
+ * Test IRadioVoice.sendDtmf() for the response returned.
+ */
+TEST_P(RadioVoiceTest, sendDtmf) {
+ LOG(DEBUG) << "sendDtmf";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->sendDtmf(serial, "1");
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_voice->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INVALID_CALL_ID,
+ RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "sendDtmf finished";
+}
+
+/*
+ * Test IRadioVoice.startDtmf() for the response returned.
+ */
+TEST_P(RadioVoiceTest, startDtmf) {
+ LOG(DEBUG) << "startDtmf";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->startDtmf(serial, "1");
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_voice->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INVALID_CALL_ID,
+ RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "startDtmf finished";
+}
+
+/*
+ * Test IRadioVoice.stopDtmf() for the response returned.
+ */
+TEST_P(RadioVoiceTest, stopDtmf) {
+ LOG(DEBUG) << "stopDtmf";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->stopDtmf(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_CALL_ID,
+ RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "stopDtmf finished";
+}
+
+/*
+ * Test IRadioVoice.setMute() for the response returned.
+ */
+TEST_P(RadioVoiceTest, setMute) {
+ LOG(DEBUG) << "setMute";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->setMute(serial, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "setMute finished";
+}
+
+/*
+ * Test IRadioVoice.getMute() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getMute) {
+ LOG(DEBUG) << "getMute";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->getMute(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
+ }
+ LOG(DEBUG) << "getMute finished";
+}
+
+/*
+ * Test IRadioVoice.sendBurstDtmf() for the response returned.
+ */
+TEST_P(RadioVoiceTest, sendBurstDtmf) {
+ LOG(DEBUG) << "sendBurstDtmf";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->sendBurstDtmf(serial, "1", 0, 0);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE,
+ RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "sendBurstDtmf finished";
+}
+
+/*
+ * Test IRadioVoice.sendUssd() for the response returned.
+ */
+TEST_P(RadioVoiceTest, sendUssd) {
+ LOG(DEBUG) << "sendUssd";
+ serial = GetRandomSerialNumber();
+ radio_voice->sendUssd(serial, std::string("test"));
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_voice->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "sendUssd finished";
+}
+
+/*
+ * Test IRadioVoice.cancelPendingUssd() for the response returned.
+ */
+TEST_P(RadioVoiceTest, cancelPendingUssd) {
+ LOG(DEBUG) << "cancelPendingUssd";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->cancelPendingUssd(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_voice->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "cancelPendingUssd finished";
+}
diff --git a/radio/aidl/vts/radio_voice_utils.h b/radio/aidl/vts/radio_voice_utils.h
index d61bf1e..0c3df7f 100644
--- a/radio/aidl/vts/radio_voice_utils.h
+++ b/radio/aidl/vts/radio_voice_utils.h
@@ -43,6 +43,8 @@
virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
+ virtual ndk::ScopedAStatus cancelPendingUssdResponse(const RadioResponseInfo& info) override;
+
virtual ndk::ScopedAStatus conferenceResponse(const RadioResponseInfo& info) override;
virtual ndk::ScopedAStatus dialResponse(const RadioResponseInfo& info) override;
@@ -103,6 +105,8 @@
virtual ndk::ScopedAStatus sendDtmfResponse(const RadioResponseInfo& info) override;
+ virtual ndk::ScopedAStatus sendUssdResponse(const RadioResponseInfo& info) override;
+
virtual ndk::ScopedAStatus separateConnectionResponse(const RadioResponseInfo& info) override;
virtual ndk::ScopedAStatus setCallForwardResponse(const RadioResponseInfo& info) override;
@@ -164,6 +168,9 @@
virtual ndk::ScopedAStatus onSupplementaryServiceIndication(
RadioIndicationType type, const StkCcUnsolSsResult& ss) override;
+ virtual ndk::ScopedAStatus onUssd(RadioIndicationType type, UssdModeType modeType,
+ const std::string& msg) override;
+
virtual ndk::ScopedAStatus resendIncallMute(RadioIndicationType type) override;
virtual ndk::ScopedAStatus srvccStateNotify(RadioIndicationType type,
diff --git a/security/keymint/aidl/Android.bp b/security/keymint/aidl/Android.bp
index fb736e3..c9ee1b3 100644
--- a/security/keymint/aidl/Android.bp
+++ b/security/keymint/aidl/Android.bp
@@ -55,6 +55,13 @@
],
}
+cc_defaults {
+ name: "keymint_use_latest_hal_aidl_cpp_static",
+ static_libs: [
+ "android.hardware.security.keymint-V2-cpp",
+ ],
+}
+
// A rust_defaults that includes the latest KeyMint AIDL library.
// Modules that depend on KeyMint directly can include this cc_defaults to avoid
// managing dependency versions explicitly.
diff --git a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
index b0761bf..abb2a7b 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
@@ -27,29 +27,29 @@
@VintfStability
parcelable DeviceInfo {
/**
- * DeviceInfo is a CBOR Map structure described by the following CDDL.
+ * DeviceInfo is a CBOR Map structure described by the following CDDL. DeviceInfo must be
+ * canonicalized according to the specification in RFC 7049. The ordering presented here is
+ * non-canonical to group similar entries semantically.
*
* DeviceInfo = {
- * ? "brand" : tstr,
- * ? "manufacturer" : tstr,
- * ? "product" : tstr,
- * ? "model" : tstr,
- * ? "board" : tstr,
- * ? "vb_state" : "green" / "yellow" / "orange", // Taken from the AVB values
- * ? "bootloader_state" : "locked" / "unlocked", // Taken from the AVB values
- * ? "vbmeta_digest": bstr, // Taken from the AVB values
- * ? "os_version" : tstr, // Same as android.os.Build.VERSION.release
- * ? "system_patch_level" : uint, // YYYYMMDD
- * ? "boot_patch_level" : uint, // YYYYMMDD
- * ? "vendor_patch_level" : uint, // YYYYMMDD
- * "version" : 1, // The CDDL schema version.
- * "security_level" : "tee" / "strongbox"
- * "att_id_state": "locked" / "open", // Attestation IDs State. If "locked", this
- * // indicates a device's attestable IDs are
- * // factory-locked and immutable. If "open",
- * // this indicates the device is still in a
- * // provisionable state and the attestable IDs
- * // are not yet frozen.
+ * "brand" : tstr,
+ * "manufacturer" : tstr,
+ * "product" : tstr,
+ * "model" : tstr,
+ * "device" : tstr,
+ * "vb_state" : "green" / "yellow" / "orange", // Taken from the AVB values
+ * "bootloader_state" : "locked" / "unlocked", // Taken from the AVB values
+ * "vbmeta_digest": bstr, // Taken from the AVB values
+ * ? "os_version" : tstr, // Same as
+ * // android.os.Build.VERSION.release
+ * // Not optional for TEE.
+ * "system_patch_level" : uint, // YYYYMMDD
+ * "boot_patch_level" : uint, // YYYYMMDD
+ * "vendor_patch_level" : uint, // YYYYMMDD
+ * "version" : 2, // The CDDL schema version.
+ * "security_level" : "tee" / "strongbox",
+ * "fused": 1 / 0, // 1 if secure boot is enforced for the processor that the IRPC
+ * // implementation is contained in. 0 otherwise.
* }
*/
byte[] deviceInfo;
diff --git a/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl b/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl
index 62a48e9..ad97443 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl
@@ -37,10 +37,10 @@
*
* PublicKey = { // COSE_Key
* 1 : 2, // Key type : EC2
- * 3 : -8 // Algorithm : ES256
- * -1 : 6, // Curve : P256
- * -2 : bstr // X coordinate, little-endian
- * -3 : bstr // Y coordinate, little-endian
+ * 3 : -7, // Algorithm : ES256
+ * -1 : 1, // Curve : P256
+ * -2 : bstr, // X coordinate, little-endian
+ * -3 : bstr, // Y coordinate, little-endian
* ? -70000 : nil // Presence indicates this is a test key. If set, K_mac is
* // all zeros.
* },
diff --git a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
index 24cdbc1..a14fc88 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
@@ -169,7 +169,6 @@
* PubKeyEd25519 = { // COSE_Key
* 1 : 1, // Key type : octet key pair
* 3 : AlgorithmEdDSA, // Algorithm : EdDSA
- * 4 : 2, // Ops: Verify
* -1 : 6, // Curve : Ed25519
* -2 : bstr // X coordinate, little-endian
* }
@@ -184,7 +183,6 @@
* PubKeyECDSA256 = { // COSE_Key
* 1 : 2, // Key type : EC2
* 3 : AlgorithmES256, // Algorithm : ECDSA w/ SHA-256
- * 4 : 2, // Ops: Verify
* -1 : 1, // Curve: P256
* -2 : bstr, // X coordinate
* -3 : bstr // Y coordinate
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 2d2d701..91db3c8 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -75,6 +75,9 @@
export_include_dirs: [
".",
],
+ export_static_lib_headers: [
+ "libkeymint_support",
+ ],
static_libs: [
"libgmock_ndk",
],
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 829780d..e2d75ce 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -57,6 +57,22 @@
using namespace remote_prov;
using namespace keymaster;
+std::set<std::string> getAllowedVbStates() {
+ return {"green", "yellow", "orange"};
+}
+
+std::set<std::string> getAllowedBootloaderStates() {
+ return {"locked", "unlocked"};
+}
+
+std::set<std::string> getAllowedSecurityLevels() {
+ return {"tee", "strongbox"};
+}
+
+std::set<std::string> getAllowedAttIdStates() {
+ return {"locked", "open"};
+}
+
bytevec string_to_bytevec(const char* s) {
const uint8_t* p = reinterpret_cast<const uint8_t*>(s);
return bytevec(p, p + strlen(s));
@@ -406,6 +422,8 @@
ASSERT_TRUE(deviceInfoMap) << "Failed to parse deviceInfo: " << deviceInfoErrMsg;
ASSERT_TRUE(deviceInfoMap->asMap());
+ checkDeviceInfo(deviceInfoMap->asMap(), deviceInfo.deviceInfo);
+
auto& signingKey = bccContents->back().pubKey;
auto macKey = verifyAndParseCoseSign1(signedMac->asArray(), signingKey,
cppbor::Array() // SignedMacAad
@@ -432,6 +450,80 @@
}
}
+ void checkType(const cppbor::Map* devInfo, uint8_t majorType, std::string entryName) {
+ const auto& val = devInfo->get(entryName);
+ ASSERT_TRUE(val) << entryName << " does not exist";
+ ASSERT_EQ(val->type(), majorType) << entryName << " has the wrong type.";
+ switch (majorType) {
+ case cppbor::TSTR:
+ ASSERT_GT(val->asTstr()->value().size(), 0);
+ break;
+ case cppbor::BSTR:
+ ASSERT_GT(val->asBstr()->value().size(), 0);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void checkDeviceInfo(const cppbor::Map* deviceInfo, bytevec deviceInfoBytes) {
+ const auto& version = deviceInfo->get("version");
+ ASSERT_TRUE(version);
+ ASSERT_TRUE(version->asUint());
+ RpcHardwareInfo info;
+ provisionable_->getHardwareInfo(&info);
+ ASSERT_EQ(version->asUint()->value(), info.versionNumber);
+ std::set<std::string> allowList;
+ switch (version->asUint()->value()) {
+ // These fields became mandated in version 2.
+ case 2:
+ checkType(deviceInfo, cppbor::TSTR, "brand");
+ checkType(deviceInfo, cppbor::TSTR, "manufacturer");
+ checkType(deviceInfo, cppbor::TSTR, "product");
+ checkType(deviceInfo, cppbor::TSTR, "model");
+ checkType(deviceInfo, cppbor::TSTR, "device");
+ // TODO: Refactor the KeyMint code that validates these fields and include it here.
+ checkType(deviceInfo, cppbor::TSTR, "vb_state");
+ allowList = getAllowedVbStates();
+ ASSERT_NE(allowList.find(deviceInfo->get("vb_state")->asTstr()->value()),
+ allowList.end());
+ checkType(deviceInfo, cppbor::TSTR, "bootloader_state");
+ allowList = getAllowedBootloaderStates();
+ ASSERT_NE(allowList.find(deviceInfo->get("bootloader_state")->asTstr()->value()),
+ allowList.end());
+ checkType(deviceInfo, cppbor::BSTR, "vbmeta_digest");
+ checkType(deviceInfo, cppbor::UINT, "system_patch_level");
+ checkType(deviceInfo, cppbor::UINT, "boot_patch_level");
+ checkType(deviceInfo, cppbor::UINT, "vendor_patch_level");
+ checkType(deviceInfo, cppbor::UINT, "fused");
+ ASSERT_LT(deviceInfo->get("fused")->asUint()->value(), 2); // Must be 0 or 1.
+ checkType(deviceInfo, cppbor::TSTR, "security_level");
+ allowList = getAllowedSecurityLevels();
+ ASSERT_NE(allowList.find(deviceInfo->get("security_level")->asTstr()->value()),
+ allowList.end());
+ if (deviceInfo->get("security_level")->asTstr()->value() == "tee") {
+ checkType(deviceInfo, cppbor::TSTR, "os_version");
+ }
+ break;
+ case 1:
+ checkType(deviceInfo, cppbor::TSTR, "security_level");
+ allowList = getAllowedSecurityLevels();
+ ASSERT_NE(allowList.find(deviceInfo->get("security_level")->asTstr()->value()),
+ allowList.end());
+ if (version->asUint()->value() == 1) {
+ checkType(deviceInfo, cppbor::TSTR, "att_id_state");
+ allowList = getAllowedAttIdStates();
+ ASSERT_NE(allowList.find(deviceInfo->get("att_id_state")->asTstr()->value()),
+ allowList.end());
+ }
+ break;
+ default:
+ FAIL() << "Unrecognized version: " << version->asUint()->value();
+ }
+ ASSERT_EQ(deviceInfo->clone()->asMap()->canonicalize().encode(), deviceInfoBytes)
+ << "DeviceInfo ordering is non-canonical.";
+ }
+
bytevec eekId_;
size_t testEekLength_;
EekChain testEekChain_;
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 0cbee51..35cb891 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -26,6 +26,11 @@
namespace aidl::android::hardware::security::keymint::remote_prov {
+constexpr uint32_t kBccPayloadIssuer = 1;
+constexpr uint32_t kBccPayloadSubject = 2;
+constexpr int32_t kBccPayloadSubjPubKey = -4670552;
+constexpr int32_t kBccPayloadKeyUsage = -4670553;
+
bytevec kTestMacKey(32 /* count */, 0 /* byte value */);
bytevec randomBytes(size_t numBytes) {
@@ -98,6 +103,18 @@
return prodEek;
}
+ErrMsgOr<bytevec> validatePayloadAndFetchPubKey(const cppbor::Map* payload) {
+ const auto& issuer = payload->get(kBccPayloadIssuer);
+ if (!issuer || !issuer->asTstr()) return "Issuer is not present or not a tstr.";
+ const auto& subject = payload->get(kBccPayloadSubject);
+ if (!subject || !subject->asTstr()) return "Subject is not present or not a tstr.";
+ const auto& keyUsage = payload->get(kBccPayloadKeyUsage);
+ if (!keyUsage || !keyUsage->asBstr()) return "Key usage is not present or not a bstr.";
+ const auto& serializedKey = payload->get(kBccPayloadSubjPubKey);
+ if (!serializedKey || !serializedKey->asBstr()) return "Key is not present or not a bstr.";
+ return serializedKey->asBstr()->value();
+}
+
ErrMsgOr<bytevec> verifyAndParseCoseSign1Cwt(const cppbor::Array* coseSign1,
const bytevec& signingCoseKey, const bytevec& aad) {
if (!coseSign1 || coseSign1->size() != kCoseSign1EntryCount) {
@@ -126,18 +143,16 @@
return "Unsupported signature algorithm";
}
- // TODO(jbires): Handle CWTs as the CoseSign1 payload in a less hacky way. Since the CWT payload
- // is extremely remote provisioning specific, probably just make a separate
- // function there.
auto [parsedPayload, __, payloadErrMsg] = cppbor::parse(payload);
if (!parsedPayload) return payloadErrMsg + " when parsing key";
if (!parsedPayload->asMap()) return "CWT must be a map";
- auto serializedKey = parsedPayload->asMap()->get(-4670552)->clone();
- if (!serializedKey || !serializedKey->asBstr()) return "Could not find key entry";
+ auto serializedKey = validatePayloadAndFetchPubKey(parsedPayload->asMap());
+ if (!serializedKey) {
+ return "CWT validation failed: " + serializedKey.moveMessage();
+ }
bool selfSigned = signingCoseKey.empty();
- auto key =
- CoseKey::parseEd25519(selfSigned ? serializedKey->asBstr()->value() : signingCoseKey);
+ auto key = CoseKey::parseEd25519(selfSigned ? *serializedKey : signingCoseKey);
if (!key) return "Bad signing key: " + key.moveMessage();
bytevec signatureInput =
@@ -148,7 +163,7 @@
return "Signature verification failed";
}
- return serializedKey->asBstr()->value();
+ return serializedKey.moveValue();
}
ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc) {
@@ -156,8 +171,11 @@
std::vector<BccEntryData> result;
+ const auto& devicePubKey = bcc->get(0);
+ if (!devicePubKey->asMap()) return "Invalid device public key at the 1st entry in the BCC";
+
bytevec prevKey;
- // TODO(jbires): Actually process the pubKey at the start of the new bcc entry
+
for (size_t i = 1; i < bcc->size(); ++i) {
const cppbor::Array* entry = bcc->get(i)->asArray();
if (!entry || entry->size() != kCoseSign1EntryCount) {
@@ -177,6 +195,13 @@
// This entry's public key is the signing key for the next entry.
prevKey = payload.moveValue();
+ if (i == 1) {
+ auto [parsedRootKey, _, errMsg] = cppbor::parse(prevKey);
+ if (!parsedRootKey || !parsedRootKey->asMap()) return "Invalid payload entry in BCC.";
+ if (*parsedRootKey != *devicePubKey) {
+ return "Device public key doesn't match BCC root.";
+ }
+ }
}
return result;
diff --git a/sensors/common/default/2.X/multihal/HalProxy.cpp b/sensors/common/default/2.X/multihal/HalProxy.cpp
index f5fc066..ccc4172 100644
--- a/sensors/common/default/2.X/multihal/HalProxy.cpp
+++ b/sensors/common/default/2.X/multihal/HalProxy.cpp
@@ -250,8 +250,8 @@
Result currRes = mSubHalList[i]->initialize(this, this, i);
if (currRes != Result::OK) {
result = currRes;
- ALOGE("Subhal '%s' failed to initialize.", mSubHalList[i]->getName().c_str());
- break;
+ ALOGE("Subhal '%s' failed to initialize with reason %" PRId32 ".",
+ mSubHalList[i]->getName().c_str(), static_cast<int32_t>(currRes));
}
}
diff --git a/thermal/2.0/default/Android.bp b/thermal/2.0/default/Android.bp
index a63ffbc..f743ade 100644
--- a/thermal/2.0/default/Android.bp
+++ b/thermal/2.0/default/Android.bp
@@ -22,16 +22,26 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
+filegroup {
+ name: "android.hardware.thermal@2.0-service.xml",
+ srcs: ["android.hardware.thermal@2.0-service.xml"],
+}
+
+filegroup {
+ name: "android.hardware.thermal@2.0-service.rc",
+ srcs: ["android.hardware.thermal@2.0-service.rc"],
+}
+
cc_binary {
name: "android.hardware.thermal@2.0-service.mock",
defaults: ["hidl_defaults"],
relative_install_path: "hw",
vendor: true,
- init_rc: ["android.hardware.thermal@2.0-service.rc"],
- vintf_fragments: ["android.hardware.thermal@2.0-service.xml"],
+ init_rc: [":android.hardware.thermal@2.0-service.rc"],
+ vintf_fragments: [":android.hardware.thermal@2.0-service.xml"],
srcs: [
"Thermal.cpp",
- "service.cpp"
+ "service.cpp",
],
shared_libs: [
"libbase",
diff --git a/thermal/2.0/default/apex/Android.bp b/thermal/2.0/default/apex/Android.bp
new file mode 100644
index 0000000..914a3a8
--- /dev/null
+++ b/thermal/2.0/default/apex/Android.bp
@@ -0,0 +1,55 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+apex_key {
+ name: "com.android.hardware.thermal.key",
+ public_key: "com.android.hardware.thermal.avbpubkey",
+ private_key: "com.android.hardware.thermal.pem",
+}
+
+android_app_certificate {
+ name: "com.android.hardware.thermal.certificate",
+ certificate: "com.android.hardware.thermal",
+}
+
+genrule {
+ name: "com.android.hardware.thermal.rc-gen",
+ srcs: [":android.hardware.thermal@2.0-service.rc"],
+ out: ["com.android.hardware.thermal.rc"],
+ cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.thermal.mock/' $(in) > $(out)",
+}
+
+prebuilt_etc {
+ name: "com.android.hardware.thermal.rc",
+ src: ":com.android.hardware.thermal.rc-gen",
+ installable: false,
+}
+
+apex {
+ name: "com.android.hardware.thermal.mock",
+ manifest: "manifest.json",
+ file_contexts: "file_contexts",
+ key: "com.android.hardware.thermal.key",
+ certificate: ":com.android.hardware.thermal.certificate",
+ use_vndk_as_stable: true,
+ updatable: false,
+ soc_specific: true,
+ binaries: ["android.hardware.thermal@2.0-service.mock"],
+ prebuilts: ["com.android.hardware.thermal.rc"],
+ vintf_fragments: [":android.hardware.thermal@2.0-service.xml"],
+}
diff --git a/thermal/2.0/default/apex/com.android.hardware.thermal.avbpubkey b/thermal/2.0/default/apex/com.android.hardware.thermal.avbpubkey
new file mode 100644
index 0000000..8f7cf72
--- /dev/null
+++ b/thermal/2.0/default/apex/com.android.hardware.thermal.avbpubkey
Binary files differ
diff --git a/thermal/2.0/default/apex/com.android.hardware.thermal.pem b/thermal/2.0/default/apex/com.android.hardware.thermal.pem
new file mode 100644
index 0000000..4ea6e85
--- /dev/null
+++ b/thermal/2.0/default/apex/com.android.hardware.thermal.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEApXL2prEKqnU/xHlYeZB55x5EOrVAsfBuyHN5xOgUY877UuDC
+xoX+DOYAkCDSwMPmBj/Q9E70lId1PXMeI3y0obgYpdFubqRsoGNcEq2zG811tr6J
+BAE/7mAI0a4VVFWtauBNTiP5G31hsRpZNTE/dyZxs20GEVQqdvtBlEAuebCt7VIb
+fCwXnPCXSiYQ9WyjU0dwHoZPuy02qBuq3v9NYt5J6lYiPDqTWmpYBFm+SIZvth/j
+HUcaU3p+BlUad0qLhA8HYTPPBwJq2uHbTXeFrWXngt+UPCdzYubyUjG4WmgHIfee
+zSvoTjud2Gaofnd4/PcE5jFTMYUJuz0D4E+8StZArw+xegfxGcvqFZ4gfKAO1Vha
+eQBhw94P2eieUfh9metQEyKZ+A24sxG0awtAUOgcwr/WNv2TgJoN8+56DhuPXOuO
+U2qeIZuIrmE5xmyzrzJsCx+5vRQA7A3kpxRo1ZCgbJlzMgdAQaRTe2rqxyyoeFQR
+HbxUdsM7ZwDLE62UlaTTZFoJ1wzvZmsIJdkdRg97zcc3R3kYnVehCxAZ1KdAKzq6
+bhrw/kNAVA0zUHhlhHWGDnJQ/rkGfjQ9GGhS51IJYgKEoQc5M9hSgZD3idic8hso
+63r/P2Wn4S78gwLigfpzsGD7RrusTbMIRkebwpHwAYpB8qIykrtUKfunLtMCAwEA
+AQKCAgEAjiKbv0ytaw9bfwD4f0cdUu5vkzgPok55/f8mh4ERs0UoKGUrL74BKTeX
+GDr6k9w4CvpcGuaRu+A7WlVBeR8zVxN/KUUo6CidoZR6jxlmm+YA0MQTlbs1Hyal
+rO0vKcqJNx4Hi6/f3Dv0519JcCck7Mm8OHbbFZwG9zyXdDNHOggNA6rcLer7Rjpy
+3qKhQxbXoT3oFnEwog8Pu5A5VWZjJyLswULKGo//81cU0nf+vvOvmPj/9jEVbs32
+4p3OJNmHziXTIzCNFOqAvhX2fzDFSNgY8hf9k0gZGshpOS+5vwFLz2SZqo2j/0G8
+MyLOcgdVi4zzSobpf8tZNuAOKnCVwxteV3Ddl0o+qAf4cQCAXtuEkJvFWpAxrX4m
+J7nDDuvcTjKMlnchlm6XxmP27YNTKA2w5uNfrJQV5LR3IDs77PFpNiKOwERka6MU
+WE1LnjAFTCDxujT29NfIjC9z0iOY45TYut4okesaK7woe6pfK2H0ouvE6mZ+Lb7Y
+qZphPb4e4DZZZAVoELVvWflm/VC/xmBMA9vtzpjuvRXD+iYjgxbHaiG2UANLWmTd
+vADLqBadlbp10AvyrjKxHUhAiZnJgaVKRXtw5qk8YrwZOwypEHCQjY41fJuRScWF
+pD58/PYOLtSdwewzTijXSVwwPeqL1JMdJ+KWFk5zI410DtmHwoECggEBANM5dHEj
+L4ZOCcgHVG7aCLah7f/0Za7BBiPsZFD0uRIzWFTd77st3v8ulMw1JQiO3+xmpL7e
+iOP+onuSEMKgNQqeX9WCnv6pL+mjg0of2IEcGnvCpmfUZRA2x/MlyJRrQ1vHGqkV
+oBIIWgCGmIAWuFbHPmkNYx7mAJymAfzShkVtMw29oiGYyubqx9cTjD0odeyScbhZ
+LuMt72O5QeNsPREX4SsSRAL+vZbz1+8iRI8Fon89csZym3hos3DA4QSml+FNHnLe
+YFD6AfU7pdn79YhhNkn4jE0BxLaEkXhMs8RRTU2Q3o990ZxrAZGQz4zqOm5sOIQT
+JaXFXxGvOwEysrMCggEBAMiFaTzkhJSLEmLEu0T3gNEC2d3jE9kt4Olv4mQmzD00
+AzDtkrkArLQCeG3CMn55oFcJRwr8gAEk7/f2mvJSoZQnw0J0tRI+QiHJG4zwdsQC
+UszqN89X8ef0yoobwVa31ZoWxK4/NvLO4GZQ6UUd9uni10jfYVWmwEwKBU61ihvT
+ntcZIXvROR6khxzLeXtglnsznnYcdYMPJUeN+cfK9/rL3V3jk1jes8y8XwYfxkUa
+99nEe1NkRCUznzKxvkRwnKunlMCEkZ5z4nNMlqEqiOlVEYgwKwNCP+qM7ZKUJg7t
+uOL91bqWFPj2qdzyUh0uP5V/dg2odnu0xSblKWhxI2ECggEBAKbZttJ8Idlsoath
+pt+d2c4yoadTLlNZ5HjSDfgpKFxpNLhtTCbGuGVJLX8V5/gXrGi4OCER9n5rMXx9
+SEIFfYCy1C77bI7rpI5hfJ88ArESOxVSEFLqYx7otw+p5AThqibAY533GCfGcxoB
+OEvOJrVd1D31tju9IfSb6ewFfM0w0mhjSMRTRswb39pUda4F3QkQMUaXJEOOkJBs
+0dBNOvvaqiJ03kajZa3tVsBuiEuV/uOV7ak29Pqrcjt6EQW0dzsgyRGh+eFda9iE
+0qEbt7uQVusdq+5UnEg09hhaNpK4SmEgM76Te9WcbXPIOTst9xQs5oPmABIvk8aL
+bgenPaMCggEAX9EAHIzFnYVm37NKGQZ7k2RdXt2nGlwF4QYJk/nGFmjILZUYSza7
+T7jueuQU5MKRj4VrYSCOuf1AfahlGe3KL9VgRF0oOPNu/l3uwEYXOkox7qDs0jMf
+8MrUDXJ9zEZD10GR8gFa7GNWbw2yqchLuC8g2D2FcTwhHzSanKW6vNk+SWJE0bmE
+JdRQi73e6smYnn5n9eBbdqjCE5MQDBw8qqbHvJmGSyz/lZFdhrugLl1YmcJ9e7ep
+qG0mYT71wBZfhtapCeVO//w39Qhf4dtFWNnBauY5Z3E8wYNd8nDATtnhQvYwLtyQ
+YPbc7CsOecsjrvgdHSGmnC4hFxjh1HpbgQKCAQBzEr35CFQpUfGsu06SqRrxp7mb
+BfQzLmqnt+ZLu21H/YjVbamMXNjbJFSdtFLxAK/s9vFGQzEWWEYia2pRZejlCXhQ
+RO+TREJ4rm4Erfdh+zS9z8MZlxe2ybIMs260XxjZ0gEltRtJ6P14zLBlChi/rQEY
+tGrOpfjvLc1Lryaucwj7snDLtMfyqvemAUmuJNn/6IEMuG4DcdtJ3Whh7t3xKfO0
+Hc71Oh7F30okQQ6Ctiwp1T77Y1EXlRJrUtpf1sLxeItP6/r3WXLNaiFdKqGJxiCM
+Gw11oUcBA9bvfAzeJIpVVbLtGPNOp4J1XpkgFcWzsTM+ZpxWwbj4yJL6rSN2
+-----END RSA PRIVATE KEY-----
diff --git a/thermal/2.0/default/apex/com.android.hardware.thermal.pk8 b/thermal/2.0/default/apex/com.android.hardware.thermal.pk8
new file mode 100644
index 0000000..3e5bf69
--- /dev/null
+++ b/thermal/2.0/default/apex/com.android.hardware.thermal.pk8
Binary files differ
diff --git a/thermal/2.0/default/apex/com.android.hardware.thermal.x509.pem b/thermal/2.0/default/apex/com.android.hardware.thermal.x509.pem
new file mode 100644
index 0000000..048e69a
--- /dev/null
+++ b/thermal/2.0/default/apex/com.android.hardware.thermal.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF3TCCA8UCFFWeg2KJX/fyAqZPcKaFS61/a3GiMA0GCSqGSIb3DQEBCwUAMIGp
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
+bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
+MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTElMCMGA1UEAwwcY29t
+LmFuZHJvaWQuaGFyZHdhcmUudGhlcm1hbDAgFw0yMTExMTcxODE3MjRaGA80NzU5
+MTAxNDE4MTcyNFowgakxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
+MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYD
+VQQLDAdBbmRyb2lkMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29t
+MSUwIwYDVQQDDBxjb20uYW5kcm9pZC5oYXJkd2FyZS50aGVybWFsMIICIjANBgkq
+hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2W8QhCKX0WoS5jhIWbWBoKulD6XhKASA
+CL0oU6Uci0U6id2m++ou/T0aHSlliS9kT1NEABNwbLeTDa9h1qg1lbajRzXbvzEz
+EvZYT+dlgYFNZ9zaVCIlMapoiN+nrM/Rs24UBjJrZu1B39+IcE5ciQz69PgrLKWF
+vFEdYzxWI246azOVr3fvdelQg+CyPgiGObVAGOHhAidvsjg4FssKnADzn+JNlTt6
+b9P65xUQErut8hz9YdLtfZ096iwe8eEpsMOQwCNdKNXVCcNjQWkOwRaU+0awHoH1
+4mArvF7yyvJxqzkNaR03BPqXAHPIAPu6xdfA19+HVIiz6bLEZ1mfCM6edXByCWZu
+K8o54OZph71r15ncv4DVd+cnBjNvBvfdlJSeGjSreFkUo5NkfAwqdmLfZx6CedHI
+sLx7X8vPYolQnR4UEvaX6yeNN0gs8Dd6ePMqOEiwWFVASD+cbpcUrp09uzlDStGV
+1DPx/9J2kw8eXPMqOSGThkLWuUMUFojyh7bNlL16oYmEeZW6/OOXCOXzAQgJ7NIs
+DA1/H2w1HMHWgSfF4y+Es2CiqcgVFOIU/07b31Edw4v56pjx1CUpRpJZjDA1JJNo
+A4YCnpA6JWTxzUTmv21fEYyY+poA3CuzvCfZ80z9h/UFW98oM9GawGvK0i2pLudS
+RaZXWeil08cCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAj2gpn/IpAHQLDlI52WwL
+IDc5uzlf1BGseLZ8M8uuMiwvN00nOjunQQZEIbhH7+03GYyMzRhTTI3nWwmX4Fnq
+vC5sR68yNlu9gOAMXaAHo/Rw73ak7sv8xGbb2FeQsHaMKDQ2nqxP17SWdQ0xWa1u
+5qNurPOdAPOw77noZcT7yYX7lcrOKxPIekPJxyeOlp4bQSmabSRgYr70B7GybPlv
+K1gkgCBxl5RiVjVxLo+7ESHSAaGLy0S7F2v6PJ9oj15TovWQ0py2iBKZ6HReB7s/
+umnQqkwXDLudlNmoXIsgIYn8vKFTYpy1GSNJqhRSLfvLR6NtuU0iCTvg/X7oPmS1
+dWUdjVeO7ZVvIpO3gLLEe4maBEYF2sOlt3bRmzIHydORJtkfTt5tiZ4wR9RfJbkj
+iBiDbNiX010bZPTAXmgMbuJzQXZEXCBy0qKeS1cHwf9M8FDoiLajXepfZIp+6syt
+D4lZk4eAV141JL5PfABfdZWwT3cTgFIqCYpqrMQJIu+GHEjUwD2yNPi0I1/ydFCW
+CPDnzWjYCi6yVB8hss3ZFbvhfyJzdm3LivNVbLGK0+TG0EOAz6d2aQ0UjESgMD1A
+U8hLzQt7MiFSG0bt2cVx6SgCHeYUqMntbFELEAURWrhAfPLMJtAvFgKbEiZEAkkW
+pdDVh603aIp4LjVCfTYp/mQ=
+-----END CERTIFICATE-----
diff --git a/thermal/2.0/default/apex/file_contexts b/thermal/2.0/default/apex/file_contexts
new file mode 100644
index 0000000..e0d87c7
--- /dev/null
+++ b/thermal/2.0/default/apex/file_contexts
@@ -0,0 +1,5 @@
+(/.*)? u:object_r:vendor_file:s0
+# Permission XMLs
+/etc/permissions(/.*)? u:object_r:vendor_configs_file:s0
+# binary
+/bin/hw/android\.hardware\.thermal@2\.0-service\.mock u:object_r:hal_thermal_default_exec:s0
diff --git a/thermal/2.0/default/apex/manifest.json b/thermal/2.0/default/apex/manifest.json
new file mode 100644
index 0000000..ee44dc1
--- /dev/null
+++ b/thermal/2.0/default/apex/manifest.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.hardware.thermal.mock",
+ "version": 1
+}
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
index 8cb7e22..1606b7b 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
@@ -69,37 +69,6 @@
// disable.
bool waitForSupplicantStop() { return waitForSupplicantState(false); }
-// Helper function to initialize the driver and firmware to STA mode
-// using the vendor HAL HIDL interface.
-void initilializeDriverAndFirmware(const std::string& wifi_instance_name) {
- // Skip if wifi instance is not set.
- if (wifi_instance_name == "") {
- return;
- }
- if (getWifi(wifi_instance_name) != nullptr) {
- sp<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name);
- ChipModeId mode_id;
- EXPECT_TRUE(configureChipToSupportIfaceType(
- wifi_chip, ::android::hardware::wifi::V1_0::IfaceType::STA, &mode_id));
- } else {
- LOG(WARNING) << __func__ << ": Vendor HAL not supported";
- }
-}
-
-// Helper function to deinitialize the driver and firmware
-// using the vendor HAL HIDL interface.
-void deInitilializeDriverAndFirmware(const std::string& wifi_instance_name) {
- // Skip if wifi instance is not set.
- if (wifi_instance_name == "") {
- return;
- }
- if (getWifi(wifi_instance_name) != nullptr) {
- stopWifi(wifi_instance_name);
- } else {
- LOG(WARNING) << __func__ << ": Vendor HAL not supported";
- }
-}
-
// Helper function to find any iface of the desired type exposed.
bool findIfaceOfType(sp<ISupplicant> supplicant, IfaceType desired_type,
ISupplicant::IfaceInfo* out_info) {
@@ -156,14 +125,46 @@
SupplicantManager supplicant_manager;
ASSERT_TRUE(supplicant_manager.StopSupplicant());
- deInitilializeDriverAndFirmware(wifi_instance_name);
+ deInitializeDriverAndFirmware(wifi_instance_name);
ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
}
+// Helper function to initialize the driver and firmware to STA mode
+// using the vendor HAL HIDL interface.
+void initializeDriverAndFirmware(const std::string& wifi_instance_name) {
+ // Skip if wifi instance is not set.
+ if (wifi_instance_name == "") {
+ return;
+ }
+ if (getWifi(wifi_instance_name) != nullptr) {
+ sp<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name);
+ ChipModeId mode_id;
+ EXPECT_TRUE(configureChipToSupportIfaceType(
+ wifi_chip, ::android::hardware::wifi::V1_0::IfaceType::STA,
+ &mode_id));
+ } else {
+ LOG(WARNING) << __func__ << ": Vendor HAL not supported";
+ }
+}
+
+// Helper function to deinitialize the driver and firmware
+// using the vendor HAL HIDL interface.
+void deInitializeDriverAndFirmware(const std::string& wifi_instance_name) {
+ // Skip if wifi instance is not set.
+ if (wifi_instance_name == "") {
+ return;
+ }
+ if (getWifi(wifi_instance_name) != nullptr) {
+ stopWifi(wifi_instance_name);
+ } else {
+ LOG(WARNING) << __func__ << ": Vendor HAL not supported";
+ }
+}
+
void startSupplicantAndWaitForHidlService(
const std::string& wifi_instance_name,
const std::string& supplicant_instance_name) {
- initilializeDriverAndFirmware(wifi_instance_name);
+ initializeDriverAndFirmware(wifi_instance_name);
SupplicantManager supplicant_manager;
ASSERT_TRUE(supplicant_manager.StartSupplicant());
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
index 22cea8c..7228623 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
@@ -42,6 +42,11 @@
const std::string& wifi_instance_name,
const std::string& supplicant_instance_name);
+// Used to initialize/deinitialize the driver and firmware at the
+// beginning and end of each test.
+void initializeDriverAndFirmware(const std::string& wifi_instance_name);
+void deInitializeDriverAndFirmware(const std::string& wifi_instance_name);
+
// 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
diff --git a/wifi/supplicant/aidl/vts/functional/Android.bp b/wifi/supplicant/aidl/vts/functional/Android.bp
index 65f9652..8e142ec 100644
--- a/wifi/supplicant/aidl/vts/functional/Android.bp
+++ b/wifi/supplicant/aidl/vts/functional/Android.bp
@@ -33,11 +33,23 @@
shared_libs: [
"libbinder",
"libbinder_ndk",
+ "libvndksupport",
],
static_libs: [
+ "android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.1",
+ "android.hardware.wifi@1.2",
+ "android.hardware.wifi@1.3",
+ "android.hardware.wifi@1.4",
+ "android.hardware.wifi@1.5",
+ "android.hardware.wifi.supplicant@1.0",
+ "android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi.supplicant-V1-ndk",
"libwifi-system",
"libwifi-system-iface",
+ "VtsHalWifiV1_0TargetTestUtil",
+ "VtsHalWifiV1_5TargetTestUtil",
+ "VtsHalWifiSupplicantV1_0TargetTestUtil",
],
test_suites: [
"general-tests",
@@ -55,11 +67,23 @@
shared_libs: [
"libbinder",
"libbinder_ndk",
+ "libvndksupport",
],
static_libs: [
+ "android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.1",
+ "android.hardware.wifi@1.2",
+ "android.hardware.wifi@1.3",
+ "android.hardware.wifi@1.4",
+ "android.hardware.wifi@1.5",
+ "android.hardware.wifi.supplicant@1.0",
+ "android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi.supplicant-V1-ndk",
"libwifi-system",
"libwifi-system-iface",
+ "VtsHalWifiV1_0TargetTestUtil",
+ "VtsHalWifiV1_5TargetTestUtil",
+ "VtsHalWifiSupplicantV1_0TargetTestUtil",
],
test_suites: [
"general-tests",
@@ -77,11 +101,23 @@
shared_libs: [
"libbinder",
"libbinder_ndk",
+ "libvndksupport",
],
static_libs: [
+ "android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.1",
+ "android.hardware.wifi@1.2",
+ "android.hardware.wifi@1.3",
+ "android.hardware.wifi@1.4",
+ "android.hardware.wifi@1.5",
+ "android.hardware.wifi.supplicant@1.0",
+ "android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi.supplicant-V1-ndk",
"libwifi-system",
"libwifi-system-iface",
+ "VtsHalWifiV1_0TargetTestUtil",
+ "VtsHalWifiV1_5TargetTestUtil",
+ "VtsHalWifiSupplicantV1_0TargetTestUtil",
],
test_suites: [
"general-tests",
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
index d9d8179..d5bdde2 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
@@ -165,8 +165,7 @@
public:
void SetUp() override {
initializeService();
- supplicant_ = ISupplicant::fromBinder(ndk::SpAIBinder(
- AServiceManager_waitForService(GetParam().c_str())));
+ supplicant_ = getSupplicant(GetParam().c_str());
ASSERT_NE(supplicant_, nullptr);
ASSERT_TRUE(supplicant_
->setDebugParams(DebugLevel::EXCESSIVE,
@@ -180,13 +179,13 @@
GTEST_SKIP() << "Wi-Fi Direct is not supported, skip this test.";
}
- EXPECT_TRUE(supplicant_->addP2pInterface(getP2pIfaceName(), &p2p_iface_)
+ EXPECT_TRUE(supplicant_->getP2pInterface(getP2pIfaceName(), &p2p_iface_)
.isOk());
ASSERT_NE(p2p_iface_, nullptr);
}
void TearDown() override {
- stopSupplicant();
+ stopSupplicantService();
startWifiFramework();
}
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
index 6e6955f..b24f502 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
@@ -197,21 +197,20 @@
public:
void SetUp() override {
initializeService();
- supplicant_ = ISupplicant::fromBinder(ndk::SpAIBinder(
- AServiceManager_waitForService(GetParam().c_str())));
+ supplicant_ = getSupplicant(GetParam().c_str());
ASSERT_NE(supplicant_, nullptr);
ASSERT_TRUE(supplicant_
->setDebugParams(DebugLevel::EXCESSIVE,
true, // show timestamps
true)
.isOk());
- EXPECT_TRUE(supplicant_->addStaInterface(getStaIfaceName(), &sta_iface_)
+ EXPECT_TRUE(supplicant_->getStaInterface(getStaIfaceName(), &sta_iface_)
.isOk());
ASSERT_NE(sta_iface_, nullptr);
}
void TearDown() override {
- stopSupplicant();
+ stopSupplicantService();
startWifiFramework();
}
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
index 3d8242b..a19b300 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
@@ -99,15 +99,14 @@
public:
void SetUp() override {
initializeService();
- supplicant_ = ISupplicant::fromBinder(ndk::SpAIBinder(
- AServiceManager_waitForService(GetParam().c_str())));
+ supplicant_ = getSupplicant(GetParam().c_str());
ASSERT_NE(supplicant_, nullptr);
ASSERT_TRUE(supplicant_
->setDebugParams(DebugLevel::EXCESSIVE,
true, // show timestamps
true)
.isOk());
- EXPECT_TRUE(supplicant_->addStaInterface(getStaIfaceName(), &sta_iface_)
+ EXPECT_TRUE(supplicant_->getStaInterface(getStaIfaceName(), &sta_iface_)
.isOk());
ASSERT_NE(sta_iface_, nullptr);
EXPECT_TRUE(sta_iface_->addNetwork(&sta_network_).isOk());
@@ -115,7 +114,7 @@
}
void TearDown() override {
- stopSupplicant();
+ stopSupplicantService();
startWifiFramework();
}
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
index b7e1a80..17e0394 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
@@ -19,8 +19,14 @@
#include <VtsCoreUtil.h>
#include <android-base/logging.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
+#include <hidl/ServiceManagement.h>
+#include <supplicant_hidl_test_utils.h>
#include <wifi_system/supplicant_manager.h>
+using aidl::android::hardware::wifi::supplicant::IfaceInfo;
+using aidl::android::hardware::wifi::supplicant::ISupplicant;
+using aidl::android::hardware::wifi::supplicant::ISupplicantP2pIface;
using aidl::android::hardware::wifi::supplicant::ISupplicantStaIface;
using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
using android::wifi_system::SupplicantManager;
@@ -37,6 +43,14 @@
return std::string(buffer.data());
}
+std::string getWifiInstanceName() {
+ const std::vector<std::string> instances =
+ android::hardware::getAllHalInstanceNames(
+ ::android::hardware::wifi::V1_0::IWifi::descriptor);
+ EXPECT_NE(0, instances.size());
+ return instances.size() != 0 ? instances[0] : "";
+}
+
bool keyMgmtSupported(std::shared_ptr<ISupplicantStaIface> iface,
KeyMgmtMask expected) {
KeyMgmtMask caps;
@@ -53,60 +67,44 @@
return keyMgmtSupported(iface, filsMask);
}
-bool waitForSupplicantState(bool is_running) {
+void startSupplicant() {
+ initializeDriverAndFirmware(getWifiInstanceName());
SupplicantManager supplicant_manager;
- int count = 50; /* wait at most 5 seconds for completion */
- while (count-- > 0) {
- if (supplicant_manager.IsSupplicantRunning() == is_running) {
- return true;
- }
- usleep(100000);
- }
- LOG(ERROR) << "Supplicant not " << (is_running ? "running" : "stopped");
- return false;
+ ASSERT_TRUE(supplicant_manager.StartSupplicant());
+ ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
}
-bool waitForFrameworkReady() {
- int waitCount = 15;
- do {
- // Check whether package service is ready or not.
- if (!testing::checkSubstringInCommandOutput(
- "/system/bin/service check package", ": not found")) {
- return true;
- }
- LOG(INFO) << "Framework is not ready";
- sleep(1);
- } while (waitCount-- > 0);
- return false;
-}
-
-bool waitForSupplicantStart() { return waitForSupplicantState(true); }
-
-bool waitForSupplicantStop() { return waitForSupplicantState(false); }
-
-void stopSupplicant() {
- SupplicantManager supplicant_manager;
- ASSERT_TRUE(supplicant_manager.StopSupplicant());
- ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
-}
-
-bool startWifiFramework() {
- std::system("svc wifi enable");
- std::system("cmd wifi set-scan-always-available enabled");
- return waitForSupplicantStart();
-}
-
-bool stopWifiFramework() {
- std::system("svc wifi disable");
- std::system("cmd wifi set-scan-always-available disabled");
- return waitForSupplicantStop();
-}
+// Wrapper around the implementation in supplicant_hidl_test_util.
+void stopSupplicantService() { stopSupplicant(getWifiInstanceName()); }
void initializeService() {
ASSERT_TRUE(stopWifiFramework());
std::system("/system/bin/start");
ASSERT_TRUE(waitForFrameworkReady());
- stopSupplicant();
+ stopSupplicantService();
+ startSupplicant();
+}
+
+void addStaIface(const std::shared_ptr<ISupplicant> supplicant) {
+ ASSERT_TRUE(supplicant.get());
+ std::shared_ptr<ISupplicantStaIface> iface;
+ ASSERT_TRUE(supplicant->addStaInterface(getStaIfaceName(), &iface).isOk());
+}
+
+void addP2pIface(const std::shared_ptr<ISupplicant> supplicant) {
+ ASSERT_TRUE(supplicant.get());
+ std::shared_ptr<ISupplicantP2pIface> iface;
+ ASSERT_TRUE(supplicant->addP2pInterface(getP2pIfaceName(), &iface).isOk());
+}
+
+std::shared_ptr<ISupplicant> getSupplicant(const char* supplicant_name) {
+ std::shared_ptr<ISupplicant> supplicant = ISupplicant::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(supplicant_name)));
+ addStaIface(supplicant);
+ if (testing::deviceSupportsFeature("android.hardware.wifi.direct")) {
+ addP2pIface(supplicant);
+ }
+ return supplicant;
}
#endif // SUPPLICANT_TEST_UTILS_H
\ No newline at end of file