Line data Source code
1 : /*
2 : * Copyright (C) 2004-2024 Savoir-faire Linux Inc.
3 : *
4 : * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
5 : * Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com>
6 : * Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
7 : *
8 : * This program is free software; you can redistribute it and/or modify
9 : * it under the terms of the GNU General Public License as published by
10 : * the Free Software Foundation; either version 3 of the License, or
11 : * (at your option) any later version.
12 : *
13 : * This program is distributed in the hope that it will be useful,
14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : * GNU General Public License for more details.
17 : *
18 : * You should have received a copy of the GNU General Public License
19 : * along with this program; if not, write to the Free Software
20 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 : */
22 :
23 : #ifdef HAVE_CONFIG_H
24 : #include "config.h"
25 : #endif
26 :
27 : #include "preferences.h"
28 : #include "logger.h"
29 : #include "audio/audiolayer.h"
30 : #if HAVE_OPENSL
31 : #include "audio/opensl/opensllayer.h"
32 : #else
33 : #if HAVE_ALSA
34 : #include "audio/alsa/alsalayer.h"
35 : #endif
36 : #if HAVE_JACK
37 : #include "audio/jack/jacklayer.h"
38 : #endif
39 : #if HAVE_PULSE
40 : #include "audio/pulseaudio/pulselayer.h"
41 : #endif
42 : #if HAVE_COREAUDIO
43 : #ifdef __APPLE__
44 : #include <TargetConditionals.h>
45 : #endif
46 : #if TARGET_OS_IOS
47 : #include "audio/coreaudio/ios/corelayer.h"
48 : #else
49 : #include "audio/coreaudio/osx/corelayer.h"
50 : #endif /* TARGET_OS_IOS */
51 : #endif /* HAVE_COREAUDIO */
52 : #if HAVE_PORTAUDIO
53 : #include "audio/portaudio/portaudiolayer.h"
54 : #endif
55 : #endif /* HAVE_OPENSL */
56 :
57 : #ifdef ENABLE_VIDEO
58 : #include "client/videomanager.h"
59 : #endif
60 :
61 : #pragma GCC diagnostic push
62 : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
63 : #include <yaml-cpp/yaml.h>
64 : #pragma GCC diagnostic pop
65 :
66 : #include "config/yamlparser.h"
67 : #include "connectivity/sip_utils.h"
68 : #include <sstream>
69 : #include <algorithm>
70 : #include <stdexcept>
71 : #include "fileutils.h"
72 : #include "string_utils.h"
73 :
74 : namespace jami {
75 :
76 : using yaml_utils::parseValue;
77 :
78 : constexpr const char* const Preferences::CONFIG_LABEL;
79 : const char* const Preferences::DFT_ZONE = "North America";
80 : const char* const Preferences::REGISTRATION_EXPIRE_KEY = "registrationexpire";
81 : constexpr std::string_view DEFAULT_CONFERENCE_RESOLUTION {"1280x720"};
82 :
83 : // general preferences
84 : static constexpr const char* ORDER_KEY {"order"};
85 : static constexpr const char* AUDIO_API_KEY {"audioApi"};
86 : static constexpr const char* HISTORY_LIMIT_KEY {"historyLimit"};
87 : static constexpr const char* RINGING_TIMEOUT {"ringingTimeout"};
88 : static constexpr const char* HISTORY_MAX_CALLS_KEY {"historyMaxCalls"};
89 : static constexpr const char* ZONE_TONE_CHOICE_KEY {"zoneToneChoice"};
90 : static constexpr const char* PORT_NUM_KEY {"portNum"};
91 : static constexpr const char* SEARCH_BAR_DISPLAY_KEY {"searchBarDisplay"};
92 : static constexpr const char* MD5_HASH_KEY {"md5Hash"};
93 :
94 : // voip preferences
95 : constexpr const char* const VoipPreference::CONFIG_LABEL;
96 : static constexpr const char* PLAY_DTMF_KEY {"playDtmf"};
97 : static constexpr const char* PLAY_TONES_KEY {"playTones"};
98 : static constexpr const char* PULSE_LENGTH_KEY {"pulseLength"};
99 :
100 : // audio preferences
101 : constexpr const char* const AudioPreference::CONFIG_LABEL;
102 : static constexpr const char* ALSAMAP_KEY {"alsa"};
103 : static constexpr const char* PULSEMAP_KEY {"pulse"};
104 : static constexpr const char* PORTAUDIO_KEY {"portaudio"};
105 : static constexpr const char* CARDIN_KEY {"cardIn"};
106 : static constexpr const char* CARDOUT_KEY {"cardOut"};
107 : static constexpr const char* CARLIBJAMI_KEY {"cardRing"};
108 : static constexpr const char* PLUGIN_KEY {"plugin"};
109 : static constexpr const char* SMPLRATE_KEY {"smplRate"};
110 : static constexpr const char* DEVICE_PLAYBACK_KEY {"devicePlayback"};
111 : static constexpr const char* DEVICE_RECORD_KEY {"deviceRecord"};
112 : static constexpr const char* DEVICE_RINGTONE_KEY {"deviceRingtone"};
113 : static constexpr const char* RECORDPATH_KEY {"recordPath"};
114 : static constexpr const char* ALWAYS_RECORDING_KEY {"alwaysRecording"};
115 : static constexpr const char* VOLUMEMIC_KEY {"volumeMic"};
116 : static constexpr const char* VOLUMESPKR_KEY {"volumeSpkr"};
117 : static constexpr const char* AUDIO_PROCESSOR_KEY {"audioProcessor"};
118 : static constexpr const char* NOISE_REDUCE_KEY {"noiseReduce"};
119 : static constexpr const char* AGC_KEY {"automaticGainControl"};
120 : static constexpr const char* CAPTURE_MUTED_KEY {"captureMuted"};
121 : static constexpr const char* PLAYBACK_MUTED_KEY {"playbackMuted"};
122 : static constexpr const char* VAD_KEY {"voiceActivityDetection"};
123 : static constexpr const char* ECHO_CANCEL_KEY {"echoCancel"};
124 :
125 : #ifdef ENABLE_VIDEO
126 : // video preferences
127 : constexpr const char* const VideoPreferences::CONFIG_LABEL;
128 : static constexpr const char* DECODING_ACCELERATED_KEY {"decodingAccelerated"};
129 : static constexpr const char* ENCODING_ACCELERATED_KEY {"encodingAccelerated"};
130 : static constexpr const char* RECORD_PREVIEW_KEY {"recordPreview"};
131 : static constexpr const char* RECORD_QUALITY_KEY {"recordQuality"};
132 : static constexpr const char* CONFERENCE_RESOLUTION_KEY {"conferenceResolution"};
133 : #endif
134 :
135 : #ifdef ENABLE_PLUGIN
136 : // plugin preferences
137 : constexpr const char* const PluginPreferences::CONFIG_LABEL;
138 : static constexpr const char* JAMI_PLUGIN_KEY {"pluginsEnabled"};
139 : static constexpr const char* JAMI_PLUGINS_INSTALLED_KEY {"installedPlugins"};
140 : static constexpr const char* JAMI_PLUGINS_LOADED_KEY {"loadedPlugins"};
141 : #endif
142 :
143 : static constexpr int PULSE_LENGTH_DEFAULT {250}; /** Default DTMF length */
144 : #ifndef _MSC_VER
145 : static constexpr const char* ALSA_DFT_CARD {"0"}; /** Default sound card index */
146 : #else
147 : static constexpr const char* ALSA_DFT_CARD {"-1"}; /** Default sound card index (Portaudio) */
148 : #endif // _MSC_VER
149 :
150 38 : Preferences::Preferences()
151 38 : : accountOrder_("")
152 38 : , historyLimit_(0)
153 38 : , historyMaxCalls_(20)
154 38 : , ringingTimeout_(30)
155 38 : , zoneToneChoice_(DFT_ZONE) // DFT_ZONE
156 38 : , portNum_(sip_utils::DEFAULT_SIP_PORT)
157 38 : , searchBarDisplay_(true)
158 38 : , md5Hash_(false)
159 38 : {}
160 :
161 : void
162 1720 : Preferences::verifyAccountOrder(const std::vector<std::string>& accountIDs)
163 : {
164 1720 : std::vector<std::string> tokens;
165 1720 : std::string token;
166 1720 : bool drop = false;
167 :
168 55829 : for (const auto c : accountOrder_) {
169 54109 : if (c != '/') {
170 50925 : token += c;
171 : } else {
172 3184 : if (find(accountIDs.begin(), accountIDs.end(), token) != accountIDs.end())
173 3184 : tokens.push_back(token);
174 : else {
175 0 : JAMI_DBG("Dropping nonexistent account %s", token.c_str());
176 0 : drop = true;
177 : }
178 3184 : token.clear();
179 : }
180 : }
181 :
182 1720 : if (drop) {
183 0 : accountOrder_.clear();
184 0 : for (const auto& t : tokens)
185 0 : accountOrder_ += t + '/';
186 : }
187 1720 : }
188 :
189 : void
190 794 : Preferences::addAccount(const std::string& newAccountID)
191 : {
192 : // Add the newly created account in the account order list
193 794 : if (not accountOrder_.empty())
194 529 : accountOrder_.insert(0, newAccountID + "/");
195 : else
196 265 : accountOrder_ = newAccountID + "/";
197 794 : }
198 :
199 : void
200 794 : Preferences::removeAccount(const std::string& oldAccountID)
201 : {
202 : // include the slash since we don't want to remove a partial match
203 794 : const size_t start = accountOrder_.find(oldAccountID + "/");
204 794 : if (start != std::string::npos)
205 794 : accountOrder_.erase(start, oldAccountID.length() + 1);
206 794 : }
207 :
208 : void
209 1720 : Preferences::serialize(YAML::Emitter& out) const
210 : {
211 1720 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
212 :
213 1720 : out << YAML::Key << HISTORY_LIMIT_KEY << YAML::Value << historyLimit_;
214 1720 : out << YAML::Key << RINGING_TIMEOUT << YAML::Value << ringingTimeout_;
215 1720 : out << YAML::Key << HISTORY_MAX_CALLS_KEY << YAML::Value << historyMaxCalls_;
216 1720 : out << YAML::Key << MD5_HASH_KEY << YAML::Value << md5Hash_;
217 1720 : out << YAML::Key << ORDER_KEY << YAML::Value << accountOrder_;
218 1720 : out << YAML::Key << PORT_NUM_KEY << YAML::Value << portNum_;
219 1720 : out << YAML::Key << SEARCH_BAR_DISPLAY_KEY << YAML::Value << searchBarDisplay_;
220 1720 : out << YAML::Key << ZONE_TONE_CHOICE_KEY << YAML::Value << zoneToneChoice_;
221 1720 : out << YAML::EndMap;
222 1720 : }
223 :
224 : void
225 36 : Preferences::unserialize(const YAML::Node& in)
226 : {
227 36 : const auto& node = in[CONFIG_LABEL];
228 :
229 36 : parseValue(node, ORDER_KEY, accountOrder_);
230 30 : parseValue(node, HISTORY_LIMIT_KEY, historyLimit_);
231 30 : parseValue(node, RINGING_TIMEOUT, ringingTimeout_);
232 30 : parseValue(node, HISTORY_MAX_CALLS_KEY, historyMaxCalls_);
233 30 : parseValue(node, ZONE_TONE_CHOICE_KEY, zoneToneChoice_);
234 30 : parseValue(node, PORT_NUM_KEY, portNum_);
235 30 : parseValue(node, SEARCH_BAR_DISPLAY_KEY, searchBarDisplay_);
236 30 : parseValue(node, MD5_HASH_KEY, md5Hash_);
237 36 : }
238 :
239 38 : VoipPreference::VoipPreference()
240 38 : : playDtmf_(true)
241 38 : , playTones_(true)
242 38 : , pulseLength_(PULSE_LENGTH_DEFAULT)
243 38 : {}
244 :
245 : void
246 1720 : VoipPreference::serialize(YAML::Emitter& out) const
247 : {
248 1720 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
249 1720 : out << YAML::Key << PLAY_DTMF_KEY << YAML::Value << playDtmf_;
250 1720 : out << YAML::Key << PLAY_TONES_KEY << YAML::Value << playTones_;
251 1720 : out << YAML::Key << PULSE_LENGTH_KEY << YAML::Value << pulseLength_;
252 1720 : out << YAML::EndMap;
253 1720 : }
254 :
255 : void
256 30 : VoipPreference::unserialize(const YAML::Node& in)
257 : {
258 30 : const auto& node = in[CONFIG_LABEL];
259 30 : parseValue(node, PLAY_DTMF_KEY, playDtmf_);
260 30 : parseValue(node, PLAY_TONES_KEY, playTones_);
261 30 : parseValue(node, PULSE_LENGTH_KEY, pulseLength_);
262 30 : }
263 :
264 38 : AudioPreference::AudioPreference()
265 38 : : audioApi_(PULSEAUDIO_API_STR)
266 38 : , alsaCardin_(atoi(ALSA_DFT_CARD))
267 38 : , alsaCardout_(atoi(ALSA_DFT_CARD))
268 38 : , alsaCardRingtone_(atoi(ALSA_DFT_CARD))
269 38 : , alsaPlugin_("default")
270 38 : , alsaSmplrate_(44100)
271 38 : , pulseDevicePlayback_("")
272 38 : , pulseDeviceRecord_("")
273 38 : , pulseDeviceRingtone_("")
274 38 : , recordpath_("")
275 38 : , alwaysRecording_(false)
276 38 : , volumemic_(1.0)
277 38 : , volumespkr_(1.0)
278 38 : , audioProcessor_("webrtc")
279 38 : , denoise_("auto")
280 38 : , agcEnabled_(true)
281 38 : , vadEnabled_(true)
282 38 : , echoCanceller_("auto")
283 38 : , captureMuted_(false)
284 76 : , playbackMuted_(false)
285 38 : {}
286 :
287 : #if HAVE_ALSA
288 :
289 : static const int ALSA_DFT_CARD_ID = 0; // Index of the default soundcard
290 :
291 : static void
292 99 : checkSoundCard(int& card, AudioDeviceType type)
293 : {
294 99 : if (not AlsaLayer::soundCardIndexExists(card, type)) {
295 99 : JAMI_WARN(" Card with index %d doesn't exist or is unusable.", card);
296 99 : card = ALSA_DFT_CARD_ID;
297 : }
298 99 : }
299 : #endif
300 :
301 : AudioLayer*
302 33 : AudioPreference::createAudioLayer()
303 : {
304 : #if HAVE_OPENSL
305 : return new OpenSLLayer(*this);
306 : #else
307 :
308 : #if HAVE_JACK
309 : if (audioApi_ == JACK_API_STR) {
310 : try {
311 : if (auto ret = system("jack_lsp > /dev/null"))
312 : throw std::runtime_error("Error running jack_lsp: " + std::to_string(ret));
313 : return new JackLayer(*this);
314 : } catch (const std::runtime_error& e) {
315 : JAMI_ERR("%s", e.what());
316 : #if HAVE_PULSE
317 : audioApi_ = PULSEAUDIO_API_STR;
318 : #elif HAVE_ALSA
319 : audioApi_ = ALSA_API_STR;
320 : #elif HAVE_COREAUDIO
321 : audioApi_ = COREAUDIO_API_STR;
322 : #elif HAVE_PORTAUDIO
323 : audioApi_ = PORTAUDIO_API_STR;
324 : #else
325 : throw;
326 : #endif // HAVE_PULSE
327 : }
328 : }
329 : #endif // HAVE_JACK
330 :
331 : #if HAVE_PULSE
332 :
333 33 : if (audioApi_ == PULSEAUDIO_API_STR) {
334 : try {
335 3 : return new PulseLayer(*this);
336 3 : } catch (const std::runtime_error& e) {
337 3 : JAMI_WARN("Could not create pulseaudio layer, falling back to ALSA");
338 3 : }
339 : }
340 :
341 : #endif
342 :
343 : #if HAVE_ALSA
344 :
345 33 : audioApi_ = ALSA_API_STR;
346 33 : checkSoundCard(alsaCardin_, AudioDeviceType::CAPTURE);
347 33 : checkSoundCard(alsaCardout_, AudioDeviceType::PLAYBACK);
348 33 : checkSoundCard(alsaCardRingtone_, AudioDeviceType::RINGTONE);
349 :
350 33 : return new AlsaLayer(*this);
351 : #endif
352 :
353 : #if HAVE_COREAUDIO
354 : audioApi_ = COREAUDIO_API_STR;
355 : try {
356 : return new CoreLayer(*this);
357 : } catch (const std::runtime_error& e) {
358 : JAMI_WARN("Could not create coreaudio layer. There will be no sound.");
359 : }
360 : return NULL;
361 : #endif
362 :
363 : #if HAVE_PORTAUDIO
364 : audioApi_ = PORTAUDIO_API_STR;
365 : try {
366 : return new PortAudioLayer(*this);
367 : } catch (const std::runtime_error& e) {
368 : JAMI_WARN("Could not create PortAudio layer. There will be no sound.");
369 : }
370 : return nullptr;
371 : #endif
372 : #endif // HAVE_OPENSL
373 :
374 : JAMI_WARN("No audio layer provided");
375 : return nullptr;
376 : }
377 :
378 : std::vector<std::string>
379 0 : AudioPreference::getSupportedAudioManagers()
380 : {
381 : return
382 : {
383 : #if HAVE_OPENSL
384 : OPENSL_API_STR,
385 : #endif
386 : #if HAVE_ALSA
387 : ALSA_API_STR,
388 : #endif
389 : #if HAVE_PULSE
390 : PULSEAUDIO_API_STR,
391 : #endif
392 : #if HAVE_JACK
393 : JACK_API_STR,
394 : #endif
395 : #if HAVE_COREAUDIO
396 : COREAUDIO_API_STR,
397 : #endif
398 : #if HAVE_PORTAUDIO
399 : PORTAUDIO_API_STR,
400 : #endif
401 0 : };
402 : }
403 :
404 : void
405 1720 : AudioPreference::serialize(YAML::Emitter& out) const
406 : {
407 1720 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
408 : // alsa submap
409 1720 : out << YAML::Key << ALSAMAP_KEY << YAML::Value << YAML::BeginMap;
410 1720 : out << YAML::Key << CARDIN_KEY << YAML::Value << alsaCardin_;
411 1720 : out << YAML::Key << CARDOUT_KEY << YAML::Value << alsaCardout_;
412 1720 : out << YAML::Key << CARLIBJAMI_KEY << YAML::Value << alsaCardRingtone_;
413 1720 : out << YAML::Key << PLUGIN_KEY << YAML::Value << alsaPlugin_;
414 1720 : out << YAML::Key << SMPLRATE_KEY << YAML::Value << alsaSmplrate_;
415 1720 : out << YAML::EndMap;
416 :
417 : // common options
418 1720 : out << YAML::Key << ALWAYS_RECORDING_KEY << YAML::Value << alwaysRecording_;
419 1720 : out << YAML::Key << AUDIO_API_KEY << YAML::Value << audioApi_;
420 1720 : out << YAML::Key << CAPTURE_MUTED_KEY << YAML::Value << captureMuted_;
421 1720 : out << YAML::Key << PLAYBACK_MUTED_KEY << YAML::Value << playbackMuted_;
422 :
423 : // pulse submap
424 1720 : out << YAML::Key << PULSEMAP_KEY << YAML::Value << YAML::BeginMap;
425 1720 : out << YAML::Key << DEVICE_PLAYBACK_KEY << YAML::Value << pulseDevicePlayback_;
426 1720 : out << YAML::Key << DEVICE_RECORD_KEY << YAML::Value << pulseDeviceRecord_;
427 1720 : out << YAML::Key << DEVICE_RINGTONE_KEY << YAML::Value << pulseDeviceRingtone_;
428 1720 : out << YAML::EndMap;
429 :
430 : // portaudio submap
431 1720 : out << YAML::Key << PORTAUDIO_KEY << YAML::Value << YAML::BeginMap;
432 1720 : out << YAML::Key << DEVICE_PLAYBACK_KEY << YAML::Value << portaudioDevicePlayback_;
433 1720 : out << YAML::Key << DEVICE_RECORD_KEY << YAML::Value << portaudioDeviceRecord_;
434 1720 : out << YAML::Key << DEVICE_RINGTONE_KEY << YAML::Value << portaudioDeviceRingtone_;
435 1720 : out << YAML::EndMap;
436 :
437 : // more common options!
438 1720 : out << YAML::Key << RECORDPATH_KEY << YAML::Value << recordpath_;
439 1720 : out << YAML::Key << VOLUMEMIC_KEY << YAML::Value << volumemic_;
440 1720 : out << YAML::Key << VOLUMESPKR_KEY << YAML::Value << volumespkr_;
441 :
442 : // audio processor options, not in a submap
443 1720 : out << YAML::Key << AUDIO_PROCESSOR_KEY << YAML::Value << audioProcessor_;
444 1720 : out << YAML::Key << AGC_KEY << YAML::Value << agcEnabled_;
445 1720 : out << YAML::Key << VAD_KEY << YAML::Value << vadEnabled_;
446 1720 : out << YAML::Key << NOISE_REDUCE_KEY << YAML::Value << denoise_;
447 1720 : out << YAML::Key << ECHO_CANCEL_KEY << YAML::Value << echoCanceller_;
448 1720 : out << YAML::EndMap;
449 1720 : }
450 :
451 : bool
452 5 : AudioPreference::setRecordPath(const std::string& r)
453 : {
454 5 : std::string path = fileutils::expand_path(r);
455 5 : if (fileutils::isDirectoryWritable(path)) {
456 5 : recordpath_ = path;
457 5 : return true;
458 : } else {
459 0 : JAMI_ERR("%s is not writable, cannot be the recording path", path.c_str());
460 0 : return false;
461 : }
462 5 : }
463 :
464 : void
465 30 : AudioPreference::unserialize(const YAML::Node& in)
466 : {
467 30 : const auto& node = in[CONFIG_LABEL];
468 :
469 : // alsa submap
470 30 : const auto& alsa = node[ALSAMAP_KEY];
471 :
472 30 : parseValue(alsa, CARDIN_KEY, alsaCardin_);
473 30 : parseValue(alsa, CARDOUT_KEY, alsaCardout_);
474 30 : parseValue(alsa, CARLIBJAMI_KEY, alsaCardRingtone_);
475 30 : parseValue(alsa, PLUGIN_KEY, alsaPlugin_);
476 30 : parseValue(alsa, SMPLRATE_KEY, alsaSmplrate_);
477 :
478 : // common options
479 30 : parseValue(node, ALWAYS_RECORDING_KEY, alwaysRecording_);
480 30 : parseValue(node, AUDIO_API_KEY, audioApi_);
481 30 : parseValue(node, AGC_KEY, agcEnabled_);
482 30 : parseValue(node, CAPTURE_MUTED_KEY, captureMuted_);
483 30 : parseValue(node, NOISE_REDUCE_KEY, denoise_);
484 30 : parseValue(node, PLAYBACK_MUTED_KEY, playbackMuted_);
485 :
486 : // pulse submap
487 30 : const auto& pulse = node[PULSEMAP_KEY];
488 30 : parseValue(pulse, DEVICE_PLAYBACK_KEY, pulseDevicePlayback_);
489 30 : parseValue(pulse, DEVICE_RECORD_KEY, pulseDeviceRecord_);
490 30 : parseValue(pulse, DEVICE_RINGTONE_KEY, pulseDeviceRingtone_);
491 :
492 : // portaudio submap
493 30 : const auto& portaudio = node[PORTAUDIO_KEY];
494 30 : parseValue(portaudio, DEVICE_PLAYBACK_KEY, portaudioDevicePlayback_);
495 30 : parseValue(portaudio, DEVICE_RECORD_KEY, portaudioDeviceRecord_);
496 30 : parseValue(portaudio, DEVICE_RINGTONE_KEY, portaudioDeviceRingtone_);
497 :
498 : // more common options!
499 30 : parseValue(node, RECORDPATH_KEY, recordpath_);
500 30 : parseValue(node, VOLUMEMIC_KEY, volumemic_);
501 30 : parseValue(node, VOLUMESPKR_KEY, volumespkr_);
502 30 : parseValue(node, AUDIO_PROCESSOR_KEY, audioProcessor_);
503 30 : parseValue(node, VAD_KEY, vadEnabled_);
504 30 : parseValue(node, ECHO_CANCEL_KEY, echoCanceller_);
505 30 : }
506 :
507 : #ifdef ENABLE_VIDEO
508 38 : VideoPreferences::VideoPreferences()
509 38 : : decodingAccelerated_(true)
510 38 : , encodingAccelerated_(false)
511 38 : , recordPreview_(true)
512 38 : , recordQuality_(0)
513 38 : , conferenceResolution_(DEFAULT_CONFERENCE_RESOLUTION)
514 38 : {}
515 :
516 : void
517 1720 : VideoPreferences::serialize(YAML::Emitter& out) const
518 : {
519 1720 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
520 1720 : out << YAML::Key << RECORD_PREVIEW_KEY << YAML::Value << recordPreview_;
521 1720 : out << YAML::Key << RECORD_QUALITY_KEY << YAML::Value << recordQuality_;
522 : #ifdef RING_ACCEL
523 1720 : out << YAML::Key << DECODING_ACCELERATED_KEY << YAML::Value << decodingAccelerated_;
524 1720 : out << YAML::Key << ENCODING_ACCELERATED_KEY << YAML::Value << encodingAccelerated_;
525 : #endif
526 1720 : out << YAML::Key << CONFERENCE_RESOLUTION_KEY << YAML::Value << conferenceResolution_;
527 1720 : getVideoDeviceMonitor().serialize(out);
528 1720 : out << YAML::EndMap;
529 1720 : }
530 :
531 : void
532 30 : VideoPreferences::unserialize(const YAML::Node& in)
533 : {
534 : // values may or may not be present
535 30 : const auto& node = in[CONFIG_LABEL];
536 : try {
537 30 : parseValue(node, RECORD_PREVIEW_KEY, recordPreview_);
538 30 : parseValue(node, RECORD_QUALITY_KEY, recordQuality_);
539 0 : } catch (...) {
540 0 : recordPreview_ = true;
541 0 : recordQuality_ = 0;
542 0 : }
543 : #ifdef RING_ACCEL
544 : try {
545 30 : parseValue(node, DECODING_ACCELERATED_KEY, decodingAccelerated_);
546 30 : parseValue(node, ENCODING_ACCELERATED_KEY, encodingAccelerated_);
547 0 : } catch (...) {
548 0 : decodingAccelerated_ = true;
549 0 : encodingAccelerated_ = false;
550 0 : }
551 : #endif
552 : try {
553 30 : parseValue(node, CONFERENCE_RESOLUTION_KEY, conferenceResolution_);
554 0 : } catch (...) {
555 0 : conferenceResolution_ = DEFAULT_CONFERENCE_RESOLUTION;
556 0 : }
557 30 : getVideoDeviceMonitor().unserialize(in);
558 30 : }
559 : #endif // ENABLE_VIDEO
560 :
561 : #ifdef ENABLE_PLUGIN
562 38 : PluginPreferences::PluginPreferences()
563 38 : : pluginsEnabled_(false)
564 38 : {}
565 :
566 : void
567 1720 : PluginPreferences::serialize(YAML::Emitter& out) const
568 : {
569 1720 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
570 1720 : out << YAML::Key << JAMI_PLUGIN_KEY << YAML::Value << pluginsEnabled_;
571 1720 : out << YAML::Key << JAMI_PLUGINS_INSTALLED_KEY << YAML::Value << installedPlugins_;
572 1720 : out << YAML::Key << JAMI_PLUGINS_LOADED_KEY << YAML::Value << loadedPlugins_;
573 1720 : out << YAML::EndMap;
574 1720 : }
575 :
576 : void
577 30 : PluginPreferences::unserialize(const YAML::Node& in)
578 : {
579 : // values may or may not be present
580 30 : const auto& node = in[CONFIG_LABEL];
581 : try {
582 30 : parseValue(node, JAMI_PLUGIN_KEY, pluginsEnabled_);
583 0 : } catch (...) {
584 0 : pluginsEnabled_ = false;
585 0 : }
586 :
587 30 : const auto& installedPluginsNode = node[JAMI_PLUGINS_INSTALLED_KEY];
588 : try {
589 30 : installedPlugins_ = yaml_utils::parseVector(installedPluginsNode);
590 0 : } catch (...) {
591 0 : }
592 :
593 30 : const auto& loadedPluginsNode = node[JAMI_PLUGINS_LOADED_KEY];
594 : try {
595 30 : loadedPlugins_ = yaml_utils::parseVector(loadedPluginsNode);
596 0 : } catch (...) {
597 : // loadedPlugins_ = {};
598 0 : }
599 30 : }
600 : #endif // ENABLE_PLUGIN
601 :
602 : } // namespace jami
|