blob: 1d4b681c04e2806544ef9de8ad89e173d285734f [file] [log] [blame]
Tim Yaoe8c0d4a2019-11-27 14:47:35 -08001#include <sys/types.h>
2#include <unistd.h>
3#include <sys/stat.h>
4#include <fcntl.h>
5
6#include <boost/interprocess/managed_shared_memory.hpp>
7#include <cstdlib>
8#include <iomanip>
9#include <mutex>
10#include <signal.h>
11
12#define LOG_TAG "audio_server"
13#include <cutils/log.h>
14
15#include <grpc/grpc.h>
16#include <grpcpp/server.h>
17#include <grpcpp/server_builder.h>
18#include <grpcpp/server_context.h>
19#include <grpcpp/security/server_credentials.h>
20#include "audio_if.h"
21#include "audio_service.grpc.pb.h"
22#include "CircularBuffer.h"
cheng tong7d907882020-09-04 18:53:04 +080023#include "audio_effect_if.h"
Tim Yaoe8c0d4a2019-11-27 14:47:35 -080024
25using grpc::Server;
26using grpc::ServerBuilder;
27using grpc::ServerContext;
28using grpc::ServerReader;
29using grpc::ServerReaderWriter;
30using grpc::ServerWriter;
31using grpc::Status;
32using audio_service::StatusReturn;
33using audio_service::Volume;
34using audio_service::Mode;
35using audio_service::Mute;
36using audio_service::Kv_pairs;
37using audio_service::Keys;
38using audio_service::Handle;
39using audio_service::OpenOutputStream;
40using audio_service::Stream;
41using audio_service::OpenInputStream;
42using audio_service::CreateAudioPatch;
43using audio_service::AudioPortConfig;
44using audio_service::AudioGainConfig;
45using audio_service::AudioPortConfigDeviceExt;
46using audio_service::AudioPortConfigMixExt;
47using audio_service::AudioPortConfigSessionExt;
48using audio_service::StreamSetParameters;
49using audio_service::StreamGetParameters;
50using audio_service::StreamAudioEffect;
51using audio_service::StreamOutSetVolume;
52using audio_service::StreamReadWrite;
53using audio_service::GetFrameTimestampReturn;
54using audio_service::StreamGain;
cheng tong7d907882020-09-04 18:53:04 +080055using audio_service::EffectParameters;
Tim Yaoe8c0d4a2019-11-27 14:47:35 -080056using google::protobuf::Empty;
57
58using namespace boost::interprocess;
59using namespace audio_service;
60
61//#define DEBUG__
62
63#ifdef DEBUG__
64#define TRACE_ENTRY() ALOGI("%s enter\n", __func__)
65#define TRACE_EXIT() ALOGI("%s exit\n", __func__)
66#else
67#define TRACE_ENTRY()
68#define TRACE_EXIT()
69#endif
70
71const int AudioServerShmemSize = 16 * 1024 * 1024;
72
73typedef std::pair<CircularBuffer *, struct audio_stream_out *> streamout_map_t;
74typedef std::pair<CircularBuffer *, struct audio_stream_in *> streamin_map_t;
75
76class AudioServiceImpl final : public AudioService::Service
77{
78 public:
79 explicit AudioServiceImpl(managed_shared_memory &shm)
80 : shm_(shm) {
81 if (audio_hw_load_interface(&dev_) == 0) {
cheng tong7d907882020-09-04 18:53:04 +080082 if (dev_) {
83 effect_ = (audio_effect_t *)dev_->common.reserved[0];
84 }
Tim Yaoe8c0d4a2019-11-27 14:47:35 -080085 //ALOGI(__func__, "[AudioServer] Get audio hal interface successfully.\n");
86 }
87 }
88
89 ~AudioServiceImpl() {
90 if (dev_) {
cheng tong7d907882020-09-04 18:53:04 +080091 if (effect_) {
92 effect_ = nullptr;
93 }
Tim Yaoe8c0d4a2019-11-27 14:47:35 -080094 audio_hw_unload_interface(dev_);
95 dev_ = nullptr;
96 }
97 }
98
99 Status Device_common_close(ServerContext* context, const Empty* empty, StatusReturn* response) {
100 TRACE_ENTRY();
101 if (!dev_) return Status::CANCELLED;
102
103 response->set_ret(dev_->common.close(&dev_->common));
104 return Status::OK;
105 }
106
107 Status Device_init_check(ServerContext* context, const Empty* empty, StatusReturn* response) {
108 TRACE_ENTRY();
109 if (!dev_) return Status::CANCELLED;
110
111 response->set_ret(dev_->init_check(dev_));
112 return Status::OK;
113 }
114
115 Status Device_set_voice_volume(ServerContext* context, const Volume* request, StatusReturn* response) {
116 TRACE_ENTRY();
117 if (!dev_) return Status::CANCELLED;
118
119 response->set_ret(dev_->set_voice_volume(dev_, request->vol()));
120 return Status::OK;
121 }
122
123 Status Device_set_master_volume(ServerContext* context, const Volume* request, StatusReturn* response) {
124 TRACE_ENTRY();
125 if (!dev_) return Status::CANCELLED;
126
127 response->set_ret(dev_->set_master_volume(dev_, request->vol()));
128 return Status::OK;
129 }
130
131 Status Device_get_master_volume(ServerContext* context, const Empty* request, StatusReturn* response) {
132 TRACE_ENTRY();
133 if (!dev_) return Status::CANCELLED;
134
135 float vol = 0.0;
136 response->set_ret(dev_->get_master_volume(dev_, &vol));
137 response->set_status_float(vol);
138 return Status::OK;
139 }
140
141 Status Device_set_mode(ServerContext* context, const Mode* request, StatusReturn* response) {
142 TRACE_ENTRY();
143 if (!dev_) return Status::CANCELLED;
144
145 response->set_ret(dev_->set_mode(dev_, (audio_mode_t)(request->mode())));
146 return Status::OK;
147 }
148
149 Status Device_set_mic_mute(ServerContext* context, const Mute* request, StatusReturn* response) {
150 TRACE_ENTRY();
151 if (!dev_) return Status::CANCELLED;
152
153 response->set_ret(dev_->set_mic_mute(dev_, request->mute()));
154 return Status::OK;
155 }
156
157 Status Device_get_mic_mute(ServerContext* context, const Empty* request, StatusReturn* response) {
158 TRACE_ENTRY();
159 if (!dev_) return Status::CANCELLED;
160
161 bool mute = false;
162 response->set_ret(dev_->get_mic_mute(dev_, &mute));
163 response->set_status_bool(mute);
164 return Status::OK;
165 }
166
167 Status Device_set_parameters(ServerContext* context, const Kv_pairs* request, StatusReturn* response) {
168 TRACE_ENTRY();
169 if (!dev_) return Status::CANCELLED;
170
171 response->set_ret(dev_->set_parameters(dev_, request->params().c_str()));
172 return Status::OK;
173 }
174
175 Status Device_get_parameters(ServerContext* context, const Keys* request, StatusReturn* response) {
176 TRACE_ENTRY();
177 if (!dev_) return Status::CANCELLED;
178
179 char *param = dev_->get_parameters(dev_, request->keys().c_str());
180 response->set_ret(param ? 0 : -1);
181 response->set_status_string(std::string(param));
182
183 // param is heap allocated and need free in behalf of client
184 free(param);
185
186 return Status::OK;
187 }
188
189 Status Device_get_input_buffer_size(ServerContext* context, const AudioConfig* request, StatusReturn* response) {
190 TRACE_ENTRY();
191 if (!dev_) return Status::CANCELLED;
192
193 struct audio_config config;
194 config.sample_rate = request->sample_rate();
195 config.channel_mask = request->channel_mask();
196 config.format = (audio_format_t)(request->format());
197 config.frame_count = request->frame_count();
198
199 response->set_ret(dev_->get_input_buffer_size(dev_, &config));
200 return Status::OK;
201 }
202
203 Status Device_open_output_stream(ServerContext* context, const OpenOutputStream* request, StatusReturn* response) {
204 TRACE_ENTRY();
205 if (!dev_) return Status::CANCELLED;
206
207 struct audio_stream_out *stream = nullptr;
208 struct audio_config config;
209 config.sample_rate = request->config().sample_rate();
210 config.channel_mask = request->config().channel_mask();
211 config.format = (audio_format_t)(request->config().format());
212 config.frame_count = request->config().frame_count();
213
214 streamout_gc_();
215
216 response->set_ret(dev_->open_output_stream(dev_,
217 (audio_io_handle_t)(request->handle()),
218 (audio_devices_t)(request->devices()),
219 (audio_output_flags_t)(request->flags()),
220 &config,
221 &stream,
222 request->address().c_str()));
223
224 if (stream) {
225 CircularBuffer * cb = shm_.find<CircularBuffer>(request->name().c_str()).first;
226 if (cb == nullptr)
227 cb = shm_.construct<CircularBuffer>(request->name().c_str())(shm_, request->size());
228
229 std::lock_guard<std::mutex> lock(map_out_mutex_);
230 streamout_map_.insert(
231 std::pair<const std::string, streamout_map_t>(request->name(), streamout_map_t(cb, stream)));
232 }
233
234 return Status::OK;
235 }
236
237 Status Device_close_output_stream(ServerContext* context, const Stream* request, StatusReturn* response) {
238 TRACE_ENTRY();
239 if (!dev_) return Status::CANCELLED;
240
241 std::map<const std::string, streamout_map_t >::iterator it = streamout_map_.find(request->name());
242 if (it == streamout_map_.end()) return Status::CANCELLED;
243
244 dev_->close_output_stream(dev_, it->second.second);
245
246 if (it->second.first) {
247 shm_.destroy<CircularBuffer>(request->name().c_str());
248 }
249
250 std::lock_guard<std::mutex> lock(map_out_mutex_);
251 streamout_map_.erase(it);
252
253 TRACE_EXIT();
254
255 return Status::OK;
256 }
257
258 Status Device_open_input_stream(ServerContext* context, const OpenInputStream* request, StatusReturn* response) {
259 TRACE_ENTRY();
260 if (!dev_) return Status::CANCELLED;
261
262 struct audio_stream_in *stream = nullptr;
263 struct audio_config config;
264 config.sample_rate = request->config().sample_rate();
265 config.channel_mask = request->config().channel_mask();
266 config.format = (audio_format_t)(request->config().format());
267 config.frame_count = request->config().frame_count();
268
269 streamin_gc_();
270
271 response->set_ret(dev_->open_input_stream(dev_,
272 (audio_io_handle_t)(request->handle()),
273 (audio_devices_t)(request->devices()),
274 &config,
275 &stream,
276 (audio_input_flags_t)(request->flags()),
277 request->address().c_str(),
278 (audio_source_t)(request->source())));
279
280 if (stream) {
281 CircularBuffer * cb = shm_.find<CircularBuffer>(request->name().c_str()).first;
282 if (cb == nullptr)
283 cb = shm_.construct<CircularBuffer>(request->name().c_str())(shm_, request->size());
284
285 std::lock_guard<std::mutex> lock(map_in_mutex_);
286 streamin_map_.insert(
287 std::pair<const std::string, streamin_map_t>(request->name(), streamin_map_t(cb, stream)));
288 }
289
290 return Status::OK;
291 }
292
293 Status Device_close_input_stream(ServerContext* context, const Stream* request, StatusReturn* response) {
294 TRACE_ENTRY();
295 if (!dev_) return Status::CANCELLED;
296
297 std::map<const std::string, streamin_map_t >::iterator it = streamin_map_.find(request->name());
298 if (it == streamin_map_.end()) return Status::CANCELLED;
299
300 dev_->close_input_stream(dev_, it->second.second);
301
302 if (it->second.first) {
303 shm_.destroy<CircularBuffer>(request->name().c_str());
304 }
305
306 std::lock_guard<std::mutex> lock(map_in_mutex_);
307 streamin_map_.erase(it);
308
309 return Status::OK;
310 }
311
312 Status Device_dump(ServerContext* context, const Empty* request, StatusReturn* response) {
313 TRACE_ENTRY();
314 if (!dev_) return Status::CANCELLED;
315
Tim Yaoab2a3a62020-10-29 15:33:55 -0700316 char *param = dev_->dump(dev_, 0);
317 response->set_ret(param ? 0 : -1);
318 response->set_status_string(std::string(param));
319
320 // param is heap allocated and need free
321 free(param);
322
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800323 return Status::OK;
324 }
325
326 Status Device_set_master_mute(ServerContext* context, const Mute* request, StatusReturn* response) {
327 TRACE_ENTRY();
328 if (!dev_) return Status::CANCELLED;
329
330 response->set_ret(dev_->set_master_mute(dev_, request->mute()));
331 return Status::OK;
332 }
333
334 Status Device_get_master_mute(ServerContext* context, const Empty* request, StatusReturn* response) {
335 TRACE_ENTRY();
336 if (!dev_) return Status::CANCELLED;
337
338 bool mute = false;
339 response->set_ret(dev_->get_master_mute(dev_, &mute));
340 response->set_status_bool(mute);
341 return Status::OK;
342 }
343
344 Status Device_create_audio_patch(ServerContext* context, const CreateAudioPatch* request, StatusReturn* response) {
345 TRACE_ENTRY();
346 if (!dev_) return Status::CANCELLED;
347
348 struct audio_port_config *sources, *sinks;
349 unsigned int num_sources = request->sources_size();
350 unsigned int num_sinks = request->sinks_size();
351
352 struct audio_port_config *configs = new struct audio_port_config[num_sources + num_sinks];
353
354 streamout_gc_();
355 streamin_gc_();
356
357 for (int i = 0; i < num_sources + num_sinks; i++) {
358 const AudioPortConfig &config = (i < num_sources) ?
359 request->sources(i) : request->sinks(i - num_sources);
360 configs[i].id = config.id();
361 configs[i].role = (audio_port_role_t)config.role();
362 configs[i].type = (audio_port_type_t)config.type();
363 configs[i].config_mask = config.config_mask();
364 configs[i].sample_rate = config.sample_rate();
365 configs[i].channel_mask = config.channel_mask();
366 configs[i].format = (audio_format_t)config.format();
367
368 // gain
369 configs[i].gain.index = config.gain().index();
370 configs[i].gain.mode = (audio_gain_mode_t)config.gain().mode();
371 configs[i].gain.channel_mask = (audio_channel_mask_t)config.gain().channel_mask();
372 for (int j = 0; j < config.gain().values_size(); j++)
373 configs[i].gain.values[j] = config.gain().values(j);
374 configs[i].gain.ramp_duration_ms = config.gain().ramp_duration_ms();
375
376 if (configs[i].type == AUDIO_PORT_TYPE_DEVICE) {
377 // AudioPortConfigDeviceExt
378 configs[i].ext.device.hw_module = (audio_module_handle_t)config.device().hw_module();
379 configs[i].ext.device.type = (audio_devices_t)config.device().type();
380 strncpy(configs[i].ext.device.address, config.device().address().c_str(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
381 } else if (configs[i].type == AUDIO_PORT_TYPE_MIX) {
382 // AudioPortConfigMixExt
383 configs[i].ext.mix.hw_module = (audio_module_handle_t)config.mix().hw_module();
384 configs[i].ext.mix.handle = (audio_io_handle_t)config.mix().handle();
385 configs[i].ext.mix.usecase.stream = (audio_stream_type_t)config.mix().stream_source();
386 } else if (configs[i].type == AUDIO_PORT_TYPE_SESSION) {
387 // AudioPortConfigSessionExt
388 configs[i].ext.session.session = (audio_session_t)config.session().session();
389 }
390 }
391
392 audio_patch_handle_t handle = (audio_patch_handle_t)(-1);
393 response->set_ret(dev_->create_audio_patch(dev_, num_sources,
394 configs, num_sinks, &configs[num_sources], &handle));
395 response->set_status_32((uint32_t)handle);
396
397 delete [] configs;
398
399 return Status::OK;
400 }
401
402 Status Device_release_audio_patch(ServerContext* context, const Handle* request, StatusReturn* response) {
403 TRACE_ENTRY();
404 if (!dev_) return Status::CANCELLED;
405
406 audio_patch_handle_t handle = (audio_patch_handle_t)(request->handle());
407 response->set_ret(dev_->release_audio_patch(dev_, handle));
408 return Status::OK;
409 }
410
411 Status Device_set_audio_port_config(ServerContext* context, const AudioPortConfig* request, StatusReturn* response) {
412 TRACE_ENTRY();
413 if (!dev_) return Status::CANCELLED;
414
415 struct audio_port_config config;
416
417 config.id = request->id();
418 config.role = (audio_port_role_t)request->role();
419 config.type = (audio_port_type_t)request->type();
420 config.config_mask = request->config_mask();
421 config.sample_rate = request->sample_rate();
422 config.channel_mask = request->channel_mask();
423 config.format = (audio_format_t)request->format();
424
425 // gain
426 config.gain.index = request->gain().index();
427 config.gain.mode = (audio_gain_mode_t)request->gain().mode();
428 config.gain.channel_mask = (audio_channel_mask_t)request->gain().channel_mask();
429 for (int j = 0; j < request->gain().values_size(); j++)
430 config.gain.values[j] = request->gain().values(j);
431 config.gain.ramp_duration_ms = request->gain().ramp_duration_ms();
432
433 if (config.type == AUDIO_PORT_TYPE_DEVICE) {
434 // AudioPortConfigDeviceExt
435 config.ext.device.hw_module = (audio_module_handle_t)request->device().hw_module();
436 config.ext.device.type = (audio_devices_t)request->device().type();
437 strncpy(config.ext.device.address, request->device().address().c_str(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
438 } else if (config.type == AUDIO_PORT_TYPE_MIX) {
439 // AudioPortConfigMixExt
440 config.ext.mix.hw_module = (audio_module_handle_t)request->mix().hw_module();
441 config.ext.mix.handle = (audio_io_handle_t)request->mix().handle();
442 config.ext.mix.usecase.stream = (audio_stream_type_t)request->mix().stream_source();
443 } else if (config.type == AUDIO_PORT_TYPE_SESSION) {
444 // AudioPortConfigSessionExt
445 config.ext.session.session = (audio_session_t)request->session().session();
446 }
447
448 response->set_ret(dev_->set_audio_port_config(dev_, &config));
449 return Status::OK;
450 }
451
452 Status Stream_get_sample_rate(ServerContext* context, const Stream* request, StatusReturn* response) {
453 TRACE_ENTRY();
454 if (!dev_) return Status::CANCELLED;
455
456 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
457 if (stream == nullptr) return Status::CANCELLED;
458
459 response->set_ret(stream->get_sample_rate(stream));
460 return Status::OK;
461 }
462
463 Status Stream_get_buffer_size(ServerContext* context, const Stream* request, StatusReturn* response) {
464 TRACE_ENTRY();
465 if (!dev_) return Status::CANCELLED;
466
467 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
468 if (stream == nullptr) return Status::CANCELLED;
469
470 response->set_ret(stream->get_buffer_size(stream));
471 return Status::OK;
472 }
473
474 Status Stream_get_channels(ServerContext* context, const Stream* request, StatusReturn* response) {
475 TRACE_ENTRY();
476 if (!dev_) return Status::CANCELLED;
477
478 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
479 if (stream == nullptr) return Status::CANCELLED;
480
481 response->set_ret((uint32_t)stream->get_channels(stream));
482 return Status::OK;
483 }
484
485 Status Stream_get_format(ServerContext* context, const Stream* request, StatusReturn* response) {
486 TRACE_ENTRY();
487 if (!dev_) return Status::CANCELLED;
488
489 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
490 if (stream == nullptr) return Status::CANCELLED;
491
492 response->set_ret((uint32_t)stream->get_format(stream));
493 return Status::OK;
494 }
495
496 Status Stream_standby(ServerContext* context, const Stream* request, StatusReturn* response) {
497 TRACE_ENTRY();
498 if (!dev_) return Status::CANCELLED;
499
500 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
501 if (stream == nullptr) return Status::CANCELLED;
502
503 response->set_ret((uint32_t)stream->standby(stream));
504 return Status::OK;
505 }
506
507 Status Stream_get_device(ServerContext* context, const Stream* request, StatusReturn* response) {
508 TRACE_ENTRY();
509 if (!dev_) return Status::CANCELLED;
510
511 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
512 if (stream == nullptr) return Status::CANCELLED;
513
514 response->set_ret((uint32_t)stream->get_device(stream));
515 return Status::OK;
516 }
517
518 Status Stream_set_parameters(ServerContext* context, const StreamSetParameters* request, StatusReturn* response) {
519 TRACE_ENTRY();
520 if (!dev_) return Status::CANCELLED;
521
522 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
523 if (stream == nullptr) return Status::CANCELLED;
524
525 const char *kv_pairs = request->kv_pairs().c_str();
526 response->set_ret(stream->set_parameters(stream, kv_pairs));
527 return Status::OK;
528 }
529
530 Status Stream_get_parameters(ServerContext* context, const StreamGetParameters* request, StatusReturn* response) {
531 TRACE_ENTRY();
532 if (!dev_) return Status::CANCELLED;
533
534 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
535 if (stream == nullptr) return Status::CANCELLED;
536
537 char *param = stream->get_parameters(stream, request->keys().c_str());
538 response->set_ret(param ? 0 : -1);
539 response->set_status_string(std::string(param));
540
541 // param is heap allocated and need free in behalf of client
542 free(param);
543
544 return Status::OK;
545 }
546
547 Status StreamOut_get_latency(ServerContext* context, const Stream* request, StatusReturn* response) {
548 TRACE_ENTRY();
549 if (!dev_) return Status::CANCELLED;
550
551 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
552 if (stream == nullptr) return Status::CANCELLED;
553
554 response->set_ret(stream->get_latency(stream));
555 return Status::OK;
556 }
557
558 Status StreamOut_set_volume(ServerContext* context, const StreamOutSetVolume* request, StatusReturn* response) {
559 TRACE_ENTRY();
560 if (!dev_) return Status::CANCELLED;
561
562 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
563 if (stream == nullptr) return Status::CANCELLED;
564
565 response->set_ret(stream->set_volume(stream, request->left(), request->right()));
566 return Status::OK;
567 }
568
569 Status StreamOut_write(ServerContext* context, const StreamReadWrite* request, StatusReturn* response) {
570 TRACE_ENTRY();
571 if (!dev_) return Status::CANCELLED;
572
573 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
574 if (stream == nullptr) return Status::CANCELLED;
575
576 CircularBuffer *cb = shm_.find<CircularBuffer>(request->name().c_str()).first;
577 response->set_ret(stream->write(stream, cb->start_ptr(shm_), request->size()));
578 return Status::OK;
579 }
580
581 Status StreamOut_get_render_position(ServerContext* context, const Stream* request, StatusReturn* response) {
582 TRACE_ENTRY();
583 if (!dev_) return Status::CANCELLED;
584
585 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
586 if (stream == nullptr) return Status::CANCELLED;
587
588 uint32_t dsp_frames = 0;
589 response->set_ret(stream->get_render_position(stream, &dsp_frames));
590 response->set_status_32(dsp_frames);
591 return Status::OK;
592 }
593
594 Status StreamOut_get_next_write_timestamp(ServerContext* context, const Stream* request, StatusReturn* response) {
595 TRACE_ENTRY();
596 if (!dev_) return Status::CANCELLED;
597
598 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
599 if (stream == nullptr) return Status::CANCELLED;
600
601 int64_t timestamp = 0;
602 response->set_ret(stream->get_next_write_timestamp(stream, &timestamp));
603 response->set_status_64(timestamp);
604 return Status::OK;
605 }
606
607 Status StreamOut_pause(ServerContext* context, const Stream* request, StatusReturn* response) {
608 TRACE_ENTRY();
609 if (!dev_) return Status::CANCELLED;
610
611 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
612 if (stream == nullptr) return Status::CANCELLED;
613
614 response->set_ret(stream->pause(stream));
615 return Status::OK;
616 }
617
618 Status StreamOut_resume(ServerContext* context, const Stream* request, StatusReturn* response) {
619 TRACE_ENTRY();
620 if (!dev_) return Status::CANCELLED;
621
622 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
623 if (stream == nullptr) return Status::CANCELLED;
624
625 response->set_ret(stream->resume(stream));
626 return Status::OK;
627 }
628
629 Status StreamOut_flush(ServerContext* context, const Stream* request, StatusReturn* response) {
630 TRACE_ENTRY();
631 if (!dev_) return Status::CANCELLED;
632
633 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
634 if (stream == nullptr) return Status::CANCELLED;
635
636 response->set_ret(stream->flush(stream));
637 return Status::OK;
638 }
639
640 Status StreamOut_get_presentation_position(ServerContext* context, const Stream* request, GetFrameTimestampReturn* response) {
641 TRACE_ENTRY();
642 if (!dev_) return Status::CANCELLED;
643
644 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
645 if (stream == nullptr) return Status::CANCELLED;
646
647 uint64_t frames = 0;
648 struct timespec timestamp;
649 response->set_ret(stream->get_presentation_position(stream, &frames, &timestamp));
650 response->set_frames(frames);
651 response->mutable_timestamp()->set_seconds((int64_t)timestamp.tv_sec);
652 response->mutable_timestamp()->set_nanos(timestamp.tv_nsec);
653 return Status::OK;
654 }
655
656 Status StreamIn_set_gain(ServerContext* context, const StreamGain* request, StatusReturn* response) {
657 TRACE_ENTRY();
658 if (!dev_) return Status::CANCELLED;
659
660 struct audio_stream_in *stream = find_streamin(request->name(), streamin_map_);
661 if (stream == nullptr) return Status::CANCELLED;
662
663 response->set_ret(stream->set_gain(stream, request->gain()));
664 return Status::OK;
665 }
666
667 Status StreamIn_read(ServerContext* context, const StreamReadWrite* request, StatusReturn* response) {
668 TRACE_ENTRY();
669 if (!dev_) return Status::CANCELLED;
670
671 struct audio_stream_in *stream = find_streamin(request->name(), streamin_map_);
672 if (stream == nullptr) return Status::CANCELLED;
673
674 CircularBuffer *cb = shm_.find<CircularBuffer>(request->name().c_str()).first;
675 response->set_ret(stream->read(stream, cb->start_ptr(shm_), std::min(request->size(), cb->capacity())));
676 return Status::OK;
677 }
678
679 Status StreamIn_get_input_frames_lost(ServerContext* context, const Stream* request, StatusReturn* response) {
680 TRACE_ENTRY();
681 if (!dev_) return Status::CANCELLED;
682
683 struct audio_stream_in *stream = find_streamin(request->name(), streamin_map_);
684 if (stream == nullptr) return Status::CANCELLED;
685
686 response->set_ret(stream->get_input_frames_lost(stream));
687 return Status::OK;
688 }
689
690 Status StreamIn_get_capture_position(ServerContext* context, const Stream* request, GetCapturePositionReturn* response) {
691 TRACE_ENTRY();
692 if (!dev_) return Status::CANCELLED;
693
694 struct audio_stream_in *stream = find_streamin(request->name(), streamin_map_);
695 if (stream == nullptr) return Status::CANCELLED;
696
697 int64_t frames = 0;
698 int64_t time = 0;
699 response->set_ret(stream->get_capture_position(stream, &frames, &time));
700 response->set_frames(frames);
701 response->set_time(time);
702
703 return Status::OK;
704 }
705
706 Status Service_ping(ServerContext* context, const Empty* empty, StatusReturn* response) {
707 TRACE_ENTRY();
708 response->set_status_32(0);
709 return Status::OK;
710 }
711
cheng tong7d907882020-09-04 18:53:04 +0800712 Status Effect_set_parameters(ServerContext* context, const EffectParameters* request, StatusReturn* response) {
713 TRACE_ENTRY();
714 if (!dev_ || !effect_) return Status::CANCELLED;
715
716 aml_audio_effect_type_e type = (aml_audio_effect_type_e)request->type();
717 uint32_t cmdSize = request->cmd_size();
718 void *pCmdData = (void *)request->cmd_data().data();
719 uint32_t replySize = request->reply_size();
720 uint32_t pReplyData = 0;
721
722 response->set_ret(effect_->set_parameters(type, cmdSize, pCmdData, &replySize, &pReplyData));
723 response->set_status_32(pReplyData);
724 return Status::OK;
725 }
726
727 Status Effect_get_parameters(ServerContext* context, const EffectParameters* request, StatusReturn* response) {
728 TRACE_ENTRY();
729 if (!dev_ || !effect_) return Status::CANCELLED;
730
731 aml_audio_effect_type_e type = (aml_audio_effect_type_e)request->type();
732 uint32_t cmdSize = request->cmd_size();
733 void *pCmdData = (void *)request->cmd_data().data();
734 uint32_t replySize = request->reply_size();
735 void * pReplyData = malloc(replySize);
736
737 response->set_ret(effect_->get_parameters(type, cmdSize, pCmdData, &replySize, pReplyData));
738 response->set_status_bytes(pReplyData, replySize);
739 free(pReplyData);
740 pReplyData = nullptr;
741 return Status::OK;
742 }
743
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800744 private:
745 void streamout_gc_()
746 {
747 std::lock_guard<std::mutex> lock_out(map_out_mutex_);
748 for (std::map<const std::string, streamout_map_t >::iterator it = streamout_map_.begin(); it != streamout_map_.end(); ) {
749 int pid, seq;
750 bool need_close = false;
751
752 if (sscanf(it->first.c_str(), "%d-%d", &pid, &seq) == 2) {
753 printf("!!!! found pid = %d\n", pid);
754 // Garbage collect streams when PID does not exists.
755 // It happens when client side crashed, or the client
756 // side does not have the right sequence to close opened streams.
757 if ((kill(pid, 0) == -1) && (errno == ESRCH)) {
758 need_close = true;
759 }
760 }
761 if (need_close) {
762 dev_->close_output_stream(dev_, it->second.second);
763 if (it->second.first) {
764 shm_.destroy<CircularBuffer>(it->first.c_str());
765 }
766 streamout_map_.erase(it++);
767 } else {
768 ++it;
769 }
770 }
771 }
772
773 void streamin_gc_()
774 {
775 std::lock_guard<std::mutex> lock_out(map_in_mutex_);
776 for (std::map<const std::string, streamin_map_t >::iterator it = streamin_map_.begin(); it != streamin_map_.end(); ) {
777 int pid, seq;
778 bool need_close = false;
779
780 if (sscanf(it->first.c_str(), "%d-%d", &pid, &seq) == 2) {
781 // Garbage collect streams when PID does not exists.
782 // It happens when client side crashed, or the client
783 // side does not have the right sequence to close opened streams.
784 if (kill(pid, 0) == ESRCH) {
785 need_close = true;
786 }
787 }
788 if (need_close) {
789 dev_->close_input_stream(dev_, it->second.second);
790 streamin_map_.erase(it++);
791 } else {
792 ++it;
793 }
794 }
795 }
796
797 struct audio_stream *find_stream(std::string name,
798 std::map<const std::string, streamout_map_t> &map_out,
799 std::map<const std::string, streamin_map_t> &map_in)
800 {
801 std::lock_guard<std::mutex> lock_out(map_out_mutex_);
802 std::map<const std::string, streamout_map_t >::iterator it_out = map_out.find(name);
803 if (it_out != map_out.end()) {
804 return &it_out->second.second->common;
805 }
806
807 std::lock_guard<std::mutex> lock_in(map_in_mutex_);
808 std::map<const std::string, streamin_map_t >::iterator it_in = map_in.find(name);
809 if (it_in != map_in.end()) {
810 return &it_in->second.second->common;
811 }
812
813 return nullptr;
814 }
815
816 struct audio_stream_out *find_streamout(std::string name,
817 std::map<const std::string, streamout_map_t> &map_out)
818 {
819 std::lock_guard<std::mutex> lock(map_out_mutex_);
820 std::map<const std::string, streamout_map_t >::iterator it = map_out.find(name);
821 if (it != map_out.end()) {
822 return it->second.second;
823 }
824
825 return nullptr;
826 }
827
828 struct audio_stream_in *find_streamin(std::string name,
829 std::map<const std::string, streamin_map_t> &map_in)
830 {
831 std::lock_guard<std::mutex> lock(map_in_mutex_);
832 std::map<const std::string, streamin_map_t >::iterator it = map_in.find(name);
833 if (it != map_in.end()) {
834 return it->second.second;
835 }
836
837 return nullptr;
838 }
839
840 managed_shared_memory &shm_;
841
842 /* audio hal interface */
843 struct audio_hw_device *dev_;
cheng tong7d907882020-09-04 18:53:04 +0800844 audio_effect_t *effect_;
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800845 static std::mutex map_in_mutex_;
846 static std::mutex map_out_mutex_;
847 std::map<const std::string, streamout_map_t > streamout_map_;
848 std::map<const std::string, streamin_map_t > streamin_map_;
849};
850
851std::mutex AudioServiceImpl::map_out_mutex_;
852std::mutex AudioServiceImpl::map_in_mutex_;
853
854void RunServer(managed_shared_memory& shm)
855{
Tim Yao1b84e362020-08-24 12:51:36 -0700856 const char *url = std::getenv("AUDIO_SERVER_SOCKET");
857 std::string server_address("unix:///opt/audio_socket");
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800858 AudioServiceImpl service(shm);
Tim Yao1b84e362020-08-24 12:51:36 -0700859 if (url) {
860 server_address = url;
861 }
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800862 ServerBuilder builder;
863 builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
864 builder.RegisterService(&service);
865 std::unique_ptr<Server> server(builder.BuildAndStart());
866 std::cout << "[AudioServer] listening on " << server_address << std::endl;
867 server->Wait();
868}
869
870static int daemonize()
871{
872 int fd_pid;
873 const char pidfile[] = "/var/run/audio_server.pid";
874 char pid[10];
875
876 fd_pid = open(pidfile, O_RDWR|O_CREAT, 0600);
877 if (fd_pid == -1) {
878 fprintf(stderr, "Unable to open PID lock file\n");
879 return -1;
880 }
881
882 if (lockf(fd_pid, F_TLOCK, 0) == -1) {
883 fprintf(stderr, "Unable to lock PID file, daemon is existing.\n");
884 return -2;
885 }
886
887 snprintf(pid, sizeof(pid), "%d", getpid());
888 write(fd_pid, pid, strlen(pid));
889
890 return 0;
891}
892
893int main(int argc, char** argv)
894{
895 int r = daemonize();
896 if (r < 0)
897 return r;
898
899 shared_memory_object::remove("AudioServiceShmem");
900 managed_shared_memory shm{open_or_create, "AudioServiceShmem", AudioServerShmemSize};
901
902 RunServer(shm);
903 return 0;
904}