Skip to content

Commit

Permalink
Added support for platform-specific microphone permission in calls
Browse files Browse the repository at this point in the history
  • Loading branch information
grishka committed Sep 30, 2018
1 parent 8c440cc commit 0e7f933
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Telegram/Resources/langs/lang.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1403,6 +1403,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_call_rate_label" = "Please rate the quality of your call";
"lng_call_rate_comment" = "Comment (optional)";

"lng_no_mic_permission" = "Telegram needs access to your microphone so that you can make calls and record voice messages.";

"lng_player_message_today" = "Today at {time}";
"lng_player_message_yesterday" = "Yesterday at {time}";
"lng_player_message_date" = "{date} at {time}";
Expand Down
4 changes: 4 additions & 0 deletions Telegram/SourceFiles/calls/calls_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,10 @@ void Call::startIncoming() {
}

void Call::answer() {
_delegate->requestMicrophonePermissionOrFail([this](){ actuallyAnswer(); });
}

void Call::actuallyAnswer() {
Expects(_type == Type::Incoming);

if (_state != State::Starting && _state != State::WaitingIncoming) {
Expand Down
2 changes: 2 additions & 0 deletions Telegram/SourceFiles/calls/calls_call.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class Call : public base::has_weak_ptr, private MTP::Sender {
Ended,
};
virtual void playSound(Sound sound) = 0;
virtual void requestMicrophonePermissionOrFail(Fn<void()> result) = 0;

virtual ~Delegate();

Expand Down Expand Up @@ -167,6 +168,7 @@ class Call : public base::has_weak_ptr, private MTP::Sender {
bool checkCallFields(const MTPDphoneCall &call);
bool checkCallFields(const MTPDphoneCallAccepted &call);

void actuallyAnswer();
void confirmAcceptedCall(const MTPDphoneCallAccepted &call);
void startConfirmedCall(const MTPDphoneCall &call);
void setState(State state);
Expand Down
31 changes: 30 additions & 1 deletion Telegram/SourceFiles/calls/calls_instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ For license and copyright information please follow this link:
#include "calls/calls_call.h"
#include "calls/calls_panel.h"
#include "media/media_audio_track.h"
#include "platform/platform_specific.h"
#include "mainwidget.h"

#include "boxes/rate_call_box.h"
namespace Calls {
Expand All @@ -38,7 +40,9 @@ void Instance::startOutgoingCall(not_null<UserData*> user) {
Ui::show(Box<InformBox>(lng_call_error_not_available(lt_user, App::peerName(user))));
return;
}
createCall(user, Call::Type::Outgoing);
requestMicrophonePermissionOrFail([this, user](){
createCall(user, Call::Type::Outgoing);
});
}

void Instance::callFinished(not_null<Call*> call) {
Expand Down Expand Up @@ -284,6 +288,31 @@ void Instance::handleCallUpdate(const MTPPhoneCall &call) {
bool Instance::alreadyInCall() {
return (_currentCall && _currentCall->state() != Call::State::Busy);
}

void Instance::requestMicrophonePermissionOrFail(Fn<void()> onSuccess) {
Platform::PermissionStatus status=Platform::GetPermissionStatus(Platform::PermissionType::Microphone);
if (status==Platform::PermissionStatus::Granted) {
onSuccess();
} else if(status==Platform::PermissionStatus::CanRequest) {
Platform::RequestPermission(Platform::PermissionType::Microphone, [this, onSuccess](Platform::PermissionStatus status){
if (status==Platform::PermissionStatus::Granted) {
crl::on_main(onSuccess);
} else {
if (_currentCall) {
_currentCall->hangup();
}
}
});
} else {
if (alreadyInCall()) {
_currentCall->hangup();
}
Ui::show(Box<ConfirmBox>(lang(lng_no_mic_permission), lang(lng_menu_settings), [](){
Platform::OpenSystemSettingsForPermission(Platform::PermissionType::Microphone);
Ui::hideLayer();
}));
}
}

Instance::~Instance() {
for (auto panel : _pendingPanels) {
Expand Down
1 change: 1 addition & 0 deletions Telegram/SourceFiles/calls/calls_instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class Instance : private MTP::Sender, private Call::Delegate, private base::Subs
void createCall(not_null<UserData*> user, Call::Type type);
void destroyCall(not_null<Call*> call);
void destroyCurrentPanel();
void requestMicrophonePermissionOrFail(Fn<void()> onSuccess) override;

void refreshDhConfig();
void refreshServerConfig();
Expand Down
12 changes: 12 additions & 0 deletions Telegram/SourceFiles/platform/linux/specific_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,18 @@ void RegisterCustomScheme() {
#endif // !TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
}

PermissionStatus GetPermissionStatus(PermissionType type){
return PermissionStatus::Granted;
}

void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCallback){

}

void OpenSystemSettingsForPermission(PermissionType type){

}

namespace ThirdParty {

void start() {
Expand Down
46 changes: 46 additions & 0 deletions Telegram/SourceFiles/platform/mac/specific_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <IOKit/hidsystem/ev_keymap.h>
#include <SPMediaKeyTap.h>
#include <mach-o/dyld.h>
#include <AVFoundation/AVFoundation.h>

namespace {

Expand Down Expand Up @@ -283,6 +284,51 @@ void RegisterCustomScheme() {
#endif // !TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
}

// I do check for availability, just not in the exact way clang is content with
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
PermissionStatus GetPermissionStatus(PermissionType type) {
switch(type) {
case PermissionType::Microphone:
if([AVCaptureDevice respondsToSelector: @selector(authorizationStatusForMediaType:)]) { // Available starting with 10.14
switch([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio]) {
case AVAuthorizationStatusNotDetermined:
return PermissionStatus::CanRequest;
case AVAuthorizationStatusAuthorized:
return PermissionStatus::Granted;
case AVAuthorizationStatusDenied:
case AVAuthorizationStatusRestricted:
return PermissionStatus::Denied;
}
}
return PermissionStatus::Granted;
}
return PermissionStatus::Granted;
}

void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCallback) {
switch(type) {
case PermissionType::Microphone:
if([AVCaptureDevice respondsToSelector: @selector(requestAccessForMediaType:completionHandler:)]) { // Available starting with 10.14
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
resultCallback(granted ? PermissionStatus::Granted : PermissionStatus::Denied);
}];
}else{
resultCallback(PermissionStatus::Granted);
}
break;
}
}
#pragma clang diagnostic pop // -Wunguarded-availability

void OpenSystemSettingsForPermission(PermissionType type) {
switch(type) {
case PermissionType::Microphone:
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone"]];
break;
}
}

} // namespace Platform

void psNewVersion() {
Expand Down
12 changes: 12 additions & 0 deletions Telegram/SourceFiles/platform/platform_specific.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ namespace Platform {

void start();
void finish();

enum class PermissionStatus {
Granted,
CanRequest,
Denied,
};
enum class PermissionType {
Microphone,
};

void SetWatchingMediaKeys(bool watching);
bool IsApplicationActive();
Expand All @@ -20,6 +29,9 @@ void InitOnTopPanel(QWidget *panel);
void DeInitOnTopPanel(QWidget *panel);
void ReInitOnTopPanel(QWidget *panel);
void RegisterCustomScheme();
PermissionStatus GetPermissionStatus(PermissionType type);
void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCallback);
void OpenSystemSettingsForPermission(PermissionType type);

QString SystemLanguage();
QString SystemCountry();
Expand Down
31 changes: 31 additions & 0 deletions Telegram/SourceFiles/platform/win/specific_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,37 @@ void RegisterCustomScheme() {
#endif // !TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
}

PermissionStatus GetPermissionStatus(PermissionType type) {
if(type==PermissionType::Microphone) {
PermissionStatus result=PermissionStatus::Granted;
HKEY hKey;
LSTATUS res=RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\CapabilityAccessManager\\ConsentStore\\microphone", 0, KEY_QUERY_VALUE, &hKey);
if(res==ERROR_SUCCESS) {
wchar_t buf[20];
DWORD length=sizeof(buf);
res=RegQueryValueEx(hKey, L"Value", NULL, NULL, (LPBYTE)buf, &length);
if(res==ERROR_SUCCESS) {
if(wcscmp(buf, L"Deny")==0) {
result=PermissionStatus::Denied;
}
}
RegCloseKey(hKey);
}
return result;
}
return PermissionStatus::Granted;
}

void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCallback) {

}

void OpenSystemSettingsForPermission(PermissionType type) {
if(type==PermissionType::Microphone) {
ShellExecute(NULL, L"open", L"ms-settings:privacy-microphone", NULL, NULL, SW_SHOWDEFAULT);
}
}

} // namespace Platform

void psNewVersion() {
Expand Down

0 comments on commit 0e7f933

Please sign in to comment.