LCOV - code coverage report
Current view: top level - src - preferences.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 223 250 89.2 %
Date: 2024-04-23 08:02:50 Functions: 21 22 95.5 %

          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

Generated by: LCOV version 1.14