FoxiGram/TMessagesProj/jni/voip/tgcalls/AudioDeviceHelper.cpp
instant992 8e79f2ee9c FoxiGram: Telegram client with built-in Xray VLESS proxy
Based on Nekogram. Key additions:
- Rebrand to FoxiGram (app name, APK name, applicationId com.foxigram.app)
- Embedded Xray (VLESS+Reality) proxy client via JNI libxray.so
- Bundled hidden one-tap proxies (LTE + WiFi), read-only in UI
- Auto-restore proxy on restart, rebind to active network (LTE/WiFi)
- Server credentials externalized to git-ignored XrayServers.java (+ template)
- libxray Go source included; compiled .so, keystore, google-services.json ignored
2026-06-08 16:41:07 +04:00

142 lines
4.8 KiB
C++

#include "AudioDeviceHelper.h"
#include "modules/audio_device/include/audio_device.h"
#include "rtc_base/logging.h"
namespace tgcalls {
namespace {
bool SkipDefaultDevice(const char *name) {
const auto utfName = std::string(name);
#ifdef WEBRTC_WIN
return (utfName.rfind("Default - ", 0) == 0)
|| (utfName.rfind("Communication - ", 0) == 0);
#elif defined WEBRTC_MAC
return (utfName.rfind("default (", 0) == 0)
&& (utfName.find(")", utfName.size() - 1) == utfName.size() - 1);
#else
return false;
#endif // WEBRTC_WIN || WEBRTC_MAC
}
} // namespace
void SetAudioInputDeviceById(webrtc::AudioDeviceModule *adm, const std::string &id) {
const auto recording = adm->Recording() || adm->RecordingIsInitialized();
if (recording) {
adm->StopRecording();
}
auto specific = false;
const auto finish = [&] {
if (!specific) {
if (const auto result = adm->SetRecordingDevice(webrtc::AudioDeviceModule::kDefaultCommunicationDevice)) {
RTC_LOG(LS_ERROR) << "setAudioInputDevice(" << id << "): SetRecordingDevice(kDefaultCommunicationDevice) failed: " << result << ".";
} else {
RTC_LOG(LS_INFO) << "setAudioInputDevice(" << id << "): SetRecordingDevice(kDefaultCommunicationDevice) success.";
}
}
if (recording && adm->InitRecording() == 0) {
adm->StartRecording();
}
};
if (id == "default" || id.empty()) {
return finish();
}
#ifdef TGCALLS_UWP_DESKTOP
const auto result = adm->SetRecordingDevice(id);
if (result != 0) {
RTC_LOG(LS_ERROR) << "setAudioInputDevice(" << id << ") failed: " << result << ".";
} else {
RTC_LOG(LS_INFO) << "setAudioInputDevice(" << id << ") success.";
specific = true;
}
return finish();
#else // TGCALLS_UWP_DESKTOP
const auto count = adm
? adm->RecordingDevices()
: int16_t(-666);
if (count <= 0) {
RTC_LOG(LS_ERROR) << "setAudioInputDevice(" << id << "): Could not get recording devices count: " << count << ".";
return finish();
}
int16_t order = !id.empty() && id[0] == '#' ? static_cast<int16_t>(std::stoi(id.substr(1))) : -1;
for (auto i = 0; i != count; ++i) {
char name[webrtc::kAdmMaxDeviceNameSize + 1] = { 0 };
char guid[webrtc::kAdmMaxGuidSize + 1] = { 0 };
adm->RecordingDeviceName(i, name, guid);
if ((!SkipDefaultDevice(name) && id == guid) || order == i) {
const auto result = adm->SetRecordingDevice(i);
if (result != 0) {
RTC_LOG(LS_ERROR) << "setAudioInputDevice(" << id << ") name '" << std::string(name) << "' failed: " << result << ".";
} else {
RTC_LOG(LS_INFO) << "setAudioInputDevice(" << id << ") name '" << std::string(name) << "' success.";
specific = true;
}
return finish();
}
}
RTC_LOG(LS_ERROR) << "setAudioInputDevice(" << id << "): Could not find recording device.";
return finish();
#endif // TGCALLS_UWP_DESKTOP
}
void SetAudioOutputDeviceById(webrtc::AudioDeviceModule *adm, const std::string &id) {
if (adm->Playing()) {
adm->StopPlayout();
}
auto specific = false;
const auto finish = [&] {
if (!specific) {
if (const auto result = adm->SetPlayoutDevice(webrtc::AudioDeviceModule::kDefaultCommunicationDevice)) {
RTC_LOG(LS_ERROR) << "setAudioOutputDevice(" << id << "): SetPlayoutDevice(kDefaultCommunicationDevice) failed: " << result << ".";
} else {
RTC_LOG(LS_INFO) << "setAudioOutputDevice(" << id << "): SetPlayoutDevice(kDefaultCommunicationDevice) success.";
}
}
if (adm->InitPlayout() == 0) {
adm->StartPlayout();
}
};
if (id == "default" || id.empty()) {
return finish();
}
#ifdef TGCALLS_UWP_DESKTOP
const auto result = adm->SetPlayoutDevice(id);
if (result != 0) {
RTC_LOG(LS_ERROR) << "setAudioOutputDevice(" << id << ") failed: " << result << ".";
} else {
RTC_LOG(LS_INFO) << "setAudioOutputDevice(" << id << ") success.";
specific = true;
}
return finish();
#else // TGCALLS_UWP_DESKTOP
const auto count = adm
? adm->PlayoutDevices()
: int16_t(-666);
if (count <= 0) {
RTC_LOG(LS_ERROR) << "setAudioOutputDevice(" << id << "): Could not get playout devices count: " << count << ".";
return finish();
}
int16_t order = !id.empty() && id[0] == '#' ? static_cast<int16_t>(std::stoi(id.substr(1))) : -1;
for (auto i = 0; i != count; ++i) {
char name[webrtc::kAdmMaxDeviceNameSize + 1] = { 0 };
char guid[webrtc::kAdmMaxGuidSize + 1] = { 0 };
adm->PlayoutDeviceName(i, name, guid);
if ((!SkipDefaultDevice(name) && id == guid) || order == i) {
const auto result = adm->SetPlayoutDevice(i);
if (result != 0) {
RTC_LOG(LS_ERROR) << "setAudioOutputDevice(" << id << ") name '" << std::string(name) << "' failed: " << result << ".";
} else {
RTC_LOG(LS_INFO) << "setAudioOutputDevice(" << id << ") name '" << std::string(name) << "' success.";
specific = true;
}
return finish();
}
}
RTC_LOG(LS_ERROR) << "setAudioOutputDevice(" << id << "): Could not find playout device.";
return finish();
#endif // TGCALLS_UWP_DESKTOP
}
} // namespace tgcalls