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() { void Call::answer() {
_delegate->requestMicrophonePermissionOrFail(crl::guard(this, [=] { _delegate->requestPermissionsOrFail(crl::guard(this, [=] {
actuallyAnswer(); actuallyAnswer();
})); }));
} }

View file

@ -46,7 +46,7 @@ public:
Ended, Ended,
}; };
virtual void playSound(Sound sound) = 0; virtual void playSound(Sound sound) = 0;
virtual void requestMicrophonePermissionOrFail(Fn<void()> result) = 0; virtual void requestPermissionsOrFail(Fn<void()> result) = 0;
virtual ~Delegate() = default; 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))); tr::lng_call_error_not_available(tr::now, lt_user, user->name)));
return; return;
} }
requestMicrophonePermissionOrFail(crl::guard(this, [=] { requestPermissionsOrFail(crl::guard(this, [=] {
createCall(user, Call::Type::Outgoing); createCall(user, Call::Type::Outgoing);
})); }));
} }
@ -317,13 +317,23 @@ rpl::producer<Call*> Instance::currentCallValue() const {
return _currentCallChanges.events_starting_with(currentCall()); return _currentCallChanges.events_starting_with(currentCall());
} }
void Instance::requestMicrophonePermissionOrFail(Fn<void()> onSuccess) { void Instance::requestPermissionsOrFail(Fn<void()> onSuccess) {
Platform::PermissionStatus status=Platform::GetPermissionStatus(Platform::PermissionType::Microphone); using Type = Platform::PermissionType;
if (status==Platform::PermissionStatus::Granted) { 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(); onSuccess();
} else if(status==Platform::PermissionStatus::CanRequest) { } else if (status == Status::CanRequest) {
Platform::RequestPermission(Platform::PermissionType::Microphone, crl::guard(this, [=](Platform::PermissionStatus status) { Platform::RequestPermission(type, crl::guard(this, [=](Status status) {
if (status==Platform::PermissionStatus::Granted) { if (status == Status::Granted) {
crl::on_main(onSuccess); crl::on_main(onSuccess);
} else { } else {
if (_currentCall) { if (_currentCall) {
@ -335,8 +345,8 @@ void Instance::requestMicrophonePermissionOrFail(Fn<void()> onSuccess) {
if (alreadyInCall()) { if (alreadyInCall()) {
_currentCall->hangup(); _currentCall->hangup();
} }
Ui::show(Box<ConfirmBox>(tr::lng_no_mic_permission(tr::now), tr::lng_menu_settings(tr::now), crl::guard(this, [] { 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); Platform::OpenSystemSettingsForPermission(type);
Ui::hideLayer(); Ui::hideLayer();
}))); })));
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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