File: process_singleton_mac.mm

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (82 lines) | stat: -rw-r--r-- 2,877 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/process_singleton.h"

#include <Carbon/Carbon.h>
#include <CoreServices/CoreServices.h>

#include "base/mac/scoped_aedesc.h"

namespace {

// Extracts the URL from |event| and forwards it to an already-running Chromium
// process.
OSErr HandleGURLEvent(const AppleEvent* event,
                      AppleEvent* reply,
                      SRefCon handler_refcon) {
  pid_t forwarding_pid = *(reinterpret_cast<pid_t*>(handler_refcon));
  base::mac::ScopedAEDesc<> other_process_pid;
  // Create an address descriptor for the running process.
  AECreateDesc(typeKernelProcessID, &forwarding_pid, sizeof(forwarding_pid),
               other_process_pid.OutPointer());

  OSErr status = noErr;
  base::mac::ScopedAEDesc<> event_copy;
  status = AECreateAppleEvent(kInternetEventClass, kAEGetURL, other_process_pid,
                              kAutoGenerateReturnID, kAnyTransactionID,
                              event_copy.OutPointer());
  if (status != noErr)
    return status;

  base::mac::ScopedAEDesc<> url;
  // A GURL event's direct object is the URL as a descriptor with type
  // TEXT.
  status =
      AEGetParamDesc(event, keyDirectObject, typeWildCard, url.OutPointer());
  if (status != noErr)
    return status;

  status = AEPutParamDesc(event_copy.OutPointer(), keyDirectObject, url);
  if (status != noErr)
    return status;

  status = AESendMessage(event_copy, reply, kAENoReply, kNoTimeOut);
  if (status != noErr)
    return status;

  // Activate the running instance
  base::mac::ScopedAEDesc<> activate_event;
  status = AECreateAppleEvent(kAEMiscStandards, kAEActivate, other_process_pid,
                              kAutoGenerateReturnID, kAnyTransactionID,
                              activate_event.OutPointer());
  if (status != noErr)
    return status;

  return AESendMessage(activate_event, reply, kAENoReply, kNoTimeOut);
}

}  //  namespace

bool ProcessSingleton::WaitForAndForwardOpenURLEvent(
    pid_t event_destination_pid) {
  AEEventHandlerProcPtr handler = NewAEEventHandlerUPP(HandleGURLEvent);
  if (AEInstallEventHandler(kInternetEventClass, kAEGetURL, handler,
                            &event_destination_pid, false) != noErr) {
    DisposeAEEventHandlerUPP(handler);
    return false;
  }
  bool result = false;
  const EventTypeSpec spec = {kEventClassAppleEvent, kEventAppleEvent};
  EventRef event_ref;
  if (ReceiveNextEvent(1, &spec, kEventDurationNanosecond, true, &event_ref) ==
      noErr) {
    OSStatus processed = AEProcessEvent(event_ref);
    ReleaseEvent(event_ref);
    result = processed == noErr;
  }
  AERemoveEventHandler(kInternetEventClass, kAEGetURL, handler, false);
  DisposeAEEventHandlerUPP(handler);
  return result;
}