blob: bedeb6e1ece238cab1ab46cfaa5ab4c218dcb645 [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>
Tim Yaoaaa3bc52020-12-30 17:40:14 -080025#include <IpcBuffer/audio_server_shmem.h>
26#include <IpcBuffer/IpcBuffer.h>
Tim Yaoe8c0d4a2019-11-27 14:47:35 -080027#include "audio_if.h"
28#include "audio_service.grpc.pb.h"
cheng tong7d907882020-09-04 18:53:04 +080029#include "audio_effect_if.h"
Tim Yaoe8c0d4a2019-11-27 14:47:35 -080030
31using grpc::Server;
32using grpc::ServerBuilder;
33using grpc::ServerContext;
34using grpc::ServerReader;
35using grpc::ServerReaderWriter;
36using grpc::ServerWriter;
37using grpc::Status;
38using audio_service::StatusReturn;
39using audio_service::Volume;
40using audio_service::Mode;
41using audio_service::Mute;
42using audio_service::Kv_pairs;
43using audio_service::Keys;
44using audio_service::Handle;
45using audio_service::OpenOutputStream;
46using audio_service::Stream;
47using audio_service::OpenInputStream;
48using audio_service::CreateAudioPatch;
49using audio_service::AudioPortConfig;
50using audio_service::AudioGainConfig;
51using audio_service::AudioPortConfigDeviceExt;
52using audio_service::AudioPortConfigMixExt;
53using audio_service::AudioPortConfigSessionExt;
54using audio_service::StreamSetParameters;
55using audio_service::StreamGetParameters;
56using audio_service::StreamAudioEffect;
57using audio_service::StreamOutSetVolume;
58using audio_service::StreamReadWrite;
59using audio_service::GetFrameTimestampReturn;
60using audio_service::StreamGain;
cheng tong7d907882020-09-04 18:53:04 +080061using audio_service::EffectParameters;
Tim Yaoe8c0d4a2019-11-27 14:47:35 -080062using google::protobuf::Empty;
63
64using namespace boost::interprocess;
65using namespace audio_service;
66
67//#define DEBUG__
68
69#ifdef DEBUG__
70#define TRACE_ENTRY() ALOGI("%s enter\n", __func__)
71#define TRACE_EXIT() ALOGI("%s exit\n", __func__)
72#else
73#define TRACE_ENTRY()
74#define TRACE_EXIT()
75#endif
76
Tim Yaoaaa3bc52020-12-30 17:40:14 -080077typedef std::pair<IpcBuffer *, struct audio_stream_out *> streamout_map_t;
78typedef std::pair<IpcBuffer *, struct audio_stream_in *> streamin_map_t;
Tim Yaoe8c0d4a2019-11-27 14:47:35 -080079
80class AudioServiceImpl final : public AudioService::Service
81{
82 public:
Tim Yaoaaa3bc52020-12-30 17:40:14 -080083 explicit AudioServiceImpl()
84 : shm_(audio_server_shmem::getInstance(true)),
Tim Yaob414f482021-02-17 17:59:46 -080085 gc_runner_stop_(false),
Tim Yao031950f2020-12-16 11:36:20 -080086 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) {
Tim Yaoaaa3bc52020-12-30 17:40:14 -0800245 IpcBuffer * cb = shm_->find<IpcBuffer>(request->name().c_str()).first;
246 if (cb == nullptr) {
247 cb = shm_->construct<IpcBuffer>(request->name().c_str())(request->name().c_str(), request->size());
wei.du1e60c122021-11-04 11:01:16 +0800248 std::cout << "[AudioServer] open stream pid-seq " << request->name().c_str() << std::endl;
249 ALOGI("%s pid-seq %s\n", __func__, request->name().c_str());
Tim Yaoaaa3bc52020-12-30 17:40:14 -0800250 }
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800251
252 std::lock_guard<std::mutex> lock(map_out_mutex_);
253 streamout_map_.insert(
254 std::pair<const std::string, streamout_map_t>(request->name(), streamout_map_t(cb, stream)));
255 }
256
257 return Status::OK;
258 }
259
260 Status Device_close_output_stream(ServerContext* context, const Stream* request, StatusReturn* response) {
261 TRACE_ENTRY();
262 if (!dev_) return Status::CANCELLED;
263
264 std::map<const std::string, streamout_map_t >::iterator it = streamout_map_.find(request->name());
265 if (it == streamout_map_.end()) return Status::CANCELLED;
266
wei.du1e60c122021-11-04 11:01:16 +0800267 std::cout << "[AudioServer] close stream pid-seq " << request->name().c_str() << std::endl;
268 ALOGI("%s pid-seq %s\n", __func__, request->name().c_str());
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800269 dev_->close_output_stream(dev_, it->second.second);
270
271 if (it->second.first) {
Tim Yaoaaa3bc52020-12-30 17:40:14 -0800272 shm_->destroy<IpcBuffer>(request->name().c_str());
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800273 }
274
275 std::lock_guard<std::mutex> lock(map_out_mutex_);
276 streamout_map_.erase(it);
277
278 TRACE_EXIT();
279
280 return Status::OK;
281 }
282
283 Status Device_open_input_stream(ServerContext* context, const OpenInputStream* request, StatusReturn* response) {
284 TRACE_ENTRY();
285 if (!dev_) return Status::CANCELLED;
286
287 struct audio_stream_in *stream = nullptr;
288 struct audio_config config;
289 config.sample_rate = request->config().sample_rate();
290 config.channel_mask = request->config().channel_mask();
291 config.format = (audio_format_t)(request->config().format());
292 config.frame_count = request->config().frame_count();
293
294 streamin_gc_();
295
296 response->set_ret(dev_->open_input_stream(dev_,
297 (audio_io_handle_t)(request->handle()),
298 (audio_devices_t)(request->devices()),
299 &config,
300 &stream,
301 (audio_input_flags_t)(request->flags()),
302 request->address().c_str(),
303 (audio_source_t)(request->source())));
304
305 if (stream) {
Tim Yaoaaa3bc52020-12-30 17:40:14 -0800306 IpcBuffer * cb = shm_->find<IpcBuffer>(request->name().c_str()).first;
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800307 if (cb == nullptr)
Tim Yaoaaa3bc52020-12-30 17:40:14 -0800308 cb = shm_->construct<IpcBuffer>(request->name().c_str())(request->name().c_str(), request->size());
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800309
310 std::lock_guard<std::mutex> lock(map_in_mutex_);
311 streamin_map_.insert(
312 std::pair<const std::string, streamin_map_t>(request->name(), streamin_map_t(cb, stream)));
313 }
314
315 return Status::OK;
316 }
317
318 Status Device_close_input_stream(ServerContext* context, const Stream* request, StatusReturn* response) {
319 TRACE_ENTRY();
320 if (!dev_) return Status::CANCELLED;
321
322 std::map<const std::string, streamin_map_t >::iterator it = streamin_map_.find(request->name());
323 if (it == streamin_map_.end()) return Status::CANCELLED;
324
325 dev_->close_input_stream(dev_, it->second.second);
326
327 if (it->second.first) {
Tim Yaoaaa3bc52020-12-30 17:40:14 -0800328 shm_->destroy<IpcBuffer>(request->name().c_str());
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800329 }
330
331 std::lock_guard<std::mutex> lock(map_in_mutex_);
332 streamin_map_.erase(it);
333
334 return Status::OK;
335 }
336
337 Status Device_dump(ServerContext* context, const Empty* request, StatusReturn* response) {
338 TRACE_ENTRY();
339 if (!dev_) return Status::CANCELLED;
340
Tim Yaoab2a3a62020-10-29 15:33:55 -0700341 char *param = dev_->dump(dev_, 0);
342 response->set_ret(param ? 0 : -1);
343 response->set_status_string(std::string(param));
344
345 // param is heap allocated and need free
346 free(param);
347
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800348 return Status::OK;
349 }
350
351 Status Device_set_master_mute(ServerContext* context, const Mute* request, StatusReturn* response) {
352 TRACE_ENTRY();
353 if (!dev_) return Status::CANCELLED;
354
355 response->set_ret(dev_->set_master_mute(dev_, request->mute()));
356 return Status::OK;
357 }
358
359 Status Device_get_master_mute(ServerContext* context, const Empty* request, StatusReturn* response) {
360 TRACE_ENTRY();
361 if (!dev_) return Status::CANCELLED;
362
363 bool mute = false;
364 response->set_ret(dev_->get_master_mute(dev_, &mute));
365 response->set_status_bool(mute);
366 return Status::OK;
367 }
368
369 Status Device_create_audio_patch(ServerContext* context, const CreateAudioPatch* request, StatusReturn* response) {
370 TRACE_ENTRY();
371 if (!dev_) return Status::CANCELLED;
372
373 struct audio_port_config *sources, *sinks;
374 unsigned int num_sources = request->sources_size();
375 unsigned int num_sinks = request->sinks_size();
376
377 struct audio_port_config *configs = new struct audio_port_config[num_sources + num_sinks];
378
379 streamout_gc_();
380 streamin_gc_();
381
382 for (int i = 0; i < num_sources + num_sinks; i++) {
383 const AudioPortConfig &config = (i < num_sources) ?
384 request->sources(i) : request->sinks(i - num_sources);
385 configs[i].id = config.id();
386 configs[i].role = (audio_port_role_t)config.role();
387 configs[i].type = (audio_port_type_t)config.type();
388 configs[i].config_mask = config.config_mask();
389 configs[i].sample_rate = config.sample_rate();
390 configs[i].channel_mask = config.channel_mask();
391 configs[i].format = (audio_format_t)config.format();
392
393 // gain
394 configs[i].gain.index = config.gain().index();
395 configs[i].gain.mode = (audio_gain_mode_t)config.gain().mode();
396 configs[i].gain.channel_mask = (audio_channel_mask_t)config.gain().channel_mask();
397 for (int j = 0; j < config.gain().values_size(); j++)
398 configs[i].gain.values[j] = config.gain().values(j);
399 configs[i].gain.ramp_duration_ms = config.gain().ramp_duration_ms();
400
401 if (configs[i].type == AUDIO_PORT_TYPE_DEVICE) {
402 // AudioPortConfigDeviceExt
403 configs[i].ext.device.hw_module = (audio_module_handle_t)config.device().hw_module();
404 configs[i].ext.device.type = (audio_devices_t)config.device().type();
405 strncpy(configs[i].ext.device.address, config.device().address().c_str(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
406 } else if (configs[i].type == AUDIO_PORT_TYPE_MIX) {
407 // AudioPortConfigMixExt
408 configs[i].ext.mix.hw_module = (audio_module_handle_t)config.mix().hw_module();
409 configs[i].ext.mix.handle = (audio_io_handle_t)config.mix().handle();
410 configs[i].ext.mix.usecase.stream = (audio_stream_type_t)config.mix().stream_source();
411 } else if (configs[i].type == AUDIO_PORT_TYPE_SESSION) {
412 // AudioPortConfigSessionExt
413 configs[i].ext.session.session = (audio_session_t)config.session().session();
414 }
415 }
416
417 audio_patch_handle_t handle = (audio_patch_handle_t)(-1);
418 response->set_ret(dev_->create_audio_patch(dev_, num_sources,
419 configs, num_sinks, &configs[num_sources], &handle));
420 response->set_status_32((uint32_t)handle);
421
422 delete [] configs;
423
424 return Status::OK;
425 }
426
427 Status Device_release_audio_patch(ServerContext* context, const Handle* request, StatusReturn* response) {
428 TRACE_ENTRY();
429 if (!dev_) return Status::CANCELLED;
430
431 audio_patch_handle_t handle = (audio_patch_handle_t)(request->handle());
432 response->set_ret(dev_->release_audio_patch(dev_, handle));
433 return Status::OK;
434 }
435
436 Status Device_set_audio_port_config(ServerContext* context, const AudioPortConfig* request, StatusReturn* response) {
437 TRACE_ENTRY();
438 if (!dev_) return Status::CANCELLED;
439
440 struct audio_port_config config;
441
442 config.id = request->id();
443 config.role = (audio_port_role_t)request->role();
444 config.type = (audio_port_type_t)request->type();
445 config.config_mask = request->config_mask();
446 config.sample_rate = request->sample_rate();
447 config.channel_mask = request->channel_mask();
448 config.format = (audio_format_t)request->format();
449
450 // gain
451 config.gain.index = request->gain().index();
452 config.gain.mode = (audio_gain_mode_t)request->gain().mode();
453 config.gain.channel_mask = (audio_channel_mask_t)request->gain().channel_mask();
454 for (int j = 0; j < request->gain().values_size(); j++)
455 config.gain.values[j] = request->gain().values(j);
456 config.gain.ramp_duration_ms = request->gain().ramp_duration_ms();
457
458 if (config.type == AUDIO_PORT_TYPE_DEVICE) {
459 // AudioPortConfigDeviceExt
460 config.ext.device.hw_module = (audio_module_handle_t)request->device().hw_module();
461 config.ext.device.type = (audio_devices_t)request->device().type();
462 strncpy(config.ext.device.address, request->device().address().c_str(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
463 } else if (config.type == AUDIO_PORT_TYPE_MIX) {
464 // AudioPortConfigMixExt
465 config.ext.mix.hw_module = (audio_module_handle_t)request->mix().hw_module();
466 config.ext.mix.handle = (audio_io_handle_t)request->mix().handle();
467 config.ext.mix.usecase.stream = (audio_stream_type_t)request->mix().stream_source();
468 } else if (config.type == AUDIO_PORT_TYPE_SESSION) {
469 // AudioPortConfigSessionExt
470 config.ext.session.session = (audio_session_t)request->session().session();
471 }
472
473 response->set_ret(dev_->set_audio_port_config(dev_, &config));
474 return Status::OK;
475 }
476
477 Status Stream_get_sample_rate(ServerContext* context, const Stream* request, StatusReturn* response) {
478 TRACE_ENTRY();
479 if (!dev_) return Status::CANCELLED;
480
481 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
482 if (stream == nullptr) return Status::CANCELLED;
483
484 response->set_ret(stream->get_sample_rate(stream));
485 return Status::OK;
486 }
487
488 Status Stream_get_buffer_size(ServerContext* context, const Stream* request, StatusReturn* response) {
489 TRACE_ENTRY();
490 if (!dev_) return Status::CANCELLED;
491
492 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
493 if (stream == nullptr) return Status::CANCELLED;
494
495 response->set_ret(stream->get_buffer_size(stream));
496 return Status::OK;
497 }
498
499 Status Stream_get_channels(ServerContext* context, const Stream* request, StatusReturn* response) {
500 TRACE_ENTRY();
501 if (!dev_) return Status::CANCELLED;
502
503 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
504 if (stream == nullptr) return Status::CANCELLED;
505
506 response->set_ret((uint32_t)stream->get_channels(stream));
507 return Status::OK;
508 }
509
510 Status Stream_get_format(ServerContext* context, const Stream* request, StatusReturn* response) {
511 TRACE_ENTRY();
512 if (!dev_) return Status::CANCELLED;
513
514 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
515 if (stream == nullptr) return Status::CANCELLED;
516
517 response->set_ret((uint32_t)stream->get_format(stream));
518 return Status::OK;
519 }
520
521 Status Stream_standby(ServerContext* context, const Stream* request, StatusReturn* response) {
522 TRACE_ENTRY();
523 if (!dev_) return Status::CANCELLED;
524
525 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
526 if (stream == nullptr) return Status::CANCELLED;
527
528 response->set_ret((uint32_t)stream->standby(stream));
529 return Status::OK;
530 }
531
532 Status Stream_get_device(ServerContext* context, const Stream* request, StatusReturn* response) {
533 TRACE_ENTRY();
534 if (!dev_) return Status::CANCELLED;
535
536 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
537 if (stream == nullptr) return Status::CANCELLED;
538
539 response->set_ret((uint32_t)stream->get_device(stream));
540 return Status::OK;
541 }
542
543 Status Stream_set_parameters(ServerContext* context, const StreamSetParameters* request, StatusReturn* response) {
544 TRACE_ENTRY();
545 if (!dev_) return Status::CANCELLED;
546
547 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
548 if (stream == nullptr) return Status::CANCELLED;
549
550 const char *kv_pairs = request->kv_pairs().c_str();
551 response->set_ret(stream->set_parameters(stream, kv_pairs));
552 return Status::OK;
553 }
554
555 Status Stream_get_parameters(ServerContext* context, const StreamGetParameters* request, StatusReturn* response) {
556 TRACE_ENTRY();
557 if (!dev_) return Status::CANCELLED;
558
559 struct audio_stream *stream = find_stream(request->name(), streamout_map_, streamin_map_);
560 if (stream == nullptr) return Status::CANCELLED;
561
562 char *param = stream->get_parameters(stream, request->keys().c_str());
563 response->set_ret(param ? 0 : -1);
564 response->set_status_string(std::string(param));
565
566 // param is heap allocated and need free in behalf of client
567 free(param);
568
569 return Status::OK;
570 }
571
572 Status StreamOut_get_latency(ServerContext* context, const Stream* request, StatusReturn* response) {
573 TRACE_ENTRY();
574 if (!dev_) return Status::CANCELLED;
575
576 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
577 if (stream == nullptr) return Status::CANCELLED;
578
579 response->set_ret(stream->get_latency(stream));
580 return Status::OK;
581 }
582
583 Status StreamOut_set_volume(ServerContext* context, const StreamOutSetVolume* request, StatusReturn* response) {
584 TRACE_ENTRY();
585 if (!dev_) return Status::CANCELLED;
586
587 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
588 if (stream == nullptr) return Status::CANCELLED;
589
590 response->set_ret(stream->set_volume(stream, request->left(), request->right()));
591 return Status::OK;
592 }
593
594 Status StreamOut_write(ServerContext* context, const StreamReadWrite* 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
Tim Yaoaaa3bc52020-12-30 17:40:14 -0800601 IpcBuffer *cb = shm_->find<IpcBuffer>(request->name().c_str()).first;
602 response->set_ret(stream->write(stream, cb->start_ptr(), request->size()));
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800603 return Status::OK;
604 }
605
606 Status StreamOut_get_render_position(ServerContext* context, const Stream* request, StatusReturn* response) {
607 TRACE_ENTRY();
608 if (!dev_) return Status::CANCELLED;
609
610 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
611 if (stream == nullptr) return Status::CANCELLED;
612
613 uint32_t dsp_frames = 0;
614 response->set_ret(stream->get_render_position(stream, &dsp_frames));
615 response->set_status_32(dsp_frames);
616 return Status::OK;
617 }
618
619 Status StreamOut_get_next_write_timestamp(ServerContext* context, const Stream* request, StatusReturn* response) {
620 TRACE_ENTRY();
621 if (!dev_) return Status::CANCELLED;
622
623 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
624 if (stream == nullptr) return Status::CANCELLED;
625
626 int64_t timestamp = 0;
627 response->set_ret(stream->get_next_write_timestamp(stream, &timestamp));
628 response->set_status_64(timestamp);
629 return Status::OK;
630 }
631
632 Status StreamOut_pause(ServerContext* context, const Stream* request, StatusReturn* response) {
633 TRACE_ENTRY();
634 if (!dev_) return Status::CANCELLED;
635
636 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
637 if (stream == nullptr) return Status::CANCELLED;
638
639 response->set_ret(stream->pause(stream));
640 return Status::OK;
641 }
642
643 Status StreamOut_resume(ServerContext* context, const Stream* request, StatusReturn* response) {
644 TRACE_ENTRY();
645 if (!dev_) return Status::CANCELLED;
646
647 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
648 if (stream == nullptr) return Status::CANCELLED;
649
650 response->set_ret(stream->resume(stream));
651 return Status::OK;
652 }
653
654 Status StreamOut_flush(ServerContext* context, const Stream* request, StatusReturn* response) {
655 TRACE_ENTRY();
656 if (!dev_) return Status::CANCELLED;
657
658 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
659 if (stream == nullptr) return Status::CANCELLED;
660
661 response->set_ret(stream->flush(stream));
662 return Status::OK;
663 }
664
665 Status StreamOut_get_presentation_position(ServerContext* context, const Stream* request, GetFrameTimestampReturn* response) {
666 TRACE_ENTRY();
667 if (!dev_) return Status::CANCELLED;
668
669 struct audio_stream_out *stream = find_streamout(request->name(), streamout_map_);
670 if (stream == nullptr) return Status::CANCELLED;
671
672 uint64_t frames = 0;
673 struct timespec timestamp;
674 response->set_ret(stream->get_presentation_position(stream, &frames, &timestamp));
675 response->set_frames(frames);
676 response->mutable_timestamp()->set_seconds((int64_t)timestamp.tv_sec);
677 response->mutable_timestamp()->set_nanos(timestamp.tv_nsec);
678 return Status::OK;
679 }
680
681 Status StreamIn_set_gain(ServerContext* context, const StreamGain* request, StatusReturn* response) {
682 TRACE_ENTRY();
683 if (!dev_) return Status::CANCELLED;
684
685 struct audio_stream_in *stream = find_streamin(request->name(), streamin_map_);
686 if (stream == nullptr) return Status::CANCELLED;
687
688 response->set_ret(stream->set_gain(stream, request->gain()));
689 return Status::OK;
690 }
691
692 Status StreamIn_read(ServerContext* context, const StreamReadWrite* request, StatusReturn* response) {
693 TRACE_ENTRY();
694 if (!dev_) return Status::CANCELLED;
695
696 struct audio_stream_in *stream = find_streamin(request->name(), streamin_map_);
697 if (stream == nullptr) return Status::CANCELLED;
698
Tim Yaoaaa3bc52020-12-30 17:40:14 -0800699 IpcBuffer *cb = shm_->find<IpcBuffer>(request->name().c_str()).first;
Blance Tang4c7ceb92021-03-05 17:12:40 +0800700 response->set_ret(stream->read(stream, cb->start_ptr(), std::min((size_t) request->size(), cb->capacity())));
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800701 return Status::OK;
702 }
703
704 Status StreamIn_get_input_frames_lost(ServerContext* context, const Stream* request, StatusReturn* response) {
705 TRACE_ENTRY();
706 if (!dev_) return Status::CANCELLED;
707
708 struct audio_stream_in *stream = find_streamin(request->name(), streamin_map_);
709 if (stream == nullptr) return Status::CANCELLED;
710
711 response->set_ret(stream->get_input_frames_lost(stream));
712 return Status::OK;
713 }
714
715 Status StreamIn_get_capture_position(ServerContext* context, const Stream* request, GetCapturePositionReturn* response) {
716 TRACE_ENTRY();
717 if (!dev_) return Status::CANCELLED;
718
719 struct audio_stream_in *stream = find_streamin(request->name(), streamin_map_);
720 if (stream == nullptr) return Status::CANCELLED;
721
722 int64_t frames = 0;
723 int64_t time = 0;
724 response->set_ret(stream->get_capture_position(stream, &frames, &time));
725 response->set_frames(frames);
726 response->set_time(time);
727
728 return Status::OK;
729 }
730
731 Status Service_ping(ServerContext* context, const Empty* empty, StatusReturn* response) {
732 TRACE_ENTRY();
733 response->set_status_32(0);
734 return Status::OK;
735 }
736
cheng tong7d907882020-09-04 18:53:04 +0800737 Status Effect_set_parameters(ServerContext* context, const EffectParameters* request, StatusReturn* response) {
738 TRACE_ENTRY();
739 if (!dev_ || !effect_) return Status::CANCELLED;
740
741 aml_audio_effect_type_e type = (aml_audio_effect_type_e)request->type();
742 uint32_t cmdSize = request->cmd_size();
743 void *pCmdData = (void *)request->cmd_data().data();
744 uint32_t replySize = request->reply_size();
745 uint32_t pReplyData = 0;
746
747 response->set_ret(effect_->set_parameters(type, cmdSize, pCmdData, &replySize, &pReplyData));
748 response->set_status_32(pReplyData);
749 return Status::OK;
750 }
751
752 Status Effect_get_parameters(ServerContext* context, const EffectParameters* request, StatusReturn* response) {
753 TRACE_ENTRY();
754 if (!dev_ || !effect_) return Status::CANCELLED;
755
756 aml_audio_effect_type_e type = (aml_audio_effect_type_e)request->type();
757 uint32_t cmdSize = request->cmd_size();
758 void *pCmdData = (void *)request->cmd_data().data();
759 uint32_t replySize = request->reply_size();
760 void * pReplyData = malloc(replySize);
761
762 response->set_ret(effect_->get_parameters(type, cmdSize, pCmdData, &replySize, pReplyData));
763 response->set_status_bytes(pReplyData, replySize);
764 free(pReplyData);
765 pReplyData = nullptr;
766 return Status::OK;
767 }
768
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800769 private:
770 void streamout_gc_()
771 {
772 std::lock_guard<std::mutex> lock_out(map_out_mutex_);
773 for (std::map<const std::string, streamout_map_t >::iterator it = streamout_map_.begin(); it != streamout_map_.end(); ) {
774 int pid, seq;
775 bool need_close = false;
776
777 if (sscanf(it->first.c_str(), "%d-%d", &pid, &seq) == 2) {
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800778 // Garbage collect streams when PID does not exists.
779 // It happens when client side crashed, or the client
780 // side does not have the right sequence to close opened streams.
781 if ((kill(pid, 0) == -1) && (errno == ESRCH)) {
782 need_close = true;
783 }
784 }
785 if (need_close) {
Tim Yao031950f2020-12-16 11:36:20 -0800786 ALOGI("Close disconnected output stream from PID %d", pid);
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800787 dev_->close_output_stream(dev_, it->second.second);
788 if (it->second.first) {
Tim Yaoaaa3bc52020-12-30 17:40:14 -0800789 shm_->destroy<IpcBuffer>(it->first.c_str());
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800790 }
791 streamout_map_.erase(it++);
792 } else {
793 ++it;
794 }
795 }
796 }
797
798 void streamin_gc_()
799 {
800 std::lock_guard<std::mutex> lock_out(map_in_mutex_);
801 for (std::map<const std::string, streamin_map_t >::iterator it = streamin_map_.begin(); it != streamin_map_.end(); ) {
802 int pid, seq;
803 bool need_close = false;
804
805 if (sscanf(it->first.c_str(), "%d-%d", &pid, &seq) == 2) {
806 // Garbage collect streams when PID does not exists.
807 // It happens when client side crashed, or the client
808 // side does not have the right sequence to close opened streams.
809 if (kill(pid, 0) == ESRCH) {
810 need_close = true;
811 }
812 }
813 if (need_close) {
814 dev_->close_input_stream(dev_, it->second.second);
815 streamin_map_.erase(it++);
816 } else {
817 ++it;
818 }
819 }
820 }
821
822 struct audio_stream *find_stream(std::string name,
823 std::map<const std::string, streamout_map_t> &map_out,
824 std::map<const std::string, streamin_map_t> &map_in)
825 {
826 std::lock_guard<std::mutex> lock_out(map_out_mutex_);
827 std::map<const std::string, streamout_map_t >::iterator it_out = map_out.find(name);
828 if (it_out != map_out.end()) {
829 return &it_out->second.second->common;
830 }
831
832 std::lock_guard<std::mutex> lock_in(map_in_mutex_);
833 std::map<const std::string, streamin_map_t >::iterator it_in = map_in.find(name);
834 if (it_in != map_in.end()) {
835 return &it_in->second.second->common;
836 }
837
838 return nullptr;
839 }
840
841 struct audio_stream_out *find_streamout(std::string name,
842 std::map<const std::string, streamout_map_t> &map_out)
843 {
844 std::lock_guard<std::mutex> lock(map_out_mutex_);
845 std::map<const std::string, streamout_map_t >::iterator it = map_out.find(name);
846 if (it != map_out.end()) {
847 return it->second.second;
848 }
849
850 return nullptr;
851 }
852
853 struct audio_stream_in *find_streamin(std::string name,
854 std::map<const std::string, streamin_map_t> &map_in)
855 {
856 std::lock_guard<std::mutex> lock(map_in_mutex_);
857 std::map<const std::string, streamin_map_t >::iterator it = map_in.find(name);
858 if (it != map_in.end()) {
859 return it->second.second;
860 }
861
862 return nullptr;
863 }
864
Tim Yaoaaa3bc52020-12-30 17:40:14 -0800865 managed_shared_memory *shm_;
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800866
867 /* audio hal interface */
868 struct audio_hw_device *dev_;
cheng tong7d907882020-09-04 18:53:04 +0800869 audio_effect_t *effect_;
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800870 static std::mutex map_in_mutex_;
871 static std::mutex map_out_mutex_;
872 std::map<const std::string, streamout_map_t > streamout_map_;
873 std::map<const std::string, streamin_map_t > streamin_map_;
Tim Yao031950f2020-12-16 11:36:20 -0800874
875 /* gc thread to close dead streams */
876 bool gc_runner_stop_;
877 std::mutex gc_mutex_;
878 std::condition_variable gc_cv_;
879 std::thread gc_runner_;
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800880};
881
882std::mutex AudioServiceImpl::map_out_mutex_;
883std::mutex AudioServiceImpl::map_in_mutex_;
884
wei.duc64b06a2022-01-17 16:51:12 +0800885static void SetAudioPermissions(const char* file_path){
886 struct stat buf;
887 if (stat(file_path, &buf) != 0)
888 return;
889
890 chmod(file_path, (buf.st_mode & 0711) | 0066);
891}
892
Tim Yaoaaa3bc52020-12-30 17:40:14 -0800893void RunServer()
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800894{
Tim Yao1b84e362020-08-24 12:51:36 -0700895 const char *url = std::getenv("AUDIO_SERVER_SOCKET");
wei.duc64b06a2022-01-17 16:51:12 +0800896 std::string socket_location("/tmp/audio_socket");
897 std::string server_address("unix://" + socket_location);
Tim Yaoaaa3bc52020-12-30 17:40:14 -0800898 AudioServiceImpl service;
Tim Yao1b84e362020-08-24 12:51:36 -0700899 if (url) {
900 server_address = url;
901 }
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800902 ServerBuilder builder;
903 builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
904 builder.RegisterService(&service);
905 std::unique_ptr<Server> server(builder.BuildAndStart());
wei.duc64b06a2022-01-17 16:51:12 +0800906 SetAudioPermissions(socket_location.c_str());
907 SetAudioPermissions("/dev/shm/AudioServiceShmem");
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800908 std::cout << "[AudioServer] listening on " << server_address << std::endl;
909 server->Wait();
910}
911
912static int daemonize()
913{
914 int fd_pid;
915 const char pidfile[] = "/var/run/audio_server.pid";
916 char pid[10];
917
918 fd_pid = open(pidfile, O_RDWR|O_CREAT, 0600);
919 if (fd_pid == -1) {
920 fprintf(stderr, "Unable to open PID lock file\n");
921 return -1;
922 }
923
924 if (lockf(fd_pid, F_TLOCK, 0) == -1) {
925 fprintf(stderr, "Unable to lock PID file, daemon is existing.\n");
926 return -2;
927 }
928
929 snprintf(pid, sizeof(pid), "%d", getpid());
930 write(fd_pid, pid, strlen(pid));
931
932 return 0;
933}
934
Tim Yao87d2f5a2020-12-26 17:03:58 -0800935void handler(int sig)
936{
937 void *array[10];
938 size_t size;
939
940 // get void*'s for all entries on the stack
941 size = backtrace(array, 10);
942
943 // print out all the frames to stderr
944 fprintf(stderr, "Error: signal %d:\n", sig);
945 backtrace_symbols_fd(array, size, STDERR_FILENO);
946 exit(1);
947}
948
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800949int main(int argc, char** argv)
950{
951 int r = daemonize();
952 if (r < 0)
953 return r;
954
Tim Yao87d2f5a2020-12-26 17:03:58 -0800955 signal(SIGSEGV, handler);
956 signal(SIGABRT, handler);
957 signal(SIGFPE, handler);
958
Tim Yaoaaa3bc52020-12-30 17:40:14 -0800959 RunServer();
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800960 return 0;
961}