зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1867080 - Implemented macOS functionality to find all other installed applications which support a protocol r=mhughes
Differential Revision: https://phabricator.services.mozilla.com/D195203
This commit is contained in:
Родитель
b4f96b0521
Коммит
41a15ef193
|
@ -24,4 +24,19 @@ interface nsIMacShellService : nsIShellService
|
|||
* * Privacy_Microphone
|
||||
*/
|
||||
void showSecurityPreferences(in ACString aPaneID);
|
||||
|
||||
/*
|
||||
* Searches for any available handlers for the given protocol and returns them in an
|
||||
* array in the form [[displayName1, handlerPath1], [displayName2, handlerPath2], etc.]
|
||||
* Can return an empty array if no handlers are found.
|
||||
*
|
||||
* @param protocol The protocol to search for handlers for (e.g. "http", "mailto" etc.)
|
||||
* @return The full list of handler paths and names.
|
||||
*
|
||||
* @throws NS_ERROR_ILLEGAL_VALUE if the protocol cannot be resolved as a string.
|
||||
* @throws NS_ERROR_MALFORMED_URI if the protocol cannot be resolved to a URI.
|
||||
* @throws NS_ERROR_NOT_AVAILABLE if a list of handlers fails to generate.
|
||||
*/
|
||||
|
||||
Array<Array<AString> > getAvailableApplicationsForProtocol(in ACString protocol);
|
||||
};
|
||||
|
|
|
@ -277,3 +277,70 @@ nsMacShellService::ShowSecurityPreferences(const nsACString& aPaneID) {
|
|||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsString ConvertCFStringToNSString(CFStringRef aSrc) {
|
||||
nsString aDest;
|
||||
auto len = ::CFStringGetLength(aSrc);
|
||||
aDest.SetLength(len);
|
||||
::CFStringGetCharacters(aSrc, ::CFRangeMake(0, len),
|
||||
(UniChar*)aDest.BeginWriting());
|
||||
return aDest;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacShellService::GetAvailableApplicationsForProtocol(
|
||||
const nsACString& protocol, nsTArray<nsTArray<nsString>>& aHandlerPaths) {
|
||||
class CFTypeRefAutoDeleter {
|
||||
public:
|
||||
CFTypeRefAutoDeleter(CFTypeRef ref) : mRef(ref) {}
|
||||
~CFTypeRefAutoDeleter() {
|
||||
if (mRef != NULL) ::CFRelease(mRef);
|
||||
}
|
||||
|
||||
private:
|
||||
CFTypeRef mRef;
|
||||
};
|
||||
|
||||
aHandlerPaths.Clear();
|
||||
nsCString protocolSep = protocol + "://"_ns;
|
||||
CFStringRef cfProtocol = ::CFStringCreateWithBytes(
|
||||
kCFAllocatorDefault, (const UInt8*)protocolSep.BeginReading(),
|
||||
protocolSep.Length(), kCFStringEncodingUTF8, false);
|
||||
CFTypeRefAutoDeleter cfProtocolAuto(cfProtocol);
|
||||
if (cfProtocol == NULL) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
CFURLRef protocolURL =
|
||||
::CFURLCreateWithString(kCFAllocatorDefault, cfProtocol, NULL);
|
||||
CFTypeRefAutoDeleter cfProtocolURLAuto(protocolURL);
|
||||
if (protocolURL == NULL) {
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
}
|
||||
CFArrayRef appURLs = ::LSCopyApplicationURLsForURL(protocolURL, kLSRolesAll);
|
||||
CFTypeRefAutoDeleter cfAppURLsAuto(appURLs);
|
||||
if (appURLs == NULL) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
for (CFIndex i = 0; i < ::CFArrayGetCount(appURLs); i++) {
|
||||
CFURLRef appURL = (CFURLRef)::CFArrayGetValueAtIndex(appURLs, i);
|
||||
CFBundleRef appBundle = ::CFBundleCreate(kCFAllocatorDefault, appURL);
|
||||
CFTypeRefAutoDeleter cfAppBundleAuto(appBundle);
|
||||
if (appBundle == NULL) {
|
||||
continue;
|
||||
}
|
||||
CFDictionaryRef appInfo = ::CFBundleGetInfoDictionary(appBundle);
|
||||
if (appInfo == NULL) {
|
||||
continue;
|
||||
}
|
||||
CFStringRef displayName =
|
||||
(CFStringRef)::CFDictionaryGetValue(appInfo, kCFBundleNameKey);
|
||||
if (displayName == NULL) {
|
||||
continue;
|
||||
}
|
||||
CFStringRef appPath = ::CFURLGetString(appURL);
|
||||
nsTArray<nsString> handlerPath = {ConvertCFStringToNSString(displayName),
|
||||
ConvertCFStringToNSString(appPath)};
|
||||
aHandlerPaths.AppendElement(handlerPath.Clone());
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче