opt: add microphone permission tip

This commit is contained in:
Kingtous
2023-01-31 13:32:10 +08:00
parent 038d660e60
commit ebec8811c2
37 changed files with 114 additions and 3 deletions

View File

@@ -1723,3 +1723,30 @@ Future<void> updateSystemWindowTheme() async {
}
}
}
/// macOS only
///
/// Note: not found a general solution for rust based AVFoundation bingding.
/// [AVFoundation] crate has compile error.
const kMacOSPermChannel = MethodChannel("org.rustdesk.rustdesk/macos");
enum PermissionAuthorizeType {
undetermined,
authorized,
denied, // and restricted
}
Future<PermissionAuthorizeType> osxCanRecordAudio() async {
int res = await kMacOSPermChannel.invokeMethod("canRecordAudio");
print(res);
if (res > 0) {
return PermissionAuthorizeType.authorized;
} else if (res == 0) {
return PermissionAuthorizeType.undetermined;
} else {
return PermissionAuthorizeType.denied;
}
}
Future<bool> osxRequestAudio() async {
return await kMacOSPermChannel.invokeMethod("requestRecordAudio");
}

View File

@@ -44,6 +44,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
var watchIsCanScreenRecording = false;
var watchIsProcessTrust = false;
var watchIsInputMonitoring = false;
var watchIsCanRecordAudio = false;
Timer? _updateTimer;
@override
@@ -79,7 +80,16 @@ class _DesktopHomePageState extends State<DesktopHomePage>
buildTip(context),
buildIDBoard(context),
buildPasswordBoard(context),
buildHelpCards(),
FutureBuilder<Widget>(
future: buildHelpCards(),
builder: (_, data) {
if (data.hasData) {
return data.data!;
} else {
return const Offstage();
}
},
),
],
),
),
@@ -302,7 +312,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
);
}
Widget buildHelpCards() {
Future<Widget> buildHelpCards() async {
if (updateUrl.isNotEmpty) {
return buildInstallCard(
"Status",
@@ -348,6 +358,13 @@ class _DesktopHomePageState extends State<DesktopHomePage>
return buildInstallCard("", "install_daemon_tip", "Install", () async {
bind.mainIsInstalledDaemon(prompt: true);
});
} else if ((await osxCanRecordAudio() !=
PermissionAuthorizeType.authorized)) {
return buildInstallCard("Permissions", "config_microphone", "Configure",
() async {
osxRequestAudio();
watchIsCanRecordAudio = true;
});
}
} else if (Platform.isLinux) {
if (bind.mainCurrentIsWayland()) {
@@ -481,6 +498,20 @@ class _DesktopHomePageState extends State<DesktopHomePage>
setState(() {});
}
}
if (watchIsCanRecordAudio) {
if (Platform.isMacOS) {
Future.microtask(() async {
if ((await osxCanRecordAudio() ==
PermissionAuthorizeType.authorized)) {
watchIsCanRecordAudio = false;
setState(() {});
}
});
} else {
watchIsCanRecordAudio = false;
setState(() {});
}
}
});
Get.put<RxBool>(svcStopped, tag: 'stop-service');
rustDeskWinManager.registerActiveWindowListener(onActiveWindowChanged);

View File

@@ -43,6 +43,8 @@
<string>$(PRODUCT_COPYRIGHT)</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSMicrophoneUsageDescription</key>
<string>Record the sound from microphone for the purpose of the remote desktop.</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>

View File

@@ -1,4 +1,5 @@
import Cocoa
import AVFoundation
import FlutterMacOS
import desktop_multi_window
// import bitsdojo_window_macos
@@ -81,6 +82,23 @@ class MainFlutterWindow: NSWindow {
case "terminate":
NSApplication.shared.terminate(self)
result(nil)
case "canRecordAudio":
switch AVCaptureDevice.authorizationStatus(for: .audio) {
case .authorized:
result(1)
break
case .notDetermined:
result(0)
break
default:
result(-1)
break
}
case "requestRecordAudio":
AVCaptureDevice.requestAccess(for: .audio, completionHandler: { granted in
result(granted)
})
break
default:
result(FlutterMethodNotImplemented)
}