1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/process_singleton.h"
7 #include <Carbon/Carbon.h>
8 #include <CoreServices/CoreServices.h>
10 #include "base/mac/scoped_aedesc.h"
14 // Extracts the URL from |event| and forwards it to an already-running Chromium
16 OSErr HandleGURLEvent(const AppleEvent* event,
18 SRefCon handler_refcon) {
19 pid_t forwarding_pid = *(reinterpret_cast<pid_t*>(handler_refcon));
20 base::mac::ScopedAEDesc<> other_process_pid;
21 // Create an address descriptor for the running process.
22 AECreateDesc(typeKernelProcessID, &forwarding_pid, sizeof(forwarding_pid),
23 other_process_pid.OutPointer());
26 base::mac::ScopedAEDesc<> event_copy;
27 status = AECreateAppleEvent(kInternetEventClass, kAEGetURL, other_process_pid,
28 kAutoGenerateReturnID, kAnyTransactionID,
29 event_copy.OutPointer());
33 base::mac::ScopedAEDesc<> url;
34 // A GURL event's direct object is the URL as a descriptor with type
37 AEGetParamDesc(event, keyDirectObject, typeWildCard, url.OutPointer());
41 status = AEPutParamDesc(event_copy.OutPointer(), keyDirectObject, url);
45 status = AESendMessage(event_copy, reply, kAENoReply, kNoTimeOut);
49 // Activate the running instance
50 base::mac::ScopedAEDesc<> activate_event;
51 status = AECreateAppleEvent(kAEMiscStandards, kAEActivate, other_process_pid,
52 kAutoGenerateReturnID, kAnyTransactionID,
53 activate_event.OutPointer());
57 return AESendMessage(activate_event, reply, kAENoReply, kNoTimeOut);
62 bool ProcessSingleton::WaitForAndForwardOpenURLEvent(
63 pid_t event_destination_pid) {
64 AEEventHandlerProcPtr handler = NewAEEventHandlerUPP(HandleGURLEvent);
65 if (AEInstallEventHandler(kInternetEventClass, kAEGetURL, handler,
66 &event_destination_pid, false) != noErr) {
67 DisposeAEEventHandlerUPP(handler);
71 const EventTypeSpec spec = {kEventClassAppleEvent, kEventAppleEvent};
73 if (ReceiveNextEvent(1, &spec, kEventDurationNanosecond, true, &event_ref) ==
75 OSStatus processed = AEProcessEvent(event_ref);
76 ReleaseEvent(event_ref);
77 result = processed == noErr;
79 AERemoveEventHandler(kInternetEventClass, kAEGetURL, handler, false);
80 DisposeAEEventHandlerUPP(handler);