refactor: use non-deprecated macOS API in RemoveAsDefaultProtocolClient (#47506)

refactor: use non-deprecated macOS API in RemoveAsDefaultProtocolClient
This commit is contained in:
Shelley Vohr
2025-07-01 10:19:28 +02:00
committed by GitHub
parent d347632046
commit af39dcfb09

View File

@@ -185,32 +185,40 @@ bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol,
return false;
NSString* protocol_ns = [NSString stringWithUTF8String:protocol.c_str()];
CFStringRef protocol_cf = base::apple::NSToCFPtrCast(protocol_ns);
// TODO(codebytere): Use -[NSWorkspace URLForApplicationToOpenURL:] instead
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
CFArrayRef bundleList = LSCopyAllHandlersForURLScheme(protocol_cf);
#pragma clang diagnostic pop
if (!bundleList) {
NSURL* protocol_url =
[NSURL URLWithString:[protocol_ns stringByAppendingString:@":"]];
if (!protocol_url)
return false;
}
// On macOS, we can't query the default, but the handlers list seems to put
// Apple's defaults first, so we'll use the first option that isn't our bundle
CFStringRef other = nil;
for (CFIndex i = 0; i < CFArrayGetCount(bundleList); ++i) {
other =
base::apple::CFCast<CFStringRef>(CFArrayGetValueAtIndex(bundleList, i));
if (![identifier isEqualToString:(__bridge NSString*)other]) {
// Get all applications that can handle this URL scheme.
NSArray<NSURL*>* app_urls =
[[NSWorkspace sharedWorkspace] URLsForApplicationsToOpenURL:protocol_url];
if (app_urls.count == 0)
return false;
// Find the first application that isn't our bundle.
NSString* other_bundle_id = nil;
for (NSURL* app_url in app_urls) {
NSBundle* app_bundle = [NSBundle bundleWithURL:app_url];
NSString* app_identifier = [app_bundle bundleIdentifier];
if (app_identifier && ![identifier isEqualToString:app_identifier]) {
other_bundle_id = app_identifier;
break;
}
}
// No other app was found set it to none instead of setting it back to itself.
if ([identifier isEqualToString:(__bridge NSString*)other]) {
other = base::apple::NSToCFPtrCast(@"None");
// No other app was found, set it to none instead of setting it back to
// itself.
if (!other_bundle_id) {
other_bundle_id = @"None";
}
OSStatus return_code = LSSetDefaultHandlerForURLScheme(protocol_cf, other);
OSStatus return_code = LSSetDefaultHandlerForURLScheme(
base::apple::NSToCFPtrCast(protocol_ns),
base::apple::NSToCFPtrCast(other_bundle_id));
return return_code == noErr;
}
@@ -240,21 +248,28 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol,
return false;
NSString* protocol_ns = [NSString stringWithUTF8String:protocol.c_str()];
NSURL* protocol_url =
[NSURL URLWithString:[protocol_ns stringByAppendingString:@":"]];
// TODO(codebytere): Use -[NSWorkspace URLForApplicationToOpenURL:] instead
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
base::apple::ScopedCFTypeRef<CFStringRef> bundleId(
LSCopyDefaultHandlerForURLScheme(
base::apple::NSToCFPtrCast(protocol_ns)));
#pragma clang diagnostic pop
if (!bundleId)
if (!protocol_url)
return false;
NSURL* default_app_url =
[[NSWorkspace sharedWorkspace] URLForApplicationToOpenURL:protocol_url];
if (!default_app_url)
return false;
NSBundle* default_app_bundle = [NSBundle bundleWithURL:default_app_url];
NSString* default_bundle_id = [default_app_bundle bundleIdentifier];
if (!default_bundle_id)
return false;
// Ensure the comparison is case-insensitive
// as LS does not persist the case of the bundle id.
NSComparisonResult result = [base::apple::CFToNSPtrCast(bundleId.get())
caseInsensitiveCompare:identifier];
// as bundle IDs should be compared case-insensitively
NSComparisonResult result =
[default_bundle_id caseInsensitiveCompare:identifier];
return result == NSOrderedSame;
}