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-12-21 08:56:24 Functions: 21 22 95.5 %

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

Generated by: LCOV version 1.14