1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef LOG_TAG
16 #define LOG_TAG "AudioHapticTest"
17 #endif
18 #include <chrono>
19 #include <fcntl.h>
20 #include <iostream>
21 #include <string>
22 #include <sys/stat.h>
23 #include <thread>
24
25 #include "media_errors.h"
26
27 #include "audio_haptic_manager_impl.h"
28 #include "audio_haptic_test_common.h"
29
30 using namespace OHOS;
31 using namespace OHOS::Media;
32
33 constexpr int32_t ERROR_FILE_DESCRIPTOR = -1;
34 constexpr int32_t ERROR_RESULT = -1;
35 constexpr int32_t ERROR_EXIT = -1;
36 constexpr int32_t MESSGE_OK = 0;
37
38 static std::shared_ptr<AudioHapticManagerImpl> g_audioHapticManagerImpl = nullptr;
39
RegisterSource(std::string audioFilePath,std::string hapticFilePath)40 static int32_t RegisterSource(std::string audioFilePath, std::string hapticFilePath)
41 {
42 int32_t audioFd = open(audioFilePath.c_str(), O_RDONLY);
43 struct stat64 audioBuff = { 0 };
44 int32_t ret = fstat64(audioFd, &audioBuff);
45 if (ret == ERROR_FILE_DESCRIPTOR) {
46 std::cerr << "Audio file invalid: " << audioFilePath << std::endl;
47 return ERROR_RESULT;
48 }
49 AudioHapticFileDescriptor audioFile;
50 audioFile.fd = audioFd;
51 audioFile.offset = 0;
52 audioFile.length = audioBuff.st_size;
53
54 int32_t hapticDd = open(hapticFilePath.c_str(), O_RDONLY);
55 struct stat64 hatpicBuff = { 0 };
56 ret = fstat64(hapticDd, &hatpicBuff);
57 if (ret == ERROR_FILE_DESCRIPTOR) {
58 std::cerr << "Haptic file invalid: " << hapticFilePath << std::endl;
59 return ERROR_RESULT;
60 }
61 AudioHapticFileDescriptor hapticFile;
62 hapticFile.fd = hapticDd;
63 hapticFile.offset = 0;
64 hapticFile.length = hatpicBuff.st_size;
65
66 ret = g_audioHapticManagerImpl->RegisterSourceFromFd(audioFile, hapticFile);
67 close(audioFd);
68 close(hapticDd);
69
70 return ret;
71 }
72
HandleCommand(const std::shared_ptr<AudioHapticPlayer> & player)73 static void HandleCommand(const std::shared_ptr<AudioHapticPlayer> &player)
74 {
75 std::string command;
76 while (true) {
77 std::cout << "Enter command (start/gentle/stop/exit): ";
78 std::cin >> command;
79
80 if (command == "start") {
81 player->Start();
82 } else if (command == "gentle") {
83 player->SetHapticsFeature(HapticsFeature::GENTLE_HAPTICS);
84 } else if (command == "stop") {
85 player->Stop();
86 } else if (command == "exit") {
87 break;
88 } else {
89 std::cout << "Unknown command" << std::endl;
90 }
91 }
92 }
93
main()94 int main()
95 {
96 uint64_t tokenID;
97 GetPermission({"ohos.permission.VIBRATE"}, tokenID, true);
98
99 g_audioHapticManagerImpl = std::make_shared<AudioHapticManagerImpl>();
100
101 std::string audioFilename = "demo.ogg";
102 std::string vibrationFilename = "demo.json";
103
104 int32_t sourceId = RegisterSource(audioFilename, vibrationFilename);
105 if (sourceId == ERROR_RESULT) {
106 std::cout << "failed to register source" << std::endl;
107 return ERROR_EXIT;
108 }
109
110 AudioHapticPlayerOptions options;
111 std::shared_ptr<AudioHapticPlayer> player = g_audioHapticManagerImpl->CreatePlayer(sourceId, options);
112 if (player == nullptr) {
113 std::cout << "failed to create player" << std::endl;
114 return ERROR_EXIT;
115 }
116
117 int32_t result = player->Prepare();
118 if (result != MESSGE_OK) {
119 std::cout << "failed to prepare player" << std::endl;
120 return ERROR_EXIT;
121 }
122
123 HandleCommand(player);
124
125 // Clean up resources
126 player->Release();
127 g_audioHapticManagerImpl->UnregisterSource(sourceId);
128
129 return 0;
130 }