[M120 Migration]Fix for crash during chrome exit
[platform/framework/web/chromium-efl.git] / chrome / browser / process_singleton_mac.mm
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.
4
5 #include "chrome/browser/process_singleton.h"
6
7 #include <Carbon/Carbon.h>
8 #include <CoreServices/CoreServices.h>
9
10 #include "base/mac/scoped_aedesc.h"
11
12 namespace {
13
14 // Extracts the URL from |event| and forwards it to an already-running Chromium
15 // process.
16 OSErr HandleGURLEvent(const AppleEvent* event,
17                       AppleEvent* reply,
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());
24
25   OSErr status = noErr;
26   base::mac::ScopedAEDesc<> event_copy;
27   status = AECreateAppleEvent(kInternetEventClass, kAEGetURL, other_process_pid,
28                               kAutoGenerateReturnID, kAnyTransactionID,
29                               event_copy.OutPointer());
30   if (status != noErr)
31     return status;
32
33   base::mac::ScopedAEDesc<> url;
34   // A GURL event's direct object is the URL as a descriptor with type
35   // TEXT.
36   status =
37       AEGetParamDesc(event, keyDirectObject, typeWildCard, url.OutPointer());
38   if (status != noErr)
39     return status;
40
41   status = AEPutParamDesc(event_copy.OutPointer(), keyDirectObject, url);
42   if (status != noErr)
43     return status;
44
45   status = AESendMessage(event_copy, reply, kAENoReply, kNoTimeOut);
46   if (status != noErr)
47     return status;
48
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());
54   if (status != noErr)
55     return status;
56
57   return AESendMessage(activate_event, reply, kAENoReply, kNoTimeOut);
58 }
59
60 }  //  namespace
61
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);
68     return false;
69   }
70   bool result = false;
71   const EventTypeSpec spec = {kEventClassAppleEvent, kEventAppleEvent};
72   EventRef event_ref;
73   if (ReceiveNextEvent(1, &spec, kEventDurationNanosecond, true, &event_ref) ==
74       noErr) {
75     OSStatus processed = AEProcessEvent(event_ref);
76     ReleaseEvent(event_ref);
77     result = processed == noErr;
78   }
79   AERemoveEventHandler(kInternetEventClass, kAEGetURL, handler, false);
80   DisposeAEEventHandlerUPP(handler);
81   return result;
82 }