Request camera permissions on macOS.

This commit is contained in:
John Preston 2020-05-17 13:12:27 +04:00
parent 6d36176a8d
commit 71040464c5
9 changed files with 71 additions and 40 deletions

View File

@ -217,7 +217,7 @@ void Call::startIncoming() {
}
void Call::answer() {
_delegate->requestMicrophonePermissionOrFail(crl::guard(this, [=] {
_delegate->requestPermissionsOrFail(crl::guard(this, [=] {
actuallyAnswer();
}));
}

View File

@ -46,7 +46,7 @@ public:
Ended,
};
virtual void playSound(Sound sound) = 0;
virtual void requestMicrophonePermissionOrFail(Fn<void()> result) = 0;
virtual void requestPermissionsOrFail(Fn<void()> result) = 0;
virtual ~Delegate() = default;

View File

@ -55,7 +55,7 @@ void Instance::startOutgoingCall(not_null<UserData*> user) {
tr::lng_call_error_not_available(tr::now, lt_user, user->name)));
return;
}
requestMicrophonePermissionOrFail(crl::guard(this, [=] {
requestPermissionsOrFail(crl::guard(this, [=] {
createCall(user, Call::Type::Outgoing);
}));
}
@ -317,13 +317,23 @@ rpl::producer<Call*> Instance::currentCallValue() const {
return _currentCallChanges.events_starting_with(currentCall());
}
void Instance::requestMicrophonePermissionOrFail(Fn<void()> onSuccess) {
Platform::PermissionStatus status=Platform::GetPermissionStatus(Platform::PermissionType::Microphone);
if (status==Platform::PermissionStatus::Granted) {
void Instance::requestPermissionsOrFail(Fn<void()> onSuccess) {
using Type = Platform::PermissionType;
requestPermissionOrFail(Type::Microphone, [=] {
requestPermissionOrFail(Type::Camera, [=] {
crl::on_main(onSuccess);
});
});
}
void Instance::requestPermissionOrFail(Platform::PermissionType type, Fn<void()> onSuccess) {
using Status = Platform::PermissionStatus;
const auto status = Platform::GetPermissionStatus(type);
if (status == Status::Granted) {
onSuccess();
} else if(status==Platform::PermissionStatus::CanRequest) {
Platform::RequestPermission(Platform::PermissionType::Microphone, crl::guard(this, [=](Platform::PermissionStatus status) {
if (status==Platform::PermissionStatus::Granted) {
} else if (status == Status::CanRequest) {
Platform::RequestPermission(type, crl::guard(this, [=](Status status) {
if (status == Status::Granted) {
crl::on_main(onSuccess);
} else {
if (_currentCall) {
@ -335,8 +345,8 @@ void Instance::requestMicrophonePermissionOrFail(Fn<void()> onSuccess) {
if (alreadyInCall()) {
_currentCall->hangup();
}
Ui::show(Box<ConfirmBox>(tr::lng_no_mic_permission(tr::now), tr::lng_menu_settings(tr::now), crl::guard(this, [] {
Platform::OpenSystemSettingsForPermission(Platform::PermissionType::Microphone);
Ui::show(Box<ConfirmBox>(tr::lng_no_mic_permission(tr::now), tr::lng_menu_settings(tr::now), crl::guard(this, [=] {
Platform::OpenSystemSettingsForPermission(type);
Ui::hideLayer();
})));
}

View File

@ -10,6 +10,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/sender.h"
#include "calls/calls_call.h"
namespace Platform {
enum class PermissionType;
} // namespace Platform
namespace Media {
namespace Audio {
class Track;
@ -57,7 +61,8 @@ private:
void createCall(not_null<UserData*> user, Call::Type type);
void destroyCall(not_null<Call*> call);
void destroyCurrentPanel();
void requestMicrophonePermissionOrFail(Fn<void()> onSuccess) override;
void requestPermissionsOrFail(Fn<void()> onSuccess) override;
void requestPermissionOrFail(Platform::PermissionType type, Fn<void()> onSuccess);
void handleSignalingData(const MTPDupdatePhoneCallSignalingData &data);

View File

@ -170,19 +170,23 @@ void RegisterCustomScheme(bool force) {
PermissionStatus GetPermissionStatus(PermissionType type) {
#ifndef OS_MAC_OLD
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;
}
case PermissionType::Microphone:
case PermissionType::Camera:
const auto nativeType = (type == PermissionType::Microphone)
? AVMediaTypeAudio
: AVMediaTypeVideo;
if ([AVCaptureDevice respondsToSelector: @selector(authorizationStatusForMediaType:)]) { // Available starting with 10.14
switch ([AVCaptureDevice authorizationStatusForMediaType:nativeType]) {
case AVAuthorizationStatusNotDetermined:
return PermissionStatus::CanRequest;
case AVAuthorizationStatusAuthorized:
return PermissionStatus::Granted;
case AVAuthorizationStatusDenied:
case AVAuthorizationStatusRestricted:
return PermissionStatus::Denied;
}
break;
}
break;
}
#endif // OS_MAC_OLD
return PermissionStatus::Granted;
@ -191,15 +195,19 @@ PermissionStatus GetPermissionStatus(PermissionType type) {
void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCallback) {
#ifndef OS_MAC_OLD
switch (type) {
case PermissionType::Microphone:
if ([AVCaptureDevice respondsToSelector: @selector(requestAccessForMediaType:completionHandler:)]) { // Available starting with 10.14
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
crl::on_main([=] {
resultCallback(granted ? PermissionStatus::Granted : PermissionStatus::Denied);
});
}];
}
break;
case PermissionType::Microphone:
case PermissionType::Camera:
const auto nativeType = (type == PermissionType::Microphone)
? AVMediaTypeAudio
: AVMediaTypeVideo;
if ([AVCaptureDevice respondsToSelector: @selector(requestAccessForMediaType:completionHandler:)]) { // Available starting with 10.14
[AVCaptureDevice requestAccessForMediaType:nativeType completionHandler:^(BOOL granted) {
crl::on_main([=] {
resultCallback(granted ? PermissionStatus::Granted : PermissionStatus::Denied);
});
}];
}
break;
}
#endif // OS_MAC_OLD
resultCallback(PermissionStatus::Granted);
@ -209,9 +217,12 @@ void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCal
void OpenSystemSettingsForPermission(PermissionType type) {
#ifndef OS_MAC_OLD
switch (type) {
case PermissionType::Microphone:
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone"]];
break;
case PermissionType::Microphone:
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone"]];
break;
case PermissionType::Camera:
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Camera"]];
break;
}
#endif // OS_MAC_OLD
}

View File

@ -22,6 +22,7 @@ enum class PermissionStatus {
enum class PermissionType {
Microphone,
Camera,
};
enum class SystemSettingsType {

View File

@ -41,6 +41,8 @@
<string></string>
<key>NSMicrophoneUsageDescription</key>
<string>We need access to your microphone so that you can record voice messages and make calls.</string>
<key>NSCameraUsageDescription</key>
<string>We need access to your camera so that you can record video messages and make video calls.</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>

View File

@ -4,5 +4,7 @@
<dict>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
</dict>
</plist>

View File

@ -267,6 +267,10 @@ if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "osx" ] || [ "$BuildTarget
fi
if [ "$NotarizeRequestId" == "" ]; then
rm "$ReleasePath/$BinaryName.app/Contents/Info.plist"
rm "$ProjectPath/Telegram/CMakeFiles/Telegram.dir/Info.plist"
rm -rf "$ReleasePath/$BinaryName.app/Contents/_CodeSignature"
./configure.sh
cd $ProjectPath
@ -490,8 +494,6 @@ if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "osx" ] || [ "$BuildTarget
mv "$ReleasePath/$BinaryName.app.dSYM" "$DeployPath/"
rm "$ReleasePath/$BinaryName.app/Contents/MacOS/$BinaryName"
rm "$ReleasePath/$BinaryName.app/Contents/Frameworks/Updater"
rm "$ReleasePath/$BinaryName.app/Contents/Info.plist"
rm -rf "$ReleasePath/$BinaryName.app/Contents/_CodeSignature"
mv "$ReleasePath/$UpdateFile" "$DeployPath/"
mv "$ReleasePath/$SetupFile" "$DeployPath/"
@ -518,8 +520,6 @@ if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "osx" ] || [ "$BuildTarget
mv "$ReleasePath/$BinaryName.pkg" "$DeployPath/"
mv "$ReleasePath/$BinaryName.app.dSYM" "$DeployPath/"
rm "$ReleasePath/$BinaryName.app/Contents/MacOS/$BinaryName"
rm "$ReleasePath/$BinaryName.app/Contents/Info.plist"
rm -rf "$ReleasePath/$BinaryName.app/Contents/_CodeSignature"
fi
fi