1 /*
2  * Copyright (c) 2020 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 
16 #include "audio_capturer_server.h"
17 #include "audio_capturer_impl.h"
18 #include "media_errors.h"
19 #include "media_log.h"
20 #include "securec.h"
21 #include "surface.h"
22 #include "surface_impl.h"
23 
24 using namespace std;
25 using namespace OHOS::Media;
26 namespace OHOS {
27 namespace Audio {
GetInstance()28 AudioCapturerServer *AudioCapturerServer::GetInstance()
29 {
30     static AudioCapturerServer mng;
31     return &mng;
32 }
33 
GetAudioCapturer(pid_t pid)34 AudioCapturerImpl *AudioCapturerServer::GetAudioCapturer(pid_t pid)
35 {
36     return (pid == clientPid_) ? capturer_ : nullptr;
37 }
38 
AudioCapturerServerInit()39 int32_t AudioCapturerServer::AudioCapturerServerInit()
40 {
41     return 0;
42 }
43 
AcceptServer(pid_t pid,IpcIo * reply)44 void AudioCapturerServer::AcceptServer(pid_t pid, IpcIo *reply)
45 {
46     MEDIA_INFO_LOG("in");
47     if (clientPid_ == -1) {
48         capturer_ = new AudioCapturerImpl;
49         clientPid_ = pid;
50         WriteInt32(reply, MEDIA_OK);
51     } else {
52         WriteInt32(reply, MEDIA_IPC_FAILED);
53     }
54 }
55 
DropServer(pid_t pid,IpcIo * reply)56 void AudioCapturerServer::DropServer(pid_t pid, IpcIo *reply)
57 {
58     MEDIA_INFO_LOG("in");
59     if (pid == clientPid_) {
60         if (dataThreadId_ != 0) {
61             threadExit_ = true;
62             pthread_join(dataThreadId_, nullptr);
63             threadExit_ = false;
64             dataThreadId_ = 0;
65         }
66         delete capturer_;
67         capturer_ = nullptr;
68         clientPid_ = -1;
69         bufCache_ = nullptr;
70     }
71     WriteInt32(reply, MEDIA_OK);
72 }
73 
GetCacheBuffer(void)74 SurfaceBuffer *AudioCapturerServer::GetCacheBuffer(void)
75 {
76     if (surface_ == nullptr) {
77         MEDIA_ERR_LOG("No available serverStore in surface.");
78         return nullptr;
79     }
80 
81     if (bufCache_ == nullptr) {
82         bufCache_ = surface_->RequestBuffer();
83     }
84     return bufCache_;
85 }
86 
CancelBuffer(SurfaceBuffer * buffer)87 void AudioCapturerServer::CancelBuffer(SurfaceBuffer *buffer)
88 {
89     surface_->CancelBuffer(buffer);
90     FreeCacheBuffer();
91 }
92 
FreeCacheBuffer(void)93 void AudioCapturerServer::FreeCacheBuffer(void)
94 {
95     bufCache_ = nullptr;
96 }
97 
ReadAudioDataProcess(void * serverStr)98 void *AudioCapturerServer::ReadAudioDataProcess(void *serverStr)
99 {
100     AudioCapturerServer *serverStore = (AudioCapturerServer *)serverStr;
101     if (serverStore == nullptr || serverStore->surface_ == nullptr) {
102         MEDIA_ERR_LOG("No available serverStore in surface.");
103         return nullptr;
104     }
105 
106     MEDIA_INFO_LOG("thread work");
107     while (!serverStore->threadExit_) {
108         /* request surface buffer */
109         SurfaceBuffer *surfaceBuf = serverStore->GetCacheBuffer();
110         if (surfaceBuf == nullptr) {
111             usleep(5000); // indicates 5000 microseconds
112             continue;
113         }
114         uint32_t size = serverStore->surface_->GetSize();
115         void *buf = surfaceBuf->GetVirAddr();
116         if (buf == nullptr) {
117             serverStore->CancelBuffer(surfaceBuf);
118             continue;
119         }
120         uint32_t offSet = sizeof(Timestamp);
121         /* Timestamp + audio data */
122         /* read frame data, and reserve timestamp space */
123         int32_t readLen = serverStore->capturer_->Read((uint8_t *)buf + offSet, size - offSet, true);
124         if (readLen == ERR_INVALID_READ) {
125             continue;
126         }
127 
128         Timestamp timestamp;
129         Timestamp::Timebase base = {};
130         bool ret =  serverStore->capturer_->GetTimestamp(timestamp, base);
131         if (!ret) {
132             MEDIA_ERR_LOG("No readtime get.");
133             continue;
134         }
135         errno_t retCopy = memcpy_s((uint8_t *)buf, sizeof(Timestamp), &timestamp, sizeof(Timestamp));
136         if (retCopy != EOK) {
137             MEDIA_ERR_LOG("retCopy = %x", retCopy);
138             continue;
139         }
140         surfaceBuf->SetSize(sizeof(Timestamp) + readLen);
141 
142         // flush buffer
143         if (serverStore->surface_->FlushBuffer(surfaceBuf) != 0) {
144             MEDIA_ERR_LOG("Flush surface buffer failed.");
145             serverStore->CancelBuffer(surfaceBuf);
146             ret = MEDIA_ERR;
147             continue;
148         }
149         serverStore->FreeCacheBuffer();
150     }
151     MEDIA_INFO_LOG("thread exit");
152     return nullptr;
153 }
154 
SetSurfaceProcess(Surface * surface)155 int32_t AudioCapturerServer::SetSurfaceProcess(Surface *surface)
156 {
157     if (surface == nullptr) {
158         MEDIA_INFO_LOG("Surface is null");
159         return -1;
160     }
161     surface_ = surface;
162 
163     return 0;
164 }
165 
GetMinFrameCount(IpcIo * req,IpcIo * reply)166 void AudioCapturerServer::GetMinFrameCount(IpcIo *req, IpcIo *reply)
167 {
168     int32_t sampleRate = 0;
169     ReadInt32(req, &sampleRate);
170     int32_t channelCount = 0;
171     ReadInt32(req, &channelCount);
172     int32_t data = 0;
173     ReadInt32(req, &data);
174     AudioCodecFormat audioFormat = (AudioCodecFormat)data;
175     size_t frameCount;
176     bool ret = AudioCapturerImpl::GetMinFrameCount(sampleRate, channelCount, audioFormat, frameCount);
177     WriteInt32(reply, ret);
178     WriteUint32(reply, frameCount);
179 }
180 
SetInfo(AudioCapturerImpl * capturer,IpcIo * req,IpcIo * reply)181 void AudioCapturerServer::SetInfo(AudioCapturerImpl *capturer, IpcIo *req, IpcIo *reply)
182 {
183     AudioCapturerInfo info;
184     uint32_t size = 0;
185     ReadUint32(req, &size);
186     void *bufferAdd = (void*)ReadBuffer(req, size);
187 
188     if (bufferAdd == nullptr || size == 0) {
189         MEDIA_INFO_LOG("Readbuffer info failed");
190         WriteInt32(reply, -1);
191         return;
192     }
193     errno_t retCopy = memcpy_s(&info, sizeof(AudioCapturerInfo), bufferAdd, size);
194     if (retCopy != EOK) {
195         MEDIA_ERR_LOG("retCopy = %x", retCopy);
196         return;
197     }
198     int32_t ret = capturer->SetCapturerInfo(info);
199     WriteInt32(reply, ret);
200 }
201 
GetInfo(AudioCapturerImpl * capturer,IpcIo * reply)202 void AudioCapturerServer::GetInfo(AudioCapturerImpl *capturer, IpcIo *reply)
203 {
204     if (capturer == nullptr) {
205         MEDIA_ERR_LOG("GetInfo failed, capturer value is nullptr");
206         return;
207     }
208 
209     AudioCapturerInfo info;
210     int32_t ret = capturer->GetCapturerInfo(info);
211     WriteInt32(reply, ret);
212     WriteUint32(reply, sizeof(AudioCapturerInfo));
213     WriteBuffer(reply, &info, sizeof(AudioCapturerInfo));
214 }
215 
Start(AudioCapturerImpl * capturer,IpcIo * reply)216 void AudioCapturerServer::Start(AudioCapturerImpl *capturer, IpcIo *reply)
217 {
218     if (capturer == nullptr) {
219         MEDIA_ERR_LOG("Start failed, capturer value is nullptr");
220         return;
221     }
222 
223     bool record = capturer->Record();
224     if (record) {
225         threadExit_ = false;
226         pthread_create(&dataThreadId_, nullptr, ReadAudioDataProcess, this);
227         MEDIA_INFO_LOG("create thread ReadAudioDataProcess SUCCESS");
228     }
229     WriteInt32(reply, record);
230 }
231 
Stop(AudioCapturerImpl * capturer,IpcIo * reply)232 void AudioCapturerServer::Stop(AudioCapturerImpl *capturer, IpcIo *reply)
233 {
234     if (capturer == nullptr) {
235         MEDIA_ERR_LOG("Stop failed, capturer value is nullptr");
236         return;
237     }
238     int32_t ret = capturer->Stop();
239     if (dataThreadId_ != 0) {
240         threadExit_ = true;
241         pthread_join(dataThreadId_, nullptr);
242         threadExit_ = false;
243         dataThreadId_ = 0;
244     }
245     WriteInt32(reply, ret);
246 }
247 
GetMiniFrameCount(IpcIo * req,IpcIo * reply)248 void AudioCapturerServer::GetMiniFrameCount(IpcIo *req, IpcIo *reply)
249 {
250     if (reply == nullptr) {
251         MEDIA_ERR_LOG("GetMinFrameCount failed, reply value is nullptr");
252         return;
253     }
254 
255     int32_t sampleRate = 0;
256     ReadInt32(req, &sampleRate);
257     int32_t channelCount = 0;
258     ReadInt32(req, &channelCount);
259     uint32_t size = 0;
260     ReadUint32(req, &size);
261     AudioCodecFormat *audioFormat = (AudioCodecFormat *)ReadBuffer(req, size);
262 
263     size_t frameCount;
264     bool ret = AudioCapturerImpl::GetMinFrameCount(sampleRate, channelCount, *audioFormat, frameCount);
265     WriteInt32(reply, ret);
266     WriteUint64(reply, frameCount);
267 }
268 
GetFrameCount(AudioCapturerImpl * capturer,IpcIo * reply)269 void AudioCapturerServer::GetFrameCount(AudioCapturerImpl *capturer, IpcIo *reply)
270 {
271     if (capturer == nullptr) {
272         MEDIA_ERR_LOG("GetFrameCount failed, capturer value is nullptr");
273         return;
274     }
275 
276     uint64_t frameCount = capturer->GetFrameCount();
277     WriteInt32(reply, MEDIA_OK);
278     WriteUint64(reply, frameCount);
279 }
280 
GetStatus(AudioCapturerImpl * capturer,IpcIo * reply)281 void AudioCapturerServer::GetStatus(AudioCapturerImpl *capturer, IpcIo *reply)
282 {
283     if (capturer == nullptr) {
284         MEDIA_ERR_LOG("GetStatus failed, capturer value is nullptr");
285         return;
286     }
287 
288     State status = capturer->GetStatus();
289     WriteInt32(reply, MEDIA_OK);
290     WriteInt32(reply, status);
291 }
292 
SetSurface(IpcIo * req,IpcIo * reply)293 void AudioCapturerServer::SetSurface(IpcIo *req, IpcIo *reply)
294 {
295     Surface *surface = SurfaceImpl::GenericSurfaceByIpcIo(*req);
296     if (surface == nullptr) {
297         MEDIA_ERR_LOG("SetSurface failed, surface value is nullptr");
298         return;
299     }
300     int32_t ret = SetSurfaceProcess(surface);
301     WriteInt32(reply, ret);
302 }
303 
Dispatch(int32_t funcId,pid_t pid,IpcIo * req,IpcIo * reply)304 void AudioCapturerServer::Dispatch(int32_t funcId, pid_t pid, IpcIo *req, IpcIo *reply)
305 {
306     if (funcId == AUD_CAP_FUNC_GET_MIN_FRAME_COUNT) {
307         return;
308     }
309     if (funcId == AUD_CAP_FUNC_CONNECT) {
310         AcceptServer(pid, reply);
311         return;
312     }
313     auto capturer = GetAudioCapturer(pid);
314     if (capturer == nullptr) {
315         MEDIA_ERR_LOG("Cannot find client object.(pid=%d)", pid);
316         WriteInt32(reply, MEDIA_IPC_FAILED);
317         return;
318     }
319     switch (funcId) {
320         case AUD_CAP_FUNC_DISCONNECT:
321             DropServer(pid, reply);
322             break;
323         case AUD_CAP_FUNC_GET_FRAME_COUNT:
324             GetFrameCount(capturer, reply);
325             break;
326         case AUD_CAP_FUNC_GET_STATUS:
327             GetStatus(capturer, reply);
328             break;
329         case AUD_CAP_FUNC_SET_INFO:
330             SetInfo(capturer, req, reply);
331             break;
332         case AUD_CAP_FUNC_GET_INFO:
333             GetInfo(capturer, reply);
334             break;
335         case AUD_CAP_FUNC_START:
336             Start(capturer, reply);
337             break;
338         case AUD_CAP_FUNC_STOP:
339             Stop(capturer, reply);
340             break;
341         case AUD_CAP_FUNC_RELEASE:
342             WriteInt32(reply, static_cast<int32_t>(capturer->Release()));
343             break;
344         case AUD_CAP_FUNC_SET_SURFACE:
345             SetSurface(req, reply);
346             break;
347         case AUD_CAP_FUNC_GET_MIN_FRAME_COUNT:
348             GetMiniFrameCount(req, reply);
349             break;
350         default:
351             break;
352     }
353 }
354 }  // namespace Audio
355 }  // namespace OHOS
356