Merge "cas@1.1: must be used over cas@1.0 for Q devices"
diff --git a/audio/common/5.0/types.hal b/audio/common/5.0/types.hal
index ffe4506..8f8a888 100644
--- a/audio/common/5.0/types.hal
+++ b/audio/common/5.0/types.hal
@@ -643,8 +643,10 @@
int32_t device;
} alsa; // used for USB_*
} address;
- string busAddress; // used for BUS
- string rSubmixAddress; // used for REMOTE_SUBMIX
+ /** Arbitrary BUS device unique address. Should not be interpreted by the framework. */
+ string busAddress;
+ /** Arbitrary REMOTE_SUBMIX device unique address. Should not be interpreted by the HAL. */
+ string rSubmixAddress;
};
/**
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index a22cc1c..7f8b6a0 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -142,14 +142,13 @@
android::DeviceVector availableOutputDevices;
android::DeviceVector availableInputDevices;
sp<android::DeviceDescriptor> defaultOutputDevice;
- android::VolumeCurvesCollection volumes;
};
class PolicyConfig : private PolicyConfigData, public AudioPolicyConfig {
public:
PolicyConfig()
: AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
- defaultOutputDevice, &volumes) {
+ defaultOutputDevice) {
for (const char* location : kConfigLocations) {
std::string path = std::string(location) + '/' + kConfigFileName;
if (access(path.c_str(), F_OK) == 0) {
diff --git a/current.txt b/current.txt
index a128669..4aa8c1d 100644
--- a/current.txt
+++ b/current.txt
@@ -418,7 +418,7 @@
9471b12b1c255bb530695720bc4174bd74987b75b1f820854af8944bc8c215c9 android.hardware.audio@5.0::IStreamOut
1b0500367ed2b32a841667ac3200edf3d3a164e8004aca445ff1b085ac831e93 android.hardware.audio@5.0::IStreamOutCallback
83e365479cc77d8717c155e1787ee668cd2ae4c557b467cf75b8e7cd53697ad8 android.hardware.audio@5.0::types
-edda213e520f387a3e367834b0772978b308a0f59b54479990aa9411aee9bcc4 android.hardware.audio.common@5.0::types
+894af04bebfe7da5b6791eefeb6eb3627da63d5efea735f16876d11d8ca4f61d android.hardware.audio.common@5.0::types
f269297866765b95ddd1825676cc8a772f0c7c9863286df596fc302781a42ff5 android.hardware.audio.effect@5.0::IAcousticEchoCancelerEffect
fa187b602d8939644ef708ed7627f2e3deac97899a4bda1de07f2ff126abe243 android.hardware.audio.effect@5.0::IAutomaticGainControlEffect
e1bf864ccb8458c0da1dcc74a2e748b1dca8ac360df590591cf82d98292d7981 android.hardware.audio.effect@5.0::IBassBoostEffect
@@ -487,7 +487,7 @@
dd1ec219f5d2e2b33c6c0bcb92e63bbedb36f7c716413462848f6b6ae74fc864 android.hardware.health.storage@1.0::IStorage
2b4a14661e6a38617b7dd0c6ebb66a56a90e564674ac7697a14cb8a0cab92b2f android.hardware.health.storage@1.0::types
30006fde4cb1f255f2530208728bff692100411b20af5b66fa31a9196d51f00b android.hardware.input.classifier@1.0::IInputClassifier
-97d8757bb05eb23d6a218bda374e095dfbb064c47714e2f859963c11f433e822 android.hardware.input.common@1.0::types
+0300c7667030da36c3de585f176ce18ff4b0d2615446d4930f331097378c06ef android.hardware.input.common@1.0::types
24ae089981d58bc4cc74d75a6055bf357338ae6744ce1b467c5b4a9c470aba6d android.hardware.media.bufferpool@2.0::IAccessor
897f45ee7db24ef227dea83ca3e4de72d53ff6bb7adc7983c90a650a1a6ff576 android.hardware.media.bufferpool@2.0::IClientManager
aee53b2865b4f7939fb3df6fae758d9750c14f93dd454b479fc74aa7978fda4f android.hardware.media.bufferpool@2.0::IConnection
@@ -512,12 +512,12 @@
cf7a4ba516a638f9b82a249c91fb603042c2d9ca43fd5aad9cf6c0401ed2a5d7 android.hardware.nfc@1.2::INfc
abf98c2ae08bf765db54edc8068e36d52eb558cff6706b6fd7c18c65a1f3fc18 android.hardware.nfc@1.2::types
4cb252dc6372a874aef666b92a6e9529915aa187521a700f0789065c3c702ead android.hardware.power.stats@1.0::IPowerStats
-69c394e7fe3236beb6231a709865e8a882aac7a612c8dddf64f5a66028fa2c68 android.hardware.power.stats@1.0::types
+2043037d5baaff604805757d06979aa861013a1e87430db745265339a8681f79 android.hardware.power.stats@1.0::types
11620ce020b6ef8f5b63eb2a39390de4a2fbbccc0a5e558b5b1a0e22e33f63cf android.hardware.radio@1.3::IRadio
e9d0f11a52715f5a29d89e2d8e2e21db1e16a43174af6b9d51a62d705cda1455 android.hardware.radio@1.3::IRadioIndication
d233f0da44f55fdef0a95db5229231412787bb67695cd1ea197ce89a3c2908b9 android.hardware.radio@1.3::IRadioResponse
750a363c8cec70baa1aac19e275c15233c5898e93c6bb5155fa2ca7f365490dc android.hardware.radio@1.3::types
-21e6ce53f1759f6a213ca05bac3c0325ed911f74764d1c1f6fa5ed8068ade65b android.hardware.radio@1.4::IRadio
+4ac73ec1e4cfa535209e5e22547f08beb20ef812b4a29d0824780f52cbe2324d android.hardware.radio@1.4::IRadio
33d9e6895cca98aa56296bb01720d18b8acd0e4de4960beb712e63ad147438a5 android.hardware.radio@1.4::IRadioIndication
0cc0dd87c634aad36d7df22b2832839ef7ded71909dbcde11cfdd69dc0dc52b8 android.hardware.radio@1.4::IRadioResponse
29d34232cc3974626b08759e039fe788bded7695cdeb098458e3e11e4c7d3603 android.hardware.radio@1.4::types
@@ -534,7 +534,7 @@
ae5faa38538a9f50eb71eb7f9b998271124d2c64b761cb11c4d820c7732b4ddc android.hardware.sensors@2.0::ISensorsCallback
3a98242a57d0820dacaca0f7db52bec433eae1f21c498763c6f1ece611c3967b android.hardware.sensors@2.0::types
ce4b98211959449361146d4b1e5554dc841ceb4d4577154d7b2fb6d1eb504f76 android.hardware.soundtrigger@2.2::ISoundTriggerHw
-5cc81d517c5f3fef12e719b0f5683c7c99e3e8895fcb80e6f6653b454f463320 android.hardware.thermal@2.0::IThermal
+bd88b48639cae30982021024e22371076c76faa8466e38ca598529452b618eae android.hardware.thermal@2.0::IThermal
cc4d2ef36da776c475ad054f0f3416d8a8865def9d9e2129f10074b28e36d203 android.hardware.thermal@2.0::IThermalChangedCallback
b47f90302595874dfddb19bd05a054727bf18b3a930bc810ea14957b859ae8bf android.hardware.thermal@2.0::types
61bc302e7c974c59b25898c585c6e9685e8a81021b1bed3eedf5224198f2785a android.hardware.usb@1.2::IUsb
diff --git a/input/classifier/1.0/vts/OWNERS b/input/classifier/1.0/vts/OWNERS
new file mode 100644
index 0000000..447f3d9
--- /dev/null
+++ b/input/classifier/1.0/vts/OWNERS
@@ -0,0 +1,3 @@
+michaelwr@google.com
+pquinn@google.com
+svv@google.com
\ No newline at end of file
diff --git a/input/classifier/1.0/vts/functional/Android.bp b/input/classifier/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..ef49d70
--- /dev/null
+++ b/input/classifier/1.0/vts/functional/Android.bp
@@ -0,0 +1,27 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+ name: "VtsHalInputClassifierV1_0TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: ["VtsHalInputClassifierV1_0TargetTest.cpp"],
+ static_libs: [
+ "android.hardware.input.classifier@1.0",
+ "android.hardware.input.common@1.0",
+ ],
+ test_suites: ["general-tests"],
+}
+
diff --git a/input/classifier/1.0/vts/functional/VtsHalInputClassifierV1_0TargetTest.cpp b/input/classifier/1.0/vts/functional/VtsHalInputClassifierV1_0TargetTest.cpp
new file mode 100644
index 0000000..f033c2a
--- /dev/null
+++ b/input/classifier/1.0/vts/functional/VtsHalInputClassifierV1_0TargetTest.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "input_classifier_hal_test"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
+#include <android-base/logging.h>
+#include <android/hardware/input/classifier/1.0/IInputClassifier.h>
+#include <android/hardware/input/common/1.0/types.h>
+#include <input/InputDevice.h>
+#include <unistd.h>
+
+using ::android::ReservedInputDeviceId;
+using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::input::classifier::V1_0::IInputClassifier;
+using ::android::hardware::input::common::V1_0::Action;
+using ::android::hardware::input::common::V1_0::Axis;
+using ::android::hardware::input::common::V1_0::Button;
+using ::android::hardware::input::common::V1_0::EdgeFlag;
+using ::android::hardware::input::common::V1_0::MotionEvent;
+using ::android::hardware::input::common::V1_0::PointerCoords;
+using ::android::hardware::input::common::V1_0::PointerProperties;
+using ::android::hardware::input::common::V1_0::Source;
+using ::android::hardware::input::common::V1_0::ToolType;
+using ::android::hardware::input::common::V1_0::VideoFrame;
+
+static MotionEvent getSimpleMotionEvent() {
+ MotionEvent event;
+ event.action = Action::DOWN;
+ event.actionButton = Button::NONE;
+ event.actionIndex = 0;
+ event.buttonState = 0;
+ event.deviceId = 0;
+ event.deviceTimestamp = 0;
+ event.displayId = 1;
+ event.downTime = 2;
+ event.edgeFlags = 0;
+ event.eventTime = 3;
+ event.flags = 0;
+ event.frames = {};
+ event.metaState = 0;
+ event.policyFlags = 0;
+ event.source = Source::TOUCHSCREEN;
+ event.xPrecision = 0;
+ event.yPrecision = 0;
+
+ PointerCoords coords;
+ coords.bits = Axis::X | Axis::Y;
+ coords.values = {1 /*X*/, 2 /*Y*/};
+ event.pointerCoords = {coords};
+
+ PointerProperties properties;
+ properties.id = 0;
+ properties.toolType = ToolType::FINGER;
+ event.pointerProperties = {properties};
+
+ return event;
+}
+
+// Test environment for Input Classifier HIDL HAL.
+class InputClassifierHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+ public:
+ // get the test environment singleton
+ static InputClassifierHidlEnvironment* Instance() {
+ static InputClassifierHidlEnvironment* instance = new InputClassifierHidlEnvironment;
+ return instance;
+ }
+
+ virtual void registerTestServices() override { registerTestService<IInputClassifier>(); }
+
+ private:
+ InputClassifierHidlEnvironment() {}
+};
+
+// The main test class for INPUT CLASSIFIER HIDL HAL 1.0.
+class InputClassifierHidlTest_1_0 : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ classifier = ::testing::VtsHalHidlTargetTestBase::getService<IInputClassifier>(
+ InputClassifierHidlEnvironment::Instance()->getServiceName<IInputClassifier>());
+ ASSERT_NE(classifier, nullptr);
+ }
+
+ virtual void TearDown() override {}
+
+ sp<IInputClassifier> classifier;
+};
+
+/**
+ * Call resetDevice(..) for a few common device id values, and make sure that the HAL
+ * can handle the resets gracefully.
+ */
+TEST_F(InputClassifierHidlTest_1_0, ResetDevice) {
+ EXPECT_TRUE(classifier->resetDevice(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID).isOk());
+ EXPECT_TRUE(classifier->resetDevice(ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID).isOk());
+ EXPECT_TRUE(classifier->resetDevice(1).isOk());
+ EXPECT_TRUE(classifier->resetDevice(2).isOk());
+}
+
+/**
+ * Call reset() on the HAL to ensure no fatal failure there.
+ */
+TEST_F(InputClassifierHidlTest_1_0, ResetHal) {
+ EXPECT_TRUE(classifier->reset().isOk());
+}
+
+/**
+ * Classify an event without any video frames.
+ */
+TEST_F(InputClassifierHidlTest_1_0, Classify_NoVideoFrame) {
+ // Create a MotionEvent that does not have any video data
+ MotionEvent event = getSimpleMotionEvent();
+
+ EXPECT_TRUE(classifier->classify(event).isOk());
+ // We are not checking the actual classification here,
+ // because the HAL operation is highly device-specific.
+
+ // Return HAL to a consistent state by doing a reset
+ classifier->reset();
+}
+
+/**
+ * Classify an event with one video frame. Should be the most common scenario.
+ */
+TEST_F(InputClassifierHidlTest_1_0, Classify_OneVideoFrame) {
+ MotionEvent event = getSimpleMotionEvent();
+ VideoFrame frame;
+ frame.data = {1, 2, 3, 4};
+ frame.height = 2;
+ frame.width = 2;
+ frame.timestamp = event.eventTime;
+ event.frames = {frame};
+
+ EXPECT_TRUE(classifier->classify(event).isOk());
+ // We are not checking the actual classification here,
+ // because the HAL operation is highly device-specific.
+
+ // Return HAL to a consistent state by doing a reset
+ classifier->reset();
+}
+
+/**
+ * Classify an event with 2 video frames. This could happen if there's slowness in the system,
+ * or if simply the video rate is somehow higher that the input event rate.
+ * The HAL should be able to handle events with more than 1 video frame.
+ *
+ * The frames should be in chronological order, but it is not guaranteed that they will have
+ * monotonically increasing timestamps. Still, we provide consistent timestamps here since that
+ * is the most realistic mode of operation.
+ */
+TEST_F(InputClassifierHidlTest_1_0, Classify_TwoVideoFrames) {
+ MotionEvent event = getSimpleMotionEvent();
+ VideoFrame frame1;
+ frame1.data = {1, 2, 3, 4};
+ frame1.height = 2;
+ frame1.width = 2;
+ frame1.timestamp = event.eventTime;
+ VideoFrame frame2 = frame1;
+ frame2.data = {5, 5, 5, -1};
+ frame2.timestamp += 1;
+ event.frames = {frame1, frame2};
+
+ EXPECT_TRUE(classifier->classify(event).isOk());
+ // We are not checking the actual classification here,
+ // because the HAL operation is highly device-specific.
+
+ // Return HAL to a consistent state by doing a reset
+ classifier->reset();
+}
+
+int main(int argc, char** argv) {
+ ::testing::AddGlobalTestEnvironment(InputClassifierHidlEnvironment::Instance());
+ ::testing::InitGoogleTest(&argc, argv);
+ InputClassifierHidlEnvironment::Instance()->init(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}
diff --git a/input/common/1.0/types.hal b/input/common/1.0/types.hal
index 1a07f3b..9ad368b 100644
--- a/input/common/1.0/types.hal
+++ b/input/common/1.0/types.hal
@@ -685,20 +685,20 @@
* Touch heatmap.
*
* The array is a 2-D row-major matrix with dimensions (height, width).
- * The heatmap data does not rotate when device orientation changes.
+ * The heatmap data is rotated when device orientation changes.
*
* Example:
*
* If the data in the array is:
* data[i] = i for i in 0 .. 59,
- * then it can be represented as follows:
+ * then it can be represented as a 10 x 6 matrix:
*
- * <-- width -- >
+ * <-- width -->
* 0 1 2 3 4 5 ^
* 6 7 8 9 10 11 |
- * 12 12 14 15 16 17 |
- * 18 ... 23 | height
- * 24 ... 29 |
+ * 12 13 14 15 16 17 |
+ * 18 ... 23 |
+ * 24 ... 29 | height
* 30 ... 35 |
* 36 ... 41 |
* 42 ... 47 |
@@ -708,16 +708,33 @@
* Looking at the device in standard portrait orientation,
* the element "0" is the top left of the screen,
* "5" is at the top right, and "59" is the bottom right.
- * Here width=6, and height=10.
+ * Here height=10 and width=6.
+ *
+ * If the screen orientation changes to landscape (a 90 degree orientation
+ * change), the frame's dimensions will become 6 x 10
+ * and the data will look as follows:
+ * 54 48 42 36 30 24 18 12 6 0 ^
+ * ... 13 7 1 |
+ * ... 14 8 2 | height
+ * ... 15 9 3 |
+ * ... 16 10 4 |
+ * 59 53 47 41 35 29 23 17 11 5 v
+ * <-- width -->
+ *
+ * Here the element "0" is at the physical top left of the unrotated screen.
+ *
+ * Since the coordinates of a MotionEvent are also adjusted based on the
+ * orientation, the rotation of the video frame data ensures that
+ * the axes for MotionEvent and VideoFrame data are consistent.
*/
struct VideoFrame {
/**
* Video frame data.
- * Size of the data is width * height.
+ * Size of the data is height * width.
*/
vec<int16_t> data;
- uint32_t width;
uint32_t height;
+ uint32_t width;
/**
* Time at which the frame was collected, in nanoseconds.
* Measured with the same clock that is used to populate MotionEvent times.
diff --git a/power/stats/1.0/types.hal b/power/stats/1.0/types.hal
index 644224b..6051e3f 100644
--- a/power/stats/1.0/types.hal
+++ b/power/stats/1.0/types.hal
@@ -26,9 +26,9 @@
struct RailInfo {
/** Index corresponding to the rail */
uint32_t index;
- /** Name of the rail */
+ /** Name of the rail (opaque to the framework) */
string railName;
- /** Name of the subsystem to which this rail belongs */
+ /** Name of the subsystem to which this rail belongs (opaque to the framework) */
string subsysName;
/** Hardware sampling rate */
uint32_t samplingRate;
@@ -71,7 +71,7 @@
struct PowerEntityInfo {
/** Unique ID corresponding to the PowerEntity */
uint32_t powerEntityId;
- /** Name of the PowerEntity */
+ /** Name of the PowerEntity (opaque to the framework) */
string powerEntityName;
/** Type of the PowerEntity */
PowerEntityType type;
@@ -82,7 +82,7 @@
* ID corresponding to the state. Unique for a given PowerEntityStateSpace
*/
uint32_t powerEntityStateId;
- /** Name of the state */
+ /** Name of the state (opaque to the framework) */
string powerEntityStateName;
};
diff --git a/radio/1.4/IRadio.hal b/radio/1.4/IRadio.hal
index f7ae39f..046f074 100644
--- a/radio/1.4/IRadio.hal
+++ b/radio/1.4/IRadio.hal
@@ -115,11 +115,13 @@
* PUK/PIN state of the subscription and the service state of the radio.
*
* Some countries or carriers require some emergency numbers that must be handled with normal
- * call routing or emergency routing. If the 'routing' field is specified as
- * @1.4::EmergencyNumberRouting#NORMAL, the implementation must use normal call routing to
- * handle the call; if it is specified as @1.4::EmergencyNumberRouting#EMERGENCY, the
- * implementation must use emergency routing to handle the call; if it is
- * @1.4::EmergencyNumberRouting#UNKNOWN, Android does not know how to handle the call.
+ * call routing if possible or emergency routing. 1) if the 'routing' field is specified as
+ * @1.4::EmergencyNumberRouting#NORMAL, the implementation must try the full radio service to
+ * use normal call routing to handle the call; if service cannot support normal routing, the
+ * implementation must use emergency routing to handle the call. 2) if 'routing' is specified
+ * as @1.4::EmergencyNumberRouting#EMERGENCY, the implementation must use emergency routing to
+ * handle the call. 3) if 'routing' is specified as @1.4::EmergencyNumberRouting#UNKNOWN,
+ * Android does not know how to handle the call.
*
* If the dialed emergency number does not have a specified emergency service category, the
* 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; if the dialed
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index 9237799..52eb277 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -93,4 +93,403 @@
ALOGI("emergencyDial_withEmergencyRouting, rspInfo.error = %s\n",
toString(radioRsp_v1_4->rspInfo.error).c_str());
EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
-}
\ No newline at end of file
+}
+
+/*
+ * Test IRadio.startNetworkScan() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT, .interval = 60, .specifiers = {specifier}};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan, rspInfo.error = %s\n", toString(radioRsp_v1_4->rspInfo.error).c_str());
+
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::SIM_ABSENT}));
+ } else if (cardStatus.base.base.cardState == CardState::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.
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid specifier.
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidArgument) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {.type = ScanType::ONE_SHOT,
+ .interval = 60};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_InvalidArgument, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid interval (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval1) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 4,
+ .specifiers = {specifier},
+ .maxSearchTime = 60,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_InvalidInterval1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid interval (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval2) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 301,
+ .specifiers = {specifier},
+ .maxSearchTime = 60,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_InvalidInterval2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid max search time (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime1) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 59,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_InvalidMaxSearchTime1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid max search time (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime2) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 3601,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_InvalidMaxSearchTime2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid periodicity (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity1) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 600,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 0};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_InvalidPeriodicity1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid periodicity (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity2) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 600,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 11};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_InvalidPeriodicity2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with valid periodicity
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_GoodRequest1) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ // Some vendor may not support max search time of 360s.
+ // This issue is tracked in b/112205669.
+ .maxSearchTime = 300,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 10};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_GoodRequest1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with valid periodicity and plmns
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_GoodRequest2) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ // Some vendor may not support max search time of 360s.
+ // This issue is tracked in b/112205669.
+ .maxSearchTime = 300,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 10,
+ .mccMncs = {"310410"}};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_GoodRequest2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS}));
+ }
+}
+/*
+ * Test IRadio.setupDataCall_1_4() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_4, setupDataCall_1_4) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_4::AccessNetwork accessNetwork =
+ ::android::hardware::radio::V1_4::AccessNetwork::EUTRAN;
+
+ android::hardware::radio::V1_4::DataProfileInfo dataProfileInfo;
+ memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+ dataProfileInfo.profileId = DataProfileId::DEFAULT;
+ dataProfileInfo.apn = hidl_string("internet");
+ dataProfileInfo.protocol = PdpProtocolType::IPV4V6;
+ dataProfileInfo.roamingProtocol = PdpProtocolType::IPV4V6;
+ dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+ dataProfileInfo.user = hidl_string("username");
+ dataProfileInfo.password = hidl_string("password");
+ dataProfileInfo.type = DataProfileInfoType::THREE_GPP;
+ dataProfileInfo.maxConnsTime = 300;
+ dataProfileInfo.maxConns = 20;
+ dataProfileInfo.waitTime = 0;
+ dataProfileInfo.enabled = true;
+ dataProfileInfo.supportedApnTypesBitmap = 320;
+ dataProfileInfo.bearerBitmap = 161543;
+ dataProfileInfo.mtu = 0;
+ dataProfileInfo.preferred = true;
+ dataProfileInfo.persistent = false;
+
+ bool roamingAllowed = false;
+
+ ::android::hardware::radio::V1_2::DataRequestReason reason =
+ ::android::hardware::radio::V1_2::DataRequestReason::NORMAL;
+ std::vector<hidl_string> addresses = {""};
+ std::vector<hidl_string> dnses = {""};
+
+ Return<void> res = radio_v1_4->setupDataCall_1_4(serial, accessNetwork, dataProfileInfo,
+ roamingAllowed, reason, addresses, dnses);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+ }
+}
diff --git a/thermal/2.0/IThermal.hal b/thermal/2.0/IThermal.hal
index f890694..3ea4590 100644
--- a/thermal/2.0/IThermal.hal
+++ b/thermal/2.0/IThermal.hal
@@ -56,22 +56,24 @@
* they go offline, if these devices exist on boot. The method
* always returns and never removes such temperatures. The thresholds
* are returned as static values and must not change across calls. The actual
- * throttling state is determined in driver and HAL and must not be simply
- * compared with these thresholds. To get accurate throttling status, use
- * getCurrentTemperatures or registerThermalChangedCallback and listen.
+ * throttling state is determined in device thermal mitigation policy/agorithm
+ * which might not be simple thresholds so these values Thermal HAL provided
+ * may not be accurate to detemin the throttling status. To get accurate
+ * throttling status, use getCurrentTemperatures or registerThermalChangedCallback
+ * and listen to the callback.
*/
getTemperatureThresholds(bool filterType, TemperatureType type)
generates (ThermalStatus status, vec<TemperatureThreshold> temperatureThresholds);
/**
* Register an IThermalChangedCallback, used by the Thermal HAL
- * to send thermal events when thermal mitigation status changed.
+ * to receive thermal events when thermal mitigation status changed.
* Multiple registrations with different IThermalChangedCallback must be allowed.
* Multiple registrations with same IThermalChangedCallback is not allowed, client
* should unregister the given IThermalChangedCallback first.
*
- * @param callback the IThermalChangedCallback to use for sending
- * thermal events (cannot be nullptr).
+ * @param callback the IThermalChangedCallback to use for receiving
+ * thermal events (nullptr callback will lead to failure with status code FAILURE).
* @param filterType if filter for given sensor type.
* @param type the type to be filtered.
*
@@ -84,11 +86,11 @@
generates (ThermalStatus status);
/**
- * Register an IThermalChangedCallback, used by the Thermal HAL
- * to send thermal events when thermal mitigation status changed.
+ * Unregister an IThermalChangedCallback, used by the Thermal HAL
+ * to receive thermal events when thermal mitigation status changed.
*
- * @param callback the IThermalChangedCallback to use for sending
- * thermal events, or nullptr to set no callback.
+ * @param callback the IThermalChangedCallback used for receiving
+ * thermal events (nullptr callback will lead to failure with status code FAILURE).
*
* @return status Status of the operation. If status code is FAILURE,
* the status.debugMessage must be populated with a human-readable error message.
diff --git a/thermal/2.0/default/Thermal.cpp b/thermal/2.0/default/Thermal.cpp
index 442af61..0ef4b63 100644
--- a/thermal/2.0/default/Thermal.cpp
+++ b/thermal/2.0/default/Thermal.cpp
@@ -155,7 +155,15 @@
bool filterType, TemperatureType type,
registerThermalChangedCallback_cb _hidl_cb) {
ThermalStatus status;
- status.code = ThermalStatusCode::SUCCESS;
+ if (callback == nullptr) {
+ status.code = ThermalStatusCode::FAILURE;
+ status.debugMessage = "Invalid nullptr callback";
+ LOG(ERROR) << status.debugMessage;
+ _hidl_cb(status);
+ return Void();
+ } else {
+ status.code = ThermalStatusCode::SUCCESS;
+ }
std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
if (std::any_of(callbacks_.begin(), callbacks_.end(), [&](const CallbackSetting& c) {
return interfacesEqual(c.callback, callback);
@@ -175,7 +183,15 @@
Return<void> Thermal::unregisterThermalChangedCallback(
const sp<IThermalChangedCallback>& callback, unregisterThermalChangedCallback_cb _hidl_cb) {
ThermalStatus status;
- status.code = ThermalStatusCode::SUCCESS;
+ if (callback == nullptr) {
+ status.code = ThermalStatusCode::FAILURE;
+ status.debugMessage = "Invalid nullptr callback";
+ LOG(ERROR) << status.debugMessage;
+ _hidl_cb(status);
+ return Void();
+ } else {
+ status.code = ThermalStatusCode::SUCCESS;
+ }
bool removed = false;
std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
callbacks_.erase(
diff --git a/thermal/2.0/vts/functional/VtsHalThermalV2_0TargetTest.cpp b/thermal/2.0/vts/functional/VtsHalThermalV2_0TargetTest.cpp
index 3893014..cc2f3df 100644
--- a/thermal/2.0/vts/functional/VtsHalThermalV2_0TargetTest.cpp
+++ b/thermal/2.0/vts/functional/VtsHalThermalV2_0TargetTest.cpp
@@ -132,8 +132,13 @@
TEST_F(ThermalHidlTest, RegisterThermalChangedCallbackTest) {
// Expect to fail with same callback
auto ret = mThermal->registerThermalChangedCallback(
- mThermalCallback, false, TemperatureType::SKIN,
- [](ThermalStatus status) { EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); });
+ mThermalCallback, false, TemperatureType::SKIN,
+ [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::FAILURE, status.code); });
+ ASSERT_TRUE(ret.isOk());
+ // Expect to fail with null callback
+ ret = mThermal->registerThermalChangedCallback(
+ nullptr, false, TemperatureType::SKIN,
+ [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::FAILURE, status.code); });
ASSERT_TRUE(ret.isOk());
sp<ThermalCallback> localThermalCallback = new (std::nothrow) ThermalCallback();
// Expect to succeed with different callback
@@ -141,11 +146,16 @@
localThermalCallback, false, TemperatureType::SKIN,
[](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
ASSERT_TRUE(ret.isOk());
- // Remove the local callback.
+ // Remove the local callback
ret = mThermal->unregisterThermalChangedCallback(
localThermalCallback,
[](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
ASSERT_TRUE(ret.isOk());
+ // Expect to fail with null callback
+ ret = mThermal->unregisterThermalChangedCallback(nullptr, [](ThermalStatus status) {
+ EXPECT_EQ(ThermalStatusCode::FAILURE, status.code);
+ });
+ ASSERT_TRUE(ret.isOk());
}
// Test Thermal->unregisterThermalChangedCallback.