diff --git a/shell/browser/browser_mac.mm b/shell/browser/browser_mac.mm index 1a78da0a65..dd521ebb0d 100644 --- a/shell/browser/browser_mac.mm +++ b/shell/browser/browser_mac.mm @@ -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(CFArrayGetValueAtIndex(bundleList, i)); - if (![identifier isEqualToString:(__bridge NSString*)other]) { + + // Get all applications that can handle this URL scheme. + NSArray* 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 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; }