diff --git a/sensor/test/BUILD.gn b/sensor/test/BUILD.gn
index b041b8f069d1e3e0f8b4eed18b680c1adc948143..b431ea0cfb140c5f5d5658b39b0a3c19aaaaa166 100644
--- a/sensor/test/BUILD.gn
+++ b/sensor/test/BUILD.gn
@@ -41,6 +41,7 @@ if (defined(ohos_lite)) {
"unittest/sensor_test_five_clients:SensorTestFiveClients",
"unittest/sensor_test_multi_clients:SensorTestMultiClients",
"unittest/sensor_test_three_clients:SensorTestThreeClients",
+ "unittest/sensor_test_two_clients_enable_als:SensorTestTwoClientsEnableAls",
]
}
}
diff --git a/sensor/test/unittest/sensor_test_two_clients_enable_als/BUILD.gn b/sensor/test/unittest/sensor_test_two_clients_enable_als/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..e2994fe82d785d0ae33ca43196653ff3691045f4
--- /dev/null
+++ b/sensor/test/unittest/sensor_test_two_clients_enable_als/BUILD.gn
@@ -0,0 +1,111 @@
+# Copyright (c) 2025 Huawei Device Co., Ltd.
+# 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.
+
+import("//build/ohos.gni")
+import("//build/test.gni")
+import("../../../sensor.gni")
+
+module_output_path = "drivers_peripheral_sensor/drivers_peripheral_sensor"
+
+group("SensorTestTwoClientsEnableAls") {
+ deps = []
+ testonly = true
+ deps += [
+ ":SensorSetBatchTestSamplingInterval_2",
+ ":SensorSetBatchTestSamplingInterval_100",
+ ]
+}
+
+ohos_unittest("SensorSetBatchTestSamplingInterval_2") {
+ module_out_path = module_output_path
+
+ include_dirs = [
+ "../../../interfaces/include",
+ "../../../interfaces/v1_0",
+ "../../../utils/include",
+ ]
+
+ sources = [ "sensor_setbatch_test.cpp" ]
+
+ cflags = [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ "-fsigned-char",
+ "-fno-common",
+ "-fno-strict-aliasing",
+ ]
+
+ defines = ["SAMPLINGINTERVAL=2000000"]
+
+ if (is_standard_system) {
+ external_deps = [
+ "drivers_interface_sensor:libsensor_proxy_2.0",
+ "drivers_interface_sensor:libsensor_proxy_2.1",
+ "drivers_interface_sensor:libsensor_proxy_3.0",
+ "hdf_core:libhdf_host",
+ "hdf_core:libhdf_utils",
+ "hilog:libhilog",
+ "hitrace:hitrace_meter",
+ "ipc:ipc_single",
+ ]
+ if (c_utils_enable) {
+ external_deps += [ "c_utils:utils" ]
+ }
+ } else {
+ external_deps = [ "hilog:libhilog" ]
+ }
+ external_deps += [ "ipc:ipc_single" ]
+}
+
+ohos_unittest("SensorSetBatchTestSamplingInterval_100") {
+ module_out_path = module_output_path
+
+ include_dirs = [
+ "../../../interfaces/include",
+ "../../../interfaces/v1_0",
+ "../../../utils/include",
+ ]
+
+ sources = [ "sensor_setbatch_test.cpp" ]
+
+ cflags = [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ "-fsigned-char",
+ "-fno-common",
+ "-fno-strict-aliasing",
+ ]
+
+ defines = ["SAMPLINGINTERVAL=100000000"]
+
+ if (is_standard_system) {
+ external_deps = [
+ "drivers_interface_sensor:libsensor_proxy_2.0",
+ "drivers_interface_sensor:libsensor_proxy_2.1",
+ "drivers_interface_sensor:libsensor_proxy_3.0",
+ "hdf_core:libhdf_host",
+ "hdf_core:libhdf_utils",
+ "hilog:libhilog",
+ "hitrace:hitrace_meter",
+ "ipc:ipc_single",
+ ]
+ if (c_utils_enable) {
+ external_deps += [ "c_utils:utils" ]
+ }
+ } else {
+ external_deps = [ "hilog:libhilog" ]
+ }
+ external_deps += [ "ipc:ipc_single" ]
+}
\ No newline at end of file
diff --git a/sensor/test/unittest/sensor_test_two_clients_enable_als/readme_zh.md b/sensor/test/unittest/sensor_test_two_clients_enable_als/readme_zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..07afedae5b426f34befb37bc5e534d70dc8fe89f
--- /dev/null
+++ b/sensor/test/unittest/sensor_test_two_clients_enable_als/readme_zh.md
@@ -0,0 +1,49 @@
+# sensor多客户端能力测试2
+
+> 本测试用例模拟三上游服务订阅sensor的情况。
+> 服务1,通过SetBatch(acc传感器, 2毫秒采样频率, 废弃参数)的方式订阅。
+> 服务2,通过SetBatch(acc传感器, 20毫秒采样频率, 废弃参数)的方式订阅。
+> 服务3,通过SetSdcSensor(acc传感器, true, 10毫秒采样频率)的方式订阅。
+> 最终期望的效果是:2秒时间内:
+> 服务1,收到1000帧数据,由于数据波动,在500-1500之间可认为正常。
+> 服务2,收到100帧数据,由于数据波动,在50-150之间可认为正常。
+
+---
+
+## 目录
+
+- [简介](#简介)
+- [安装说明](#安装说明)
+- [使用示例](#使用示例)
+- [贡献](#贡献)
+- [许可证](#许可证)
+
+---
+
+## 简介
+**图 1** Sensor测试用例模拟图
+
+---
+
+## 运行用例的要领:
+
+### 1. 编译用例
+
+将五个用例编译好后,放到统一路径,在当前路径执行如下命令:
+
+```bash
+hdc target mount
+hdc shell hilog -b D -D 0xD002516
+hdc file send SensorSetBatchTestSamplingInterval_2 /data/SensorSetBatchTestSamplingInterval_2
+hdc file send SensorSetBatchTestSamplingInterval_20 /data/SensorSetBatchTestSamplingInterval_20
+hdc file send SensorSetSdcSensorTestSamplingInterval_10 /data/SensorSetSdcSensorTestSamplingInterval_10
+hdc shell chmod 777 /data/SensorSetBatchTestSamplingInterval_2
+hdc shell chmod 777 /data/SensorSetBatchTestSamplingInterval_20
+hdc shell chmod 777 /data/SensorSetSdcSensorTestSamplingInterval_10
+
+start cmd /k "hdc shell /data/SensorSetBatchTestSamplingInterval_2"
+ping -n 1 -w 100 127.0.0.1 > nul
+start cmd /k "hdc shell /data/SensorSetBatchTestSamplingInterval_20"
+ping -n 1 -w 100 127.0.0.1 > nul
+start cmd /k "hdc shell /data/SensorSetSdcSensorTestSamplingInterval_10"
+parse
\ No newline at end of file
diff --git a/sensor/test/unittest/sensor_test_two_clients_enable_als/sensor_callback_impl.h b/sensor/test/unittest/sensor_test_two_clients_enable_als/sensor_callback_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..6f01770d5ff73aa11b2445c71f8777eb1bce3936
--- /dev/null
+++ b/sensor/test/unittest/sensor_test_two_clients_enable_als/sensor_callback_impl.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * 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 OHOS_HDI_SENSOR_V3_0_SENSORCALLBACKIMPL_H
+#define OHOS_HDI_SENSOR_V3_0_SENSORCALLBACKIMPL_H
+
+#include
+#include "v3_0/isensor_callback.h"
+#include "osal_mem.h"
+#include
+#include "sensor_uhdf_log.h"
+#include "isensor_interface_vdi.h"
+
+#define HDF_LOG_TAG uhdf_sensor_testcase
+
+#define DATA_LEN 256
+
+namespace OHOS {
+namespace HDI {
+namespace Sensor {
+namespace V3_0 {
+class SensorCallbackImpl : public ISensorCallback {
+public:
+ virtual ~SensorCallbackImpl() {}
+
+ int32_t OnDataEvent(const HdfSensorEvents& event) override
+ {
+ PrintData(event);
+ sensorDataCount++;
+ return HDF_SUCCESS;
+ }
+
+ int32_t OnDataEventAsync(const std::vector& events) override
+ {
+ return HDF_SUCCESS;
+ }
+
+ static int32_t sensorDataCount;
+ void PrintData(const HdfSensorEvents &event)
+ {
+ std::string st = {0};
+ DataToStr(st, event);
+ printf("%s: %s\n", __func__, st.c_str());
+ HDF_LOGI("%{public}s: testcase %{public}s\n", __func__, st.c_str());
+ }
+
+ void DataToStr(std::string &str, const HdfSensorEvents &event)
+ {
+ void *origin = OsalMemCalloc(sizeof(uint8_t) * (event.dataLen));
+ if (origin == nullptr) {
+ printf("%s: OsalMemCalloc failed", __func__);
+ return;
+ }
+
+ uint8_t *eventData = static_cast(origin);
+ std::copy(event.data.begin(), event.data.end(), eventData);
+ float *data = reinterpret_cast(eventData);
+ int32_t dataLen = event.dataLen;
+ int32_t dataDimension = static_cast(dataLen / sizeof(float));
+ std::string dataStr = {0};
+ char arrayStr[DATA_LEN] = {0};
+
+ for (int32_t i = 0; i < dataDimension; i++) {
+ if (sprintf_s(arrayStr + strlen(arrayStr), DATA_LEN, "[%f]", data[i]) < 0) {
+ printf("%s: sprintf_s failed", __func__);
+ OsalMemFree(origin);
+ return;
+ }
+ }
+
+ dataStr = arrayStr;
+ str = "sensorHandle: " + SENSOR_HANDLE_TO_STRING(event.deviceSensorInfo) + ", ts: " +
+ std::to_string(event.timestamp / 1e9) + ", data: " + dataStr;
+
+ OsalMemFree(origin);
+ return;
+ }
+};
+} // V3_0
+} // Sensor
+} // HDI
+} // OHOS
+
+#endif // OHOS_HDI_SENSOR_V1_1_SENSORCALLBACKIMPL_H
diff --git a/sensor/test/unittest/sensor_test_two_clients_enable_als/sensor_setbatch_test.cpp b/sensor/test/unittest/sensor_test_two_clients_enable_als/sensor_setbatch_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..226692c5899dfc0b787a00a7e7aca3016d4f5deb
--- /dev/null
+++ b/sensor/test/unittest/sensor_test_two_clients_enable_als/sensor_setbatch_test.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include "hdf_base.h"
+#include "osal_time.h"
+#include "v3_0/isensor_interface.h"
+#include "sensor_type.h"
+#include "sensor_callback_impl.h"
+#include "sensor_uhdf_log.h"
+#include "sensor_trace.h"
+
+using namespace OHOS::HDI::Sensor::V3_0;
+using namespace OHOS::HDI::Sensor;
+using namespace testing::ext;
+int32_t SensorCallbackImpl::sensorDataCount = 0;
+
+namespace {
+ sptr g_sensorInterface = nullptr;
+ sptr g_traditionalCallback = new SensorCallbackImpl();
+ int32_t g_duration = 2000;
+ int64_t g_samplingInterval = SAMPLINGINTERVAL;
+
+ class SensorSetBatchTest : public testing::Test {
+ public:
+ static void SetUpTestCase();
+ static void TearDownTestCase();
+ void SetUp();
+ void TearDown();
+ };
+
+ void SensorSetBatchTest::SetUpTestCase()
+ {
+ g_sensorInterface = V3_0::ISensorInterface::Get();
+ }
+
+ void SensorSetBatchTest::TearDownTestCase()
+ {
+ }
+
+ void SensorSetBatchTest::SetUp()
+ {
+ }
+
+ void SensorSetBatchTest::TearDown()
+ {
+ }
+
+ /**
+ * @tc.name: SensorSetBatchTest1
+ * @tc.desc: Get a client and check whether the client is empty.
+ * @tc.type: FUNC
+ * @tc.require: #I4L3LF
+ */
+ HWTEST_F(SensorSetBatchTest, SensorSetBatchTest1, TestSize.Level1)
+ {
+ ASSERT_NE(nullptr, g_sensorInterface);
+ std::vector info;
+ int32_t ret = g_sensorInterface->GetAllSensorInfo(info);
+ EXPECT_EQ(ret, HDF_SUCCESS);
+
+ HdfSensorInformation hdfSensorInformation = nullptr;
+ DeviceSensorInfo deviceSensorInfo = {DEFAULT_DEVICE_ID, HDF_SENSOR_TYPE_AMBIENT_LIGHT, DEFAULT_SENSOR_ID,
+ DEFAULT_LOCATION};
+ for (auto it : info) {
+ printf("it is {sensorName: %s, vendorName: %s, firmwareVersion: %s, hardwareVersion: %s, maxRange: %f, "
+ "accuracy: %f, power: %f, minDelay: %s, maxDelay: %s, fifoMaxEventCount: %ud, "
+ "deviceSensorInfo: %s, reserved: %ud}\r\n", it.sensorName.c_str(), it.vendorName.c_str(),
+ it.firmwareVersion.c_str(), it.hardwareVersion.c_str(), it.maxRange, it.accuracy, it.power,
+ std::to_string(it.minDelay).c_str(), std::to_string(it.maxDelay).c_str(),
+ it.fifoMaxEventCount, SENSOR_HANDLE_TO_C_STR(it.deviceSensorInfo), it.reserved);
+ if (it.deviceSensorInfo.sensorType == deviceSensorInfo.sensorType) {
+ hdfSensorInformation = it;
+ }
+ }
+ if (hdfSensorInformation == nullptr) {
+ GTEST_SKIP() << "target Sensor not Exist" << std::endl;
+ } else {
+ deviceSensorInfo = hdfSensorInformation.deviceSensorInfo;
+ }
+ if (hdfSensorInformation.minDelay > g_samplingInterval || hdfSensorInformation.maxDelay < g_samplingInterval) {
+ GTEST_SKIP() << "g_samplingInterval not within the frequency range supported by the device" << std::endl;
+ }
+ ret = g_sensorInterface->Register(0, g_traditionalCallback);
+ EXPECT_EQ(ret, HDF_SUCCESS);
+ ret = g_sensorInterface->SetBatch(deviceSensorInfo, g_samplingInterval, 0);
+ EXPECT_EQ(ret, HDF_SUCCESS);
+ ret = g_sensorInterface->Enable(deviceSensorInfo);
+ EXPECT_EQ(ret, HDF_SUCCESS);
+
+ OsalMSleep(g_duration);
+
+ ret = g_sensorInterface->Disable(deviceSensorInfo);
+ EXPECT_EQ(ret, HDF_SUCCESS);
+ ret = g_sensorInterface->Unregister(0, g_traditionalCallback);
+ EXPECT_EQ(ret, HDF_SUCCESS);
+ int expectedMinCount = g_duration / (g_samplingInterval / 1000000) / 2;
+ int expectedMaxCount = g_duration / (g_samplingInterval / 1000000) * 3 / 2;
+ printf("SetBatch({%s}, %s, 0)\r\n", SENSOR_HANDLE_TO_C_STR(deviceSensorInfo),
+ std::to_string(g_samplingInterval).c_str());
+ printf("expectedMinCount is %s, expectedMaxCount is %s\r\n", std::to_string(expectedMinCount).c_str(),
+ std::to_string(expectedMaxCount).c_str());
+ if (SensorCallbackImpl::sensorDataCount > expectedMinCount &&
+ SensorCallbackImpl::sensorDataCount < expectedMaxCount) {
+ printf("\033[32mas expected, 2000ms get sensor data count is %d\033[0m\r\n",
+ SensorCallbackImpl::sensorDataCount);
+ } else {
+ printf("\033[31m[ERROR] 2000ms get sensor data count is %d\033[0m\r\n",
+ SensorCallbackImpl::sensorDataCount);
+ }
+ }
+}
\ No newline at end of file