1# Vibrator 2 3## Overview 4 5### Function 6 7The vibrator driver model is developed based on OpenHarmony Hardware Driver Foundation (HDF) to facilitate vibrator driver development. The vibrator driver model shields the interaction between the device driver and the system, and provides unified and stable driver interface capabilities for the hardware service layer. It also provides open interfaces and interface parsing capabilities for developing vibrator drivers and deploying vibrators in different OSs.<br> The figure below shows the vibrator driver model. 8 9**Figure 1** Vibrator driver model 10 11![Vibrator driver model](figures/vibrator_driver_model.png) 12 13### Basic Concepts 14 15Vibrators can be classified into the following types based on vibration mechanism: 16 17- Rotor vibrator 18 19 The rotor vibrator uses magnetic field caused by current to drive the rotor to rotate and produce vibration. Rotor vibrators include ordinary rotor vibrators and coin rotor vibrators. The rotor vibrators cannot start or stop quickly or implement multiple vibration modes. However, they have small footprint and are cost-efficient. 20 21- Linear vibrator 22 23 The linear vibrator drives the spring mass for linear movement and produce vibration. Linear vibrators include longitudinal and transverse linear vibrators. The linear vibrators start and stop quickly, produce different vibration inductions, and have good sense of direction. 24 25The system calls the vibrator driver APIs to control the vibration of the device. There are two vibration modes: 26 27- One-shot vibration 28 29 The vibrator vibrates once for a given duration. 30 31- Periodic vibration 32 33 The vibrator vibrates at preset intervals. For example, if **haptic.clock.timer** is set to **[600, 600, 200, 600]**, the vibrator waits for 600 ms, vibrates for 600 ms, waits for 200 ms, and vibrates for 600 ms. 34 35### Working Principles 36 37The figure below shows how a vibrator driver is loaded. 38 39**Figure 2** How a vibrator driver works 40 41![How vibrator driver works](figures/vibrator_working.png) 42 43The following describes how a vibrator module driver loads and starts on a Hi3516DV300 that runs the standard system. 44 451. The Device Manager reads the vibrator management configuration from the **device_info.hcs** file. 462. The HDF Configuration Source (HCS) Parser parses the vibrator management configuration and loads the vibrator abstract driver. 473. The Device Manager reads the Vibrator data configuration from the **linear_vibrator_config.hcs** file. 484. The HCS Parser parses the vibrator data configuration and loads the haptic driver. 495. The Vibrator Proxy obtains the vibrator HDI service instance and sends it to the Vibrator Stub over Inter-Process Communication (IPC). 506. The Vibrator Stub processes IPC-related service logic and calls the Light Controller after parameter deserialization. 517. The Vibrator Controller implements the HDI APIs and calls the Vibrator abstract driver APIs over IPC. 528. The haptic driver starts a thread to parse the vibrator haptic module. 539. The haptic driver calls **Start()** in the vibrator abstract driver. 5410. The vibrator abstract driver calls **Start()** in the vibrator differentiated driver to control the vibrator device to vibrate with a given effect. 55 56## Development Guidelines 57 58### When to Use 59 60You can set different vibration effects as needed, for example, customizing vibration effects with different intensities and durations for buttons on the device, and customizing one-shot or periodic vibration effects with different intensities and durations for alarm clocks and incoming calls. 61 62### Available APIs 63 64The vibrator driver model supports static HCS and dynamic parameter configuration. The vibrator hardware service calls **StartOnce()** to trigger continuous vibration and calls **Start()** to trigger vibration with a specified effect. The following table describes the APIs provided by the vibrator driver model for the hardware service layer. 65 66**Table 1** APIs of the vibrator driver model 67 68| API | Description | 69| -------------------------------------- | ------------------------------------------------ | 70| int32_t (*StartOnce)([in] uint32_t duration) | Triggers a one-short vibration with a given duration.<br>**duration** specifies the duration of the one-short vibration. | 71| int32_t (*Start)([in] const char *effectType) | Triggers periodic vibrations with a preset effect. <br>**effectType** indicates the pointer to the preset effect type. | 72| int32_t (*Stop)([in] enum VibratorMode mode) | Stops vibration. <br>**mode** indicates the vibration mode, which can be one-short or periodic vibration. | 73| int32_t (*EnableVibratorModulation)(uint32_t duration, int32_t intensity, int32_t frequency) | Triggers a vibration with the given duration, frequency, and intensity.<br>**duration** indicates the duration of the vibration.<br>**intensity** indicates the vibration amplitude.<br>**frequency** indicates the vibrator frequency in the vibration period.| 74| int32_t (*GetVibratorInfo)([out] struct VibratorInfo **vibratorInfo) | Obtains information about all vibrators whose amplitude and frequency can be set in the system. <br>**vibratorInfo** indicates the pointer to the vibrator information obtained.| 75 76### How to Develop 77 78The vibrator driver model provides APIs for the upper-layer hardware service to trigger a one-shot vibration with a given duration, trigger vibration with a given effect, and stop vibration. This model implements functionalities such as cross-OS porting and device-specific configurations. The development procedure is as follows: 79 801. Develop the vibrator abstract driver based on the driver entry. Specifically, implement the **Bind**, **Init**, **Release**, and **Dispatch** functions, configure resources, and parse the HCS. 81 82 - Call **HDF_INIT** to register the driver entry with the HDF. The HDF calls **Bind** and then **Init** to load the driver. If **Init** fails to be called, the HDF calls **Release** to release the driver resources and exit the vibrator driver model. The vibrator driver model uses the HCS as the configuration source code. For details about HCS fields, see [Configuration Management](driver-hdf-manage.md). The driver entry function is defined as follows: 83 84 ```c 85 /* Register the entry structure object of the vibrator abstract driver. */ 86 struct HdfDriverEntry g_vibratorDriverEntry = { 87 .moduleVersion = 1, // Vibrator module version. 88 .moduleName = "HDF_VIBRATOR", // Vibrator module name, which must be the same as moduleName in the device_info.hcs file. 89 .Bind = BindVibratorDriver, // Bind function for the vibrator driver. 90 .Init = InitVibratorDriver, // Ini function for the vibrator driver. 91 .Release = ReleaseVibratorDriver, // Release function for the vibrator driver. 92 }; 93 /* Call HDF_INIT to register the driver entry with the HDF. */ 94 HDF_INIT(g_vibratorDriverEntry); 95 ``` 96 97 - Develop the vibrator abstract driver. Specifically, implement the **Bind**, **Init**, **Release**, and **Dispatch** functions. 98 99 ```c 100 /* External service published by the vibrator driver. */ 101 static int32_t DispatchVibrator(struct HdfDeviceIoClient *client, 102 int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply) 103 { 104 int32_t loop; 105 106 for (loop = 0; loop < sizeof(g_vibratorCmdHandle) / sizeof(g_vibratorCmdHandle[0]); ++loop) { 107 if ((cmd == g_vibratorCmdHandle[loop].cmd) && (g_vibratorCmdHandle[loop].func != NULL)) { 108 return g_vibratorCmdHandle[loop].func(data, reply); 109 } 110 } 111 112 return HDF_SUCCESS; 113 } 114 115 /* Bind the external service provided by the vibrator driver to the HDF. */ 116 int32_t BindVibratorDriver(struct HdfDeviceObject *device) 117 { 118 struct VibratorDriverData *drvData = NULL; 119 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE); 120 121 drvData = (struct VibratorDriverData *)OsalMemCalloc(sizeof(*drvData)); 122 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_MALLOC_FAIL); 123 124 drvData->ioService.Dispatch = DispatchVibrator; 125 drvData->device = device; 126 device->service = &drvData->ioService; 127 g_vibratorDrvData = drvData; 128 129 return HDF_SUCCESS; 130 } 131 132 /* Entry function for vibrator driver initialization. */ 133 int32_t InitVibratorDriver(struct HdfDeviceObject *device) 134 { 135 struct VibratorDriverData *drvData = NULL; 136 137 drvData->mode = VIBRATOR_MODE_BUTT; 138 drvData->state = VIBRATOR_STATE_IDLE; 139 ...... 140 if (CreateVibratorHaptic(device) != HDF_SUCCESS) { 141 HDF_LOGE("%s: init workQueue failed!", __func__); 142 return HDF_FAILURE; 143 } 144 145 return HDF_SUCCESS; 146 } 147 148 /* Release the resources allocated during vibrator driver initialization. */ 149 void ReleaseVibratorDriver(struct HdfDeviceObject *device) 150 { 151 struct VibratorDriverData *drvData = NULL; 152 ...... 153 (void)DestroyVibratorHaptic(); 154 (void)OsalMutexDestroy(&drvData->mutex); 155 (void)OsalMemFree(drvData); 156 g_vibratorDrvData = NULL; 157 } 158 ``` 159 160 - During system startup, the HDF configuration management loads the vibrator abstract driver based on the device information HCS and publishes the vibrator driver interfaces. 161 162 ```c 163 /* Device information HCS. */ 164 vibrator :: host { 165 hostName = "vibrator_host"; 166 device_vibrator :: device { 167 device0 :: deviceNode { 168 policy = 2; // Policy for the driver to publish services. 169 priority = 100; // Priority (0–200) for starting the vibrator driver. A larger value indicates a lower priority. The recommended value is 100. If the priorities are the same, the device loading sequence is not ensured. 170 preload = 0; // The value 0 means to load the driver by default during the startup of the system. The value 2 means the opposite. 171 permission = 0664; // Permission for the device node created. 172 moduleName = "HDF_VIBRATOR"; // Vibrator driver name. It must be the same as moduleName in the driver entry structure. 173 serviceName = "hdf_misc_vibrator"; // Service published by the vibrator driver. The service name must be unique. 174 deviceMatchAttr = "hdf_vibrator_driver"; // Keyword matching the private data of the driver. The value must be the same as that of match_attr in the private data configuration table of the driver. 175 } 176 } 177 } 178 ``` 179 1802. Create a vibrator haptic model and parse the haptic HCS. 181 182 - Create a vibrator haptic model. 183 184 ```c 185 /* Create a vibrator haptic model, allocate resources, and parse the haptic HCS. */ 186 int32_t CreateVibratorHaptic(struct HdfDeviceObject *device) 187 { 188 struct VibratorHapticData *hapticData = NULL; 189 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE); 190 191 hapticData = (struct VibratorHapticData *)OsalMemCalloc(sizeof(*hapticData)); 192 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_ERR_MALLOC_FAIL); 193 g_vibratorHapticData = hapticData; 194 hapticData->supportHaptic = false; 195 196 if (OsalMutexInit(&hapticData->mutex) != HDF_SUCCESS) { 197 HDF_LOGE("%s: failed to init mutex", __func__); 198 goto EXIT; 199 } 200 201 DListHeadInit(&hapticData->effectSeqHead); 202 203 /* Parse the haptic HCS. */ 204 if (ParserVibratorHapticConfig(device->property) != HDF_SUCCESS) { 205 HDF_LOGE("%s: parser haptic config failed!", __func__); 206 goto EXIT; 207 } 208 209 return HDF_SUCCESS; 210 EXIT: 211 OsalMemFree(hapticData); 212 return HDF_FAILURE; 213 } 214 ``` 215 216 - The vibrator haptic model uses the HCS. For details about the HCS fields, see [Configuration Management](driver-hdf-manage.md). 217 218 ```c 219 /* Vibrator data configuration template (vibrator_config.hcs). */ 220 root { 221 vibratorConfig { 222 boardConfig { 223 match_attr = "hdf_vibrator_driver"; // The value must be the same as that of match_attr in the vibrator device configuration file. 224 vibratorAttr { 225 /* The value 0 means a rotor vibrator, and 1 means a linear vibrator. */ 226 deviceType = 1; // Device type. 227 upportPreset = 1; // Supported preset type. 228 } 229 vibratorHapticConfig { 230 haptic_clock_timer { 231 effectName = "haptic.clock.timer"; 232 type = 1; // The value 0 indicates the built-in mode, and 1 indicates the time sequence. 233 seq = [600, 600, 200, 600]; // Time sequence. 234 } 235 haptic_default_effect { 236 effectName = "haptic.default.effect"; 237 type = 0; 238 seq = [0, 3, 800, 1]; 239 } 240 } 241 } 242 } 243 } 244 ``` 245 2463. Implement the APIs for obtaining vibrator information, triggering and stopping a vibration, and creating and destroying a timer based on the vibration mode. 247 248 The vibrator hardware service calls **StartOnce** to start a one-shot vibration with a given duration and calls **StartEffect** to start vibration with a specified effect. 249 250 ```c 251 /* Trigger a one-short vibration with a given duration. */ 252 static int32_t StartOnce(struct HdfSBuf *data, struct HdfSBuf *reply) 253 { 254 uint32_t duration; 255 int32_t ret; 256 struct VibratorEffectCfg config; 257 struct VibratorDriverData *drvData = GetVibratorDrvData(); 258 (void)reply; 259 ...... 260 config.cfgMode = VIBRATOR_MODE_ONCE; 261 config.duration = duration; 262 config.effect = NULL; 263 /* Create a timer based on the vibration effect. */ 264 ret = StartHaptic(&config); 265 if (ret != HDF_SUCCESS) { 266 HDF_LOGE("%s: start haptic failed!", __func__); 267 return ret; 268 } 269 270 return HDF_SUCCESS; 271 } 272 273 /* Trigger a vibration with a given effect. */ 274 static int32_t StartEffect(struct HdfSBuf *data, struct HdfSBuf *reply) 275 { 276 int32_t ret; 277 const char *effect = NULL; 278 struct VibratorEffectCfg config; 279 struct VibratorDriverData *drvData = GetVibratorDrvData(); 280 (void)reply; 281 ...... 282 config.cfgMode = VIBRATOR_MODE_PRESET; 283 config.duration = 0; 284 config.effect = effect; 285 286 ret = StartHaptic(&config); 287 if (ret != HDF_SUCCESS) { 288 HDF_LOGE("%s: start haptic failed!", __func__); 289 return ret; 290 } 291 292 return HDF_SUCCESS; 293 } 294 295 /* Stop vibration based on the specified vibration mode. */ 296 static int32_t Stop(struct HdfSBuf *data, struct HdfSBuf *reply) 297 { 298 int32_t ret; 299 int32_t mode; 300 struct VibratorDriverData *drvData = GetVibratorDrvData(); 301 (void)reply; 302 ...... 303 /* Stop vibration and destroy the timer. */ 304 ret = StopHaptic(); 305 if (ret != HDF_SUCCESS) { 306 HDF_LOGE("%s: stop haptic failed!", __func__); 307 return ret; 308 } 309 310 (void)OsalMutexLock(&drvData->mutex); 311 drvData->mode = VIBRATOR_MODE_BUTT; 312 (void)OsalMutexUnlock(&drvData->mutex); 313 314 return HDF_SUCCESS; 315 } 316 317 /* Trigger vibration with the given duration, frequency, and intensity. */ 318 static int32_t EnableModulationParameter(struct HdfSBuf *data, struct HdfSBuf *reply) 319 { 320 (void)reply; 321 struct VibratorEffectCfg config; 322 struct VibratorDriverData *drvData; 323 uint32_t duration; 324 int32_t intensity; 325 int32_t frequency; 326 int32_t ret; 327 ..... 328 (void)OsalMutexLock(&drvData->mutex); 329 drvData->mode = VIBRATOR_MODE_ONCE; 330 (void)OsalMutexUnlock(&drvData->mutex); 331 /* Set the vibration intensity and frequency. */ 332 ret = drvData->ops.SetParameter(intensity, frequency); 333 if (ret != HDF_SUCCESS) { 334 HDF_LOGE("%s: set parameter failed", __func__); 335 return HDF_FAILURE; 336 } 337 338 config.cfgMode = VIBRATOR_MODE_ONCE; 339 config.duration = duration; 340 config.effect = NULL; 341 342 ret = StartHaptic(&config); 343 if (ret != HDF_SUCCESS) { 344 HDF_LOGE("%s: start haptic failed", __func__); 345 return HDF_FAILURE; 346 } 347 348 return HDF_SUCCESS; 349 } 350 351 /* Obtain vibrator information, including whether the intensity and frequency can be set and the intensity and frequency range. */ 352 static int32_t GetVibratorInfo(struct HdfSBuf *data, struct HdfSBuf *reply) 353 { 354 (void)data; 355 struct VibratorDriverData *drvData; 356 357 drvData = GetVibratorDrvData(); 358 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); 359 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(reply, HDF_ERR_INVALID_PARAM); 360 361 if (!HdfSbufWriteBuffer(reply, &drvData->vibratorInfo, sizeof(drvData->vibratorInfo))) { 362 HDF_LOGE("%s: write sbuf failed", __func__); 363 return HDF_FAILURE; 364 } 365 366 return HDF_SUCCESS; 367 } 368 ``` 369 3704. Implement the interfaces for the vibrator chipset driver. 371 372 - Register the vibrator chipset driver interfaces when the vibrator chipset driver is initialized successfully. 373 374 ```c 375 /* Register the vibrator chipset driver interfaces. */ 376 int32_t RegisterVibrator(struct VibratorOps *ops) 377 { 378 struct VibratorDriverData *drvData = GetVibratorDrvData(); 379 380 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(ops, HDF_FAILURE); 381 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE); 382 383 (void)OsalMutexLock(&drvData->mutex); 384 drvData->ops.Start = ops->Start; 385 drvData->ops.StartEffect = ops->StartEffect; 386 drvData->ops.Stop = ops->Stop; 387 drvData->ops.SetParameter = ops->SetParameter; 388 (void)OsalMutexUnlock(&drvData->mutex); 389 390 return HDF_SUCCESS; 391 } 392 393 /* Register vibrator information. */ 394 int32_t RegisterVibratorInfo(struct VibratorInfo *vibratorInfo) 395 { 396 struct VibratorDriverData *drvData = GetVibratorDrvData(); 397 398 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(vibratorInfo, HDF_FAILURE); 399 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE); 400 401 (void)OsalMutexLock(&drvData->mutex); 402 if (memcpy_s(&drvData->vibratorInfo, sizeof(drvData->vibratorInfo), vibratorInfo, sizeof(*vibratorInfo)) != EOK) { 403 HDF_LOGE("%s: Memcpy vibrator config failed", __func__); 404 return HDF_FAILURE; 405 } 406 (void)OsalMutexUnlock(&drvData->mutex); 407 408 return HDF_SUCCESS; 409 } 410 ``` 411 412 413 414 - The vibrator driver model provides vibrator chipset driver interfaces. Implement these interfaces as follows: 415 416 ```c 417 /* Stop vibration based on the specified vibration mode. */ 418 static int32_t StopModulationParameter() 419 { 420 uint8_t value[DRV2605L_VALUE_BUTT]; 421 struct Drv2605lDriverData *drvData = NULL; 422 drvData = GetDrv2605lDrvData(); 423 424 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE); 425 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData->drv2605lCfgData, HDF_FAILURE); 426 427 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_MODE; 428 value[DRV2605L_VALUE_INDEX] = (uint8_t)DRV2605_MODE_STANDBY; 429 if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) { 430 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]); 431 return HDF_FAILURE; 432 } 433 434 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_RTPIN; 435 value[DRV2605L_VALUE_INDEX] = (uint8_t)&drvData->drv2605lCfgData->vibratorAttr.defaultIntensity; 436 if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) { 437 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]); 438 } 439 440 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_LRARESON; 441 value[DRV2605L_VALUE_INDEX] = (uint8_t)&drvData->drv2605lCfgData->vibratorAttr.defaultFrequency; 442 if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) { 443 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]); 444 } 445 446 return HDF_SUCCESS; 447 } 448 449 /* Set the vibration intensity and frequency. */ 450 static void SetModulationParameter(int32_t intensity, int32_t frequency) 451 { 452 uint8_t value[DRV2605L_VALUE_BUTT]; 453 struct Drv2605lDriverData *drvData = NULL; 454 drvData = GetDrv2605lDrvData(); 455 456 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE); 457 458 if (intensity != 0) { 459 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_RTPIN; 460 value[DRV2605L_VALUE_INDEX] = (uint8_t)INTENSITY_MAPPING_VALUE(intensity); 461 if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) { 462 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]); 463 return; 464 } 465 } else { 466 HDF_LOGD("%s: the setting of intensity 0 is not supported and \ 467 will be set as the system default intensity", __func__); 468 } 469 470 if (frequency != 0) { 471 value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_LRARESON; 472 value[DRV2605L_VALUE_INDEX] = (uint8_t)FREQUENCY_MAPPING_VALUE(frequency); 473 if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) { 474 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]); 475 return; 476 } 477 } else { 478 HDF_LOGD("%s: the setting of frequency 0 is not supported and \ 479 will be set as the system default frequency", __func__); 480 } 481 } 482 ``` 483 484### Verification 485 486After the driver is developed, develop test cases in the vibrator unit test to verify the basic functionalities of the driver. Use your own platform as the test environment. 487 488```c++ 489/* Initialize the vibrator interface instance before executing test cases. */ 490void HdfVibratorTest::SetUpTestCase() 491{ 492 g_vibratorDev = NewVibratorInterfaceInstance(); 493} 494/* Release test case resources. */ 495void HdfVibratorTest::TearDownTestCase() 496{ 497 if(g_vibratorDev != nullptr){ 498 FreeVibratorInterfaceInstance(); 499 g_vibratorDev = nullptr; 500 } 501} 502 503/* Verify one-short vibration. */ 504HWTEST_F(HdfVibratorTest, PerformOneShotVibratorDuration_001, TestSize.Level1) 505{ 506 ASSERT_NE(nullptr, g_vibratorDev); 507 508 int32_t startRet = g_vibratorDev->StartOnce(g_duration); 509 EXPECT_EQ(startRet, HDF_SUCCESS); 510 511 OsalMSleep(g_sleepTime1); 512 513 int32_t endRet = g_vibratorDev->Stop(VIBRATOR_MODE_ONCE); 514 EXPECT_EQ(endRet, HDF_SUCCESS); 515} 516/* Verify vibration with the preset effect. */ 517HWTEST_F(HdfVibratorTest, ExecuteVibratorEffect_002, TestSize.Level1) 518{ 519 ASSERT_NE(nullptr, g_vibratorDev); 520 521 int32_t startRet = g_vibratorDev->Start(g_builtIn); 522 EXPECT_EQ(startRet, HDF_SUCCESS); 523 524 OsalMSleep(g_sleepTime1); 525 526 int32_t endRet = g_vibratorDev->Stop(VIBRATOR_MODE_PRESET); 527 EXPECT_EQ(endRet, HDF_SUCCESS); 528} 529/* Obtain vibrator information, including whether the intensity and frequency can be set and the intensity and frequency range. */ 530HWTEST_F(HdfVibratorTest, GetVibratorInfo_001, TestSize.Level1) 531{ 532 ASSERT_NE(nullptr, g_vibratorDev); 533 534 int32_t startRet = g_vibratorDev->GetVibratorInfo(&g_vibratorInfo); 535 EXPECT_EQ(startRet, HDF_SUCCESS); 536 EXPECT_NE(g_vibratorInfo, nullptr); 537 538 printf("intensity = %d, intensityMaxValue = %d, intensityMinValue = %d\n\t", 539 g_vibratorInfo->isSupportIntensity, g_vibratorInfo->intensityMaxValue, g_vibratorInfo->intensityMinValue); 540 printf("frequency = %d, frequencyMaxValue = %d, frequencyMinValue = %d\n\t", 541 g_vibratorInfo->isSupportFrequency, g_vibratorInfo->frequencyMaxValue, g_vibratorInfo->frequencyMinValue); 542} 543/* Trigger vibration with the given duration, frequency, and intensity. */ 544HWTEST_F(HdfVibratorTest, EnableVibratorModulation_001, TestSize.Level1) 545{ 546 int32_t startRet; 547 ASSERT_NE(nullptr, g_vibratorDev); 548 EXPECT_GT(g_duration, 0); 549 550 if ((g_vibratorInfo->isSupportIntensity == 1) || (g_vibratorInfo->isSupportFrequency == 1)) { 551 EXPECT_GE(g_intensity1, g_vibratorInfo->intensityMinValue); 552 EXPECT_LE(g_intensity1, g_vibratorInfo->intensityMaxValue); 553 EXPECT_GE(g_frequency1, g_vibratorInfo->frequencyMinValue); 554 EXPECT_LE(g_frequency1, g_vibratorInfo->frequencyMaxValue); 555 556 startRet = g_vibratorDev->EnableVibratorModulation(g_duration, g_intensity1, g_frequency1); 557 EXPECT_EQ(startRet, HDF_SUCCESS); 558 OsalMSleep(g_sleepTime1); 559 startRet = g_vibratorDev->Stop(VIBRATOR_MODE_ONCE); 560 EXPECT_EQ(startRet, HDF_SUCCESS); 561 } 562} 563``` 564