| Index: chrome/app_shim/chrome_main_app_mode_mac.mm
|
| diff --git a/chrome/app_shim/chrome_main_app_mode_mac.mm b/chrome/app_shim/chrome_main_app_mode_mac.mm
|
| index ea203e5303d9d7257c86a202c90d0fd44f872830..2649d49e31a6f45ee52b5bf5ce5e3f7e93c268e6 100644
|
| --- a/chrome/app_shim/chrome_main_app_mode_mac.mm
|
| +++ b/chrome/app_shim/chrome_main_app_mode_mac.mm
|
| @@ -480,11 +480,6 @@ void AppShimController::SendSetAppHidden(bool hidden) {
|
| base::Callback<void(bool)> onReply_;
|
| AEDesc replyEvent_;
|
| }
|
| -// Sends an Apple Event to the process identified by |psn|, and calls |replyFn|
|
| -// when the reply is received. Internally this creates a ReplyEventHandler,
|
| -// which will delete itself once the reply event has been received.
|
| -+ (void)pingProcess:(const ProcessSerialNumber&)psn
|
| - andCall:(base::Callback<void(bool)>)replyFn;
|
| @end
|
|
|
| @interface ReplyEventHandler (PrivateMethods)
|
| @@ -493,9 +488,8 @@ void AppShimController::SendSetAppHidden(bool hidden) {
|
| // Apple Event reply arrives.
|
| - (id)initWithCallback:(base::Callback<void(bool)>)replyFn;
|
|
|
| -// Sends an Apple Event ping to the process identified by |psn| and registers
|
| -// to listen for a reply.
|
| -- (void)pingProcess:(const ProcessSerialNumber&)psn;
|
| +// Returns the apple event that should be sent to the process.
|
| +- (NSAppleEventDescriptor*)appleEventToSendToProcess;
|
|
|
| // Called when a response is received from the target process for the ping sent
|
| // by |-pingProcess:|.
|
| @@ -507,17 +501,6 @@ void AppShimController::SendSetAppHidden(bool hidden) {
|
| - (void)closeWithSuccess:(bool)success;
|
| @end
|
|
|
| -@implementation ReplyEventHandler
|
| -+ (void)pingProcess:(const ProcessSerialNumber&)psn
|
| - andCall:(base::Callback<void(bool)>)replyFn {
|
| - // The object will release itself when the reply arrives, or possibly earlier
|
| - // if an unrecoverable error occurs.
|
| - ReplyEventHandler* handler =
|
| - [[ReplyEventHandler alloc] initWithCallback:replyFn];
|
| - [handler pingProcess:psn];
|
| -}
|
| -@end
|
| -
|
| @implementation ReplyEventHandler (PrivateMethods)
|
| - (id)initWithCallback:(base::Callback<void(bool)>)replyFn {
|
| if ((self = [super init])) {
|
| @@ -526,35 +509,20 @@ void AppShimController::SendSetAppHidden(bool hidden) {
|
| return self;
|
| }
|
|
|
| -- (void)pingProcess:(const ProcessSerialNumber&)psn {
|
| +- (NSAppleEventDescriptor*)appleEventToSendToProcess {
|
| // Register the reply listener.
|
| NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager];
|
| [em setEventHandler:self
|
| andSelector:@selector(message:withReply:)
|
| forEventClass:'aevt'
|
| andEventID:'ansr'];
|
| - // Craft the Apple Event to send.
|
| - NSAppleEventDescriptor* target = [NSAppleEventDescriptor
|
| - descriptorWithDescriptorType:typeProcessSerialNumber
|
| - bytes:&psn
|
| - length:sizeof(psn)];
|
| - NSAppleEventDescriptor* initial_event =
|
| - [NSAppleEventDescriptor
|
| - appleEventWithEventClass:app_mode::kAEChromeAppClass
|
| - eventID:app_mode::kAEChromeAppPing
|
| - targetDescriptor:target
|
| - returnID:kAutoGenerateReturnID
|
| - transactionID:kAnyTransactionID];
|
| -
|
| - // Note that AESendMessage effectively ignores kAEDefaultTimeout, because this
|
| - // call does not pass kAEWantReceipt (which is deprecated and unsupported on
|
| - // Mac). Instead, rely on OnPingChromeTimeout().
|
| - OSStatus status = AESendMessage(
|
| - [initial_event aeDesc], &replyEvent_, kAEQueueReply, kAEDefaultTimeout);
|
| - if (status != noErr) {
|
| - OSSTATUS_LOG(ERROR, status) << "AESendMessage";
|
| - [self closeWithSuccess:false];
|
| - }
|
| + NSAppleEventDescriptor* initial_event = [NSAppleEventDescriptor
|
| + appleEventWithEventClass:app_mode::kAEChromeAppClass
|
| + eventID:app_mode::kAEChromeAppPing
|
| + targetDescriptor:nil
|
| + returnID:kAutoGenerateReturnID
|
| + transactionID:kAnyTransactionID];
|
| + return initial_event;
|
| }
|
|
|
| - (void)message:(NSAppleEventDescriptor*)event
|
| @@ -668,7 +636,6 @@ int ChromeAppModeStart_v4(const app_mode::ChromeAppModeInfo* info) {
|
| !base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| app_mode::kLaunchedForTest)) {
|
| // Launch Chrome if it isn't already running.
|
| - ProcessSerialNumber psn;
|
| base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
|
| command_line.AppendSwitch(switches::kSilentLaunch);
|
|
|
| @@ -681,24 +648,25 @@ int ChromeAppModeStart_v4(const app_mode::ChromeAppModeInfo* info) {
|
| info->profile_dir);
|
| }
|
|
|
| - bool success =
|
| - base::mac::OpenApplicationWithPath(base::mac::OuterBundlePath(),
|
| - command_line,
|
| - kLSLaunchDefaults,
|
| - &psn);
|
| - if (!success)
|
| - return 1;
|
| + base::Callback<void(bool)> on_ping_chrome_reply = base::Bind(
|
| + &AppShimController::OnPingChromeReply, base::Unretained(&controller));
|
|
|
| - base::Callback<void(bool)> on_ping_chrome_reply =
|
| - base::Bind(&AppShimController::OnPingChromeReply,
|
| - base::Unretained(&controller));
|
| + // Self-owned object that will delete itself.
|
| + ReplyEventHandler* handler =
|
| + [[ReplyEventHandler alloc] initWithCallback:on_ping_chrome_reply];
|
| + NSAppleEventDescriptor* descriptor = [handler appleEventToSendToProcess];
|
| +
|
| + bool success = base::mac::OpenApplicationWithPath(
|
| + base::mac::OuterBundlePath(), command_line, NSWorkspaceLaunchDefault,
|
| + descriptor, nullptr);
|
| + if (!success) {
|
| + [handler closeWithSuccess:false];
|
| + return 1;
|
| + }
|
|
|
| // This code abuses the fact that Apple Events sent before the process is
|
| // fully initialized don't receive a reply until its run loop starts. Once
|
| // the reply is received, Chrome will have opened its IPC port, guaranteed.
|
| - [ReplyEventHandler pingProcess:psn
|
| - andCall:on_ping_chrome_reply];
|
| -
|
| main_message_loop.task_runner()->PostDelayedTask(
|
| FROM_HERE, base::Bind(&AppShimController::OnPingChromeTimeout,
|
| base::Unretained(&controller)),
|
|
|