fixies
This commit is contained in:
parent
8809421181
commit
3c154878d3
4 changed files with 79 additions and 42 deletions
|
@ -142,7 +142,7 @@ namespace {
|
||||||
if (getsockopt(fileDescriptor, SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1)
|
if (getsockopt(fileDescriptor, SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1)
|
||||||
return Err(DracError("Failed to get socket credentials (SO_PEERCRED)"));
|
return Err(DracError("Failed to get socket credentials (SO_PEERCRED)"));
|
||||||
|
|
||||||
Array<char, 128> exeLinkPathBuf;
|
Array<char, 128> exeLinkPathBuf {};
|
||||||
|
|
||||||
auto [out, size] = std::format_to_n(exeLinkPathBuf.data(), exeLinkPathBuf.size() - 1, "/proc/{}/exe", cred.pid);
|
auto [out, size] = std::format_to_n(exeLinkPathBuf.data(), exeLinkPathBuf.size() - 1, "/proc/{}/exe", cred.pid);
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ namespace {
|
||||||
|
|
||||||
const char* exeLinkPath = exeLinkPathBuf.data();
|
const char* exeLinkPath = exeLinkPathBuf.data();
|
||||||
|
|
||||||
Array<char, PATH_MAX> exeRealPathBuf; // NOLINT(misc-include-cleaner) - PATH_MAX is in <climits>
|
Array<char, PATH_MAX> exeRealPathBuf {}; // NOLINT(misc-include-cleaner) - PATH_MAX is in <climits>
|
||||||
|
|
||||||
const isize bytesRead = readlink(exeLinkPath, exeRealPathBuf.data(), exeRealPathBuf.size() - 1);
|
const isize bytesRead = readlink(exeLinkPath, exeRealPathBuf.data(), exeRealPathBuf.size() - 1);
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#include <flat_map>
|
#include <flat_map> // std::flat_map
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h> // statvfs
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h> // {CTL_KERN, KERN_PROC, KERN_PROC_ALL, kinfo_proc, sysctl, sysctlbyname}
|
||||||
|
|
||||||
#include "src/core/package.hpp"
|
#include "src/core/package.hpp"
|
||||||
#include "src/util/defs.hpp"
|
#include "src/util/defs.hpp"
|
||||||
|
@ -292,8 +292,10 @@ namespace os {
|
||||||
if (statvfs("/", &vfs) != 0)
|
if (statvfs("/", &vfs) != 0)
|
||||||
return Err(DracError("Failed to get disk usage"));
|
return Err(DracError("Failed to get disk usage"));
|
||||||
|
|
||||||
return DiskSpace { .usedBytes = (vfs.f_blocks - vfs.f_bfree) * vfs.f_frsize,
|
return DiskSpace {
|
||||||
.totalBytes = vfs.f_blocks * vfs.f_frsize };
|
.usedBytes = (vfs.f_blocks - vfs.f_bfree) * vfs.f_frsize,
|
||||||
|
.totalBytes = vfs.f_blocks * vfs.f_frsize,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GetShell() -> Result<String> {
|
fn GetShell() -> Result<String> {
|
||||||
|
|
|
@ -7,15 +7,16 @@
|
||||||
#include "src/util/error.hpp"
|
#include "src/util/error.hpp"
|
||||||
#include "src/util/types.hpp"
|
#include "src/util/types.hpp"
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
using util::error::DracError;
|
using util::error::DracError;
|
||||||
using util::types::MediaInfo, util::types::String, util::types::Result;
|
using util::types::MediaInfo, util::types::String, util::types::Result;
|
||||||
|
|
||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h> // Foundation
|
||||||
|
|
||||||
@interface Bridge : NSObject
|
@interface Bridge : NSObject
|
||||||
+ (void)fetchCurrentPlayingMetadata:(void (^)(Result<NSDictionary*, const char*>))completion;
|
+ (void)fetchCurrentPlayingMetadata:(void (^_Nonnull)(NSDictionary* __nullable, NSError* __nullable))completion;
|
||||||
+ (Result<String, DracError>)macOSVersion;
|
+ (NSString* __nullable)macOSVersion;
|
||||||
@end
|
@end
|
||||||
#else
|
#else
|
||||||
extern "C++" {
|
extern "C++" {
|
||||||
|
|
|
@ -4,30 +4,34 @@
|
||||||
#import "bridge.hpp"
|
#import "bridge.hpp"
|
||||||
|
|
||||||
#import <dispatch/dispatch.h>
|
#import <dispatch/dispatch.h>
|
||||||
|
#import <objc/runtime.h>
|
||||||
|
|
||||||
#include <expected>
|
#include <expected>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#import <objc/runtime.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "src/util/error.hpp"
|
#include "src/util/error.hpp"
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
using util::error::DracErrorCode;
|
using util::error::DracError, util::error::DracErrorCode;
|
||||||
using util::types::Err, util::types::Option, util::types::None;
|
using util::types::Err, util::types::Option, util::types::None, util::types::Result;
|
||||||
|
|
||||||
using MRMediaRemoteGetNowPlayingInfoFunction =
|
using MRMediaRemoteGetNowPlayingInfoFunction =
|
||||||
void (*)(dispatch_queue_t queue, void (^handler)(NSDictionary* information));
|
void (*)(dispatch_queue_t queue, void (^handler)(NSDictionary* information));
|
||||||
|
|
||||||
@implementation Bridge
|
@implementation Bridge
|
||||||
+ (void)fetchCurrentPlayingMetadata:(void (^)(std::expected<NSDictionary*, const char*>))completion {
|
+ (void)fetchCurrentPlayingMetadata:(void (^)(NSDictionary* __nullable, NSError* __nullable))completion {
|
||||||
CFURLRef urlRef = CFURLCreateWithFileSystemPath(
|
CFURLRef urlRef = CFURLCreateWithFileSystemPath(
|
||||||
kCFAllocatorDefault, CFSTR("/System/Library/PrivateFrameworks/MediaRemote.framework"), kCFURLPOSIXPathStyle, false
|
kCFAllocatorDefault,
|
||||||
|
CFSTR("/System/Library/PrivateFrameworks/MediaRemote.framework"),
|
||||||
|
kCFURLPOSIXPathStyle,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!urlRef) {
|
if (!urlRef) {
|
||||||
completion(std::unexpected("Failed to create CFURL for MediaRemote framework"));
|
completion(nil, [NSError errorWithDomain:@"com.draconis.error" code:1 userInfo:@{ NSLocalizedDescriptionKey : @"Failed to create CFURL for MediaRemote framework" }]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +40,7 @@ using MRMediaRemoteGetNowPlayingInfoFunction =
|
||||||
CFRelease(urlRef);
|
CFRelease(urlRef);
|
||||||
|
|
||||||
if (!bundleRef) {
|
if (!bundleRef) {
|
||||||
completion(std::unexpected("Failed to create bundle for MediaRemote framework"));
|
completion(nil, [NSError errorWithDomain:@"com.draconis.error" code:1 userInfo:@{ NSLocalizedDescriptionKey : @"Failed to create bundle for MediaRemote framework" }]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +50,7 @@ using MRMediaRemoteGetNowPlayingInfoFunction =
|
||||||
|
|
||||||
if (!mrMediaRemoteGetNowPlayingInfo) {
|
if (!mrMediaRemoteGetNowPlayingInfo) {
|
||||||
CFRelease(bundleRef);
|
CFRelease(bundleRef);
|
||||||
completion(std::unexpected("Failed to get MRMediaRemoteGetNowPlayingInfo function pointer"));
|
completion(nil, [NSError errorWithDomain:@"com.draconis.error" code:1 userInfo:@{ NSLocalizedDescriptionKey : @"Failed to get MRMediaRemoteGetNowPlayingInfo function pointer" }]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,34 +62,54 @@ using MRMediaRemoteGetNowPlayingInfoFunction =
|
||||||
mrMediaRemoteGetNowPlayingInfo(
|
mrMediaRemoteGetNowPlayingInfo(
|
||||||
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||||
^(NSDictionary* information) {
|
^(NSDictionary* information) {
|
||||||
completion(
|
if (!information) {
|
||||||
information ? std::expected<NSDictionary*, const char*>(information)
|
completion(nil, [NSError errorWithDomain:@"com.draconis.error" code:1 userInfo:@ { NSLocalizedDescriptionKey : @"No now playing information" }]);
|
||||||
: std::unexpected("No now playing information")
|
return;
|
||||||
);
|
}
|
||||||
|
|
||||||
|
completion(information, nil);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (Result<String>)macOSVersion {
|
+ (NSString*)macOSVersion {
|
||||||
NSProcessInfo* processInfo = [NSProcessInfo processInfo];
|
NSProcessInfo* processInfo = [NSProcessInfo processInfo];
|
||||||
|
if (!processInfo)
|
||||||
|
return nil;
|
||||||
|
|
||||||
NSOperatingSystemVersion osVersion = [processInfo operatingSystemVersion];
|
NSOperatingSystemVersion osVersion = [processInfo operatingSystemVersion];
|
||||||
|
if (osVersion.majorVersion == 0)
|
||||||
|
return nil;
|
||||||
|
|
||||||
NSString* versionNumber = nil;
|
NSString* versionNumber = nil;
|
||||||
if (osVersion.patchVersion == 0) {
|
if (osVersion.patchVersion == 0)
|
||||||
versionNumber = [NSString stringWithFormat:@"%ld.%ld", osVersion.majorVersion, osVersion.minorVersion];
|
versionNumber = [NSString stringWithFormat:@"%ld.%ld",
|
||||||
} else {
|
osVersion.majorVersion,
|
||||||
versionNumber = [NSString
|
osVersion.minorVersion];
|
||||||
stringWithFormat:@"%ld.%ld.%ld", osVersion.majorVersion, osVersion.minorVersion, osVersion.patchVersion];
|
else
|
||||||
}
|
versionNumber = [NSString stringWithFormat:@"%ld.%ld.%ld",
|
||||||
|
osVersion.majorVersion,
|
||||||
|
osVersion.minorVersion,
|
||||||
|
osVersion.patchVersion];
|
||||||
|
|
||||||
|
if (!versionNumber)
|
||||||
|
return nil;
|
||||||
|
|
||||||
NSDictionary* versionNames =
|
NSDictionary* versionNames =
|
||||||
@{ @11 : @"Big Sur", @12 : @"Monterey", @13 : @"Ventura", @14 : @"Sonoma", @15 : @"Sequoia" };
|
@{
|
||||||
|
@11 : @"Big Sur",
|
||||||
|
@12 : @"Monterey",
|
||||||
|
@13 : @"Ventura",
|
||||||
|
@14 : @"Sonoma",
|
||||||
|
@15 : @"Sequoia"
|
||||||
|
};
|
||||||
|
|
||||||
NSNumber* majorVersion = @(osVersion.majorVersion);
|
NSNumber* majorVersion = @(osVersion.majorVersion);
|
||||||
NSString* versionName = versionNames[majorVersion] ? versionNames[majorVersion] : @"Unknown";
|
NSString* versionName = versionNames[majorVersion] ? versionNames[majorVersion] : @"Unknown";
|
||||||
|
|
||||||
NSString* fullVersion = [NSString stringWithFormat:@"macOS %@ %@", versionNumber, versionName];
|
NSString* fullVersion = [NSString stringWithFormat:@"macOS %@ %@", versionNumber, versionName];
|
||||||
return String([fullVersion UTF8String]);
|
|
||||||
|
return fullVersion ? fullVersion : nil;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -96,25 +120,29 @@ extern "C++" {
|
||||||
|
|
||||||
const dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
const dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
||||||
|
|
||||||
[Bridge fetchCurrentPlayingMetadata:^(std::expected<NSDictionary*, const char*> metadataResult) {
|
[Bridge fetchCurrentPlayingMetadata:^(NSDictionary* __nullable information, NSError* __nullable error) {
|
||||||
if (!metadataResult) {
|
if (error) {
|
||||||
result = Err(DracError(DracErrorCode::InternalError, metadataResult.error()));
|
result = Err(DracError(DracErrorCode::InternalError, [error.localizedDescription UTF8String]));
|
||||||
dispatch_semaphore_signal(semaphore);
|
dispatch_semaphore_signal(semaphore);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NSDictionary* const metadata = *metadataResult;
|
if (!information) {
|
||||||
if (!metadata) {
|
|
||||||
result = Err(DracError(DracErrorCode::InternalError, "No metadata"));
|
result = Err(DracError(DracErrorCode::InternalError, "No metadata"));
|
||||||
dispatch_semaphore_signal(semaphore);
|
dispatch_semaphore_signal(semaphore);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NSString* const title = metadata[@"kMRMediaRemoteNowPlayingInfoTitle"];
|
const NSString* const title = information[@"kMRMediaRemoteNowPlayingInfoTitle"];
|
||||||
const NSString* const artist = metadata[@"kMRMediaRemoteNowPlayingInfoArtist"];
|
const NSString* const artist = information[@"kMRMediaRemoteNowPlayingInfoArtist"];
|
||||||
|
|
||||||
result = MediaInfo(
|
result = MediaInfo(
|
||||||
title ? Option(String([title UTF8String])) : None, artist ? Option(String([artist UTF8String])) : None
|
title
|
||||||
|
? Option(String([title UTF8String]))
|
||||||
|
: None,
|
||||||
|
artist
|
||||||
|
? Option(String([artist UTF8String]))
|
||||||
|
: None
|
||||||
);
|
);
|
||||||
|
|
||||||
dispatch_semaphore_signal(semaphore);
|
dispatch_semaphore_signal(semaphore);
|
||||||
|
@ -124,7 +152,13 @@ extern "C++" {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GetMacOSVersion() -> Result<String> { return [Bridge macOSVersion]; }
|
fn GetMacOSVersion() -> Result<String> {
|
||||||
|
NSString* version = [Bridge macOSVersion];
|
||||||
|
|
||||||
|
return version
|
||||||
|
? Result<String>(String([version UTF8String]))
|
||||||
|
: Err(DracError(DracErrorCode::InternalError, "Failed to get macOS version"));
|
||||||
|
}
|
||||||
// NOLINTEND(misc-use-internal-linkage)
|
// NOLINTEND(misc-use-internal-linkage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue