[MacOS Host] Replacing system dialog with custom permission dialog
This CL replaces the confusing, generic, platform provided permission dialog on Mojave with one which provides more context and instructions on what the user needs to do to enable Chrome Remote Desktop on Mojave. Bug: 902041 Change-Id: Ibda9459dfba3579c596cf5e2703b8c3d0ea28059 Reviewed-on: https://chromium-review.googlesource.com/c/1334838 Reviewed-by: Jamie Walch <jamiewalch@chromium.org> Reviewed-by: Gary Kacmarcik <garykac@chromium.org> Commit-Queue: Joe Downing <joedow@chromium.org> Cr-Commit-Position: refs/heads/master@{#608473}
This commit is contained in:
remoting/host
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user