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