diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /ipc/glue/ProcessUtils_mac.mm | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ipc/glue/ProcessUtils_mac.mm')
-rw-r--r-- | ipc/glue/ProcessUtils_mac.mm | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/ipc/glue/ProcessUtils_mac.mm b/ipc/glue/ProcessUtils_mac.mm new file mode 100644 index 0000000000..0f1d8ecbba --- /dev/null +++ b/ipc/glue/ProcessUtils_mac.mm @@ -0,0 +1,109 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ProcessUtils.h" + +#include "nsObjCExceptions.h" +#include "nsCocoaUtils.h" +#include "nsString.h" +#include "mozilla/Sprintf.h" + +#define UNDOCUMENTED_SESSION_CONSTANT ((int)-2) + +namespace mozilla { +namespace ipc { + +static void* sApplicationASN = NULL; +static void* sApplicationInfoItem = NULL; + +void SetThisProcessName(const char* aProcessName) { + NS_OBJC_BEGIN_TRY_ABORT_BLOCK; + nsAutoreleasePool localPool; + + if (!aProcessName || strcmp(aProcessName, "") == 0) { + return; + } + + NSString* currentName = + [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + char formattedName[1024]; + SprintfLiteral(formattedName, "%s %s", [currentName UTF8String], aProcessName); + + aProcessName = formattedName; + + // This function is based on Chrome/Webkit's and relies on potentially dangerous SPI. + typedef CFTypeRef (*LSGetASNType)(); + typedef OSStatus (*LSSetInformationItemType)(int, CFTypeRef, CFStringRef, CFStringRef, + CFDictionaryRef*); + + CFBundleRef launchServices = ::CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices")); + if (!launchServices) { + NS_WARNING("Failed to set process name: Could not open LaunchServices bundle"); + return; + } + + if (!sApplicationASN) { + sApplicationASN = + ::CFBundleGetFunctionPointerForName(launchServices, CFSTR("_LSGetCurrentApplicationASN")); + if (!sApplicationASN) { + NS_WARNING("Failed to set process name: Could not get function pointer " + "for LaunchServices"); + return; + } + } + + LSGetASNType getASNFunc = reinterpret_cast<LSGetASNType>(sApplicationASN); + + if (!sApplicationInfoItem) { + sApplicationInfoItem = ::CFBundleGetFunctionPointerForName( + launchServices, CFSTR("_LSSetApplicationInformationItem")); + } + + LSSetInformationItemType setInformationItemFunc = + reinterpret_cast<LSSetInformationItemType>(sApplicationInfoItem); + + void* displayNameKeyAddr = + ::CFBundleGetDataPointerForName(launchServices, CFSTR("_kLSDisplayNameKey")); + + CFStringRef displayNameKey = nil; + if (displayNameKeyAddr) { + displayNameKey = reinterpret_cast<CFStringRef>(*(CFStringRef*)displayNameKeyAddr); + } + + // We need this to ensure we have a connection to the Process Manager, not + // doing so will silently fail and process name wont be updated. + ProcessSerialNumber psn; + if (::GetCurrentProcess(&psn) != noErr) { + return; + } + + CFTypeRef currentAsn = getASNFunc ? getASNFunc() : nullptr; + + if (!getASNFunc || !setInformationItemFunc || !displayNameKey || !currentAsn) { + NS_WARNING("Failed to set process name: Accessing launchServices failed"); + return; + } + + CFStringRef processName = ::CFStringCreateWithCString(nil, aProcessName, kCFStringEncodingASCII); + if (!processName) { + NS_WARNING("Failed to set process name: Could not create CFStringRef"); + return; + } + + OSErr err = + setInformationItemFunc(UNDOCUMENTED_SESSION_CONSTANT, currentAsn, displayNameKey, processName, + nil); // Optional out param + ::CFRelease(processName); + if (err != noErr) { + NS_WARNING("Failed to set process name: LSSetInformationItemType err"); + return; + } + + return; + NS_OBJC_END_TRY_ABORT_BLOCK; +} + +} // namespace ipc +} // namespace mozilla |