diff --git a/remoting/host/mac/permission_utils.h b/remoting/host/mac/permission_utils.h index 803a302c055bb..6725bb588e502 100644 --- a/remoting/host/mac/permission_utils.h +++ b/remoting/host/mac/permission_utils.h @@ -5,13 +5,20 @@ #ifndef REMOTING_HOST_MAC_PERMISSION_UTILS_H_ #define REMOTING_HOST_MAC_PERMISSION_UTILS_H_ +#include "base/memory/scoped_refptr.h" + +namespace base { +class SingleThreadTaskRunner; +} + namespace remoting { namespace mac { // Prompts the user to add the current application to the set of trusted // Accessibility applications. This is only required for input injection on -// 10.14 and later OSes. -void PromptUserToChangeTrustStateIfNeeded(); +// 10.14 and later OSes. |task_runner| is used to run the dialog message loop. +void PromptUserToChangeTrustStateIfNeeded( + scoped_refptr<base::SingleThreadTaskRunner> task_runner); } // namespace mac } // namespace remoting diff --git a/remoting/host/mac/permission_utils.mm b/remoting/host/mac/permission_utils.mm index a6a496b2000ce..6cb20cbc4d5b7 100644 --- a/remoting/host/mac/permission_utils.mm +++ b/remoting/host/mac/permission_utils.mm @@ -6,18 +6,71 @@ #import <Cocoa/Cocoa.h> +#include "base/bind.h" +#include "base/location.h" #include "base/logging.h" +#include "base/memory/scoped_refptr.h" +#include "base/single_thread_task_runner.h" +#include "base/strings/sys_string_conversions.h" +#include "remoting/base/string_resources.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/l10n/l10n_util_mac.h" + +namespace { + +constexpr int kMinDialogWidthPx = 650; +constexpr NSString* kServiceScriptName = @"org.chromium.chromoting.me2me.sh"; + +void ShowPermissionDialog() { + NSAlert* alert = [[NSAlert alloc] init]; + [alert setMessageText:l10n_util::GetNSString( + IDS_ACCESSIBILITY_PERMISSION_DIALOG_TITLE)]; + [alert setInformativeText: + l10n_util::GetNSStringF( + IDS_ACCESSIBILITY_PERMISSION_DIALOG_BODY_TEXT, + l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), + l10n_util::GetStringUTF16( + IDS_ACCESSIBILITY_PERMISSION_DIALOG_OPEN_BUTTON), + base::SysNSStringToUTF16(kServiceScriptName))]; + [alert + addButtonWithTitle:l10n_util::GetNSString( + IDS_ACCESSIBILITY_PERMISSION_DIALOG_OPEN_BUTTON)]; + [alert addButtonWithTitle: + l10n_util::GetNSString( + IDS_ACCESSIBILITY_PERMISSION_DIALOG_NOT_NOW_BUTTON)]; + + // Increase the alert width so the title doesn't wrap and the body text is + // less scrunched. Note that we only want to set a min-width, we don't + // want to shrink the dialog if it is already larger than our min value. + NSRect frame = [alert.window frame]; + if (frame.size.width < kMinDialogWidthPx) + frame.size.width = kMinDialogWidthPx; + [alert.window setFrame:frame display:YES]; + + [alert setAlertStyle:NSAlertStyleWarning]; + [alert.window makeKeyWindow]; + if ([alert runModal] == NSAlertFirstButtonReturn) { + // Launch the Security and Preferences pane with Accessibility selected. + [[NSWorkspace sharedWorkspace] + openURL: + [NSURL URLWithString:@"x-apple.systempreferences:com.apple." + @"preference.security?Privacy_Accessibility"]]; + } +} +} // namespace namespace remoting { namespace mac { -void PromptUserToChangeTrustStateIfNeeded() { - // This method will only display a permission prompt if the application is - // not trusted. - NSDictionary* options = @{(NSString*)kAXTrustedCheckOptionPrompt : @YES }; - if (!AXIsProcessTrustedWithOptions((CFDictionaryRef)options)) { - LOG(WARNING) << "AXIsProcessTrustedWithOptions: App is not trusted"; - } +void PromptUserToChangeTrustStateIfNeeded( + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + if (AXIsProcessTrusted()) + return; + + LOG(WARNING) << "AXIsProcessTrusted returned false, requesting " + << "permission from user to allow input injection."; + + task_runner->PostTask(FROM_HERE, base::BindOnce(&ShowPermissionDialog)); } } // namespace mac diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index 56ce6bfdfab7f..1eb1674a9f07a 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc @@ -1580,7 +1580,7 @@ void HostProcess::StartHost() { // will request that the user enable this permission for us if they are on an // affected platform and the permission has not already been approved. if (base::mac::IsAtLeastOS10_14()) { - mac::PromptUserToChangeTrustStateIfNeeded(); + mac::PromptUserToChangeTrustStateIfNeeded(context_->ui_task_runner()); } #endif