forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			534 lines
		
	
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			534 lines
		
	
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* ***** BEGIN LICENSE BLOCK *****
 | |
|  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 | |
|  *
 | |
|  * The contents of this file are subject to the Mozilla Public License Version
 | |
|  * 1.1 (the "License"); you may not use this file except in compliance with
 | |
|  * the License. You may obtain a copy of the License at
 | |
|  * http://www.mozilla.org/MPL/
 | |
|  *
 | |
|  * Software distributed under the License is distributed on an "AS IS" basis,
 | |
|  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 | |
|  * for the specific language governing rights and limitations under the
 | |
|  * License.
 | |
|  *
 | |
|  * The Original Code is Shell Service.
 | |
|  *
 | |
|  * The Initial Developer of the Original Code is Ben Goodger.
 | |
|  * Portions created by the Initial Developer are Copyright (C) 2004
 | |
|  * the Initial Developer. All Rights Reserved.
 | |
|  *
 | |
|  * Contributor(s):
 | |
|  *   Ben Goodger <ben@mozilla.org> (Original Author)
 | |
|  *   Asaf Romano <mozilla.mano@sent.com>
 | |
|  *   Benjamin Smedberg <benjamin@smedbergs.us>
 | |
|  *
 | |
|  * Alternatively, the contents of this file may be used under the terms of
 | |
|  * either the GNU General Public License Version 2 or later (the "GPL"), or
 | |
|  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 | |
|  * in which case the provisions of the GPL or the LGPL are applicable instead
 | |
|  * of those above. If you wish to allow use of your version of this file only
 | |
|  * under the terms of either the GPL or the LGPL, and not to allow others to
 | |
|  * use your version of this file under the terms of the MPL, indicate your
 | |
|  * decision by deleting the provisions above and replace them with the notice
 | |
|  * and other provisions required by the GPL or the LGPL. If you do not delete
 | |
|  * the provisions above, a recipient may use your version of this file under
 | |
|  * the terms of any one of the MPL, the GPL or the LGPL.
 | |
|  *
 | |
|  * ***** END LICENSE BLOCK ***** */
 | |
| 
 | |
| #include "nsDirectoryServiceDefs.h"
 | |
| #include "nsIDOMElement.h"
 | |
| #include "nsIDOMHTMLImageElement.h"
 | |
| #include "nsIImageLoadingContent.h"
 | |
| #include "nsIDocument.h"
 | |
| #include "nsIContent.h"
 | |
| #include "nsILocalFileMac.h"
 | |
| #include "nsIObserverService.h"
 | |
| #include "nsIPrefService.h"
 | |
| #include "nsIServiceManager.h"
 | |
| #include "nsIStringBundle.h"
 | |
| #include "nsIURL.h"
 | |
| #include "nsIWebBrowserPersist.h"
 | |
| #include "nsMacShellService.h"
 | |
| #include "nsNetUtil.h"
 | |
| #include "nsShellService.h"
 | |
| #include "nsStringAPI.h"
 | |
| 
 | |
| #include <CoreFoundation/CoreFoundation.h>
 | |
| #include <Carbon/Carbon.h>
 | |
| 
 | |
| #define NETWORK_PREFPANE NS_LITERAL_CSTRING("/System/Library/PreferencePanes/Network.prefPane")
 | |
| #define DESKTOP_PREFPANE NS_LITERAL_CSTRING("/System/Library/PreferencePanes/DesktopScreenEffectsPref.prefPane")
 | |
| 
 | |
| #define SAFARI_BUNDLE_IDENTIFIER NS_LITERAL_CSTRING("com.apple.Safari")
 | |
| 
 | |
| // These Launch Services functions are undocumented. We're using them since they're
 | |
| // the only way to set the default opener for URLs / file extensions.
 | |
| extern "C" {
 | |
|   // Returns the CFURL for application currently set as the default opener for the
 | |
|   // given URL scheme. appURL must be released by the caller.
 | |
|   extern OSStatus _LSCopyDefaultSchemeHandlerURL(CFStringRef scheme, CFURLRef *appURL);
 | |
|   extern OSStatus _LSSetDefaultSchemeHandlerURL(CFStringRef scheme, CFURLRef appURL);
 | |
|   extern OSStatus _LSSaveAndRefresh(void);
 | |
|   // Callers should pass 0 as both inType and inCreator in order to set the default opener
 | |
|   // without modifing those.
 | |
|   extern OSStatus _LSSetWeakBindingForType(OSType inType,
 | |
|                                            OSType inCreator,
 | |
|                                            CFStringRef inExtension,
 | |
|                                            LSRolesMask inRoleMask,
 | |
|                                            const FSRef* inBindingRef);
 | |
| }
 | |
| 
 | |
| NS_IMPL_ISUPPORTS3(nsMacShellService, nsIMacShellService, nsIShellService, nsIWebProgressListener)
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::IsDefaultBrowser(PRBool aStartupCheck, PRBool* aIsDefaultBrowser)
 | |
| {
 | |
|   *aIsDefaultBrowser = PR_TRUE;
 | |
| 
 | |
|   // Since neither Launch Services nor Internet Config actually differ between 
 | |
|   // bundles which have the same bundle identifier (That is, if we set our
 | |
|   // bundle's URL as the default handler, Launch Service might return the
 | |
|   // URL of another firefox bundle as the defualt http handler), we are
 | |
|   // comparing the bundles' identifiers rather than their URLs.
 | |
| 
 | |
|   CFStringRef firefoxID = ::CFBundleGetIdentifier(CFBundleGetMainBundle());
 | |
|   if (!firefoxID) {
 | |
|     // CFBundleGetIdentifier is expected to return NULL only if the specified
 | |
|     // bundle doesn't have a bundle identifier in its plist. In this case, that
 | |
|     // means a failure, since our bundle does have an identifier.
 | |
|     return NS_ERROR_FAILURE;
 | |
|   }
 | |
| 
 | |
|   ::CFRetain(firefoxID);
 | |
| 
 | |
|   // Get the default http handler URL
 | |
|   CFURLRef defaultBrowserURL;
 | |
|   OSStatus err = ::_LSCopyDefaultSchemeHandlerURL(CFSTR("http"),
 | |
|                                                   &defaultBrowserURL);
 | |
| 
 | |
|   nsresult rv = NS_ERROR_FAILURE;
 | |
|   if (err == noErr) {
 | |
|     // Get a reference to the bundle (based on its URL)
 | |
|     CFBundleRef defaultBrowserBundle = ::CFBundleCreate(NULL, 
 | |
|                                                         defaultBrowserURL);
 | |
|     if (defaultBrowserBundle) {
 | |
|       CFStringRef defaultBrowserID = ::CFBundleGetIdentifier(defaultBrowserBundle);
 | |
|       if (defaultBrowserID) {
 | |
|         ::CFRetain(defaultBrowserID);
 | |
|         // and compare it to our bundle identifier
 | |
|         *aIsDefaultBrowser = ::CFStringCompare(firefoxID, defaultBrowserID, 0)
 | |
|                              == kCFCompareEqualTo;
 | |
|         ::CFRelease(defaultBrowserID);
 | |
|       }
 | |
|       else {
 | |
|         // If the default browser bundle doesn't have an identifier in its plist,
 | |
|         // it's not our bundle
 | |
|         *aIsDefaultBrowser = PR_FALSE;
 | |
|       }
 | |
| 
 | |
|       ::CFRelease(defaultBrowserBundle);
 | |
|       rv = NS_OK;
 | |
|     }
 | |
| 
 | |
|     ::CFRelease(defaultBrowserURL);
 | |
|   }
 | |
| 
 | |
|   // release the idetifiers strings
 | |
|   ::CFRelease(firefoxID);
 | |
| 
 | |
|   // If this is the first browser window, maintain internal state that we've
 | |
|   // checked this session (so that subsequent window opens don't show the 
 | |
|   // default browser dialog).
 | |
|   if (aStartupCheck)
 | |
|     mCheckedThisSession = PR_TRUE;
 | |
| 
 | |
|   return rv;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUsers)
 | |
| {
 | |
|   // Note: We don't support aForAllUsers on Mac OS X.
 | |
| 
 | |
|   CFURLRef firefoxURL = ::CFBundleCopyBundleURL(CFBundleGetMainBundle());
 | |
| 
 | |
|   ::_LSSetDefaultSchemeHandlerURL(CFSTR("http"), firefoxURL);
 | |
|   ::_LSSetDefaultSchemeHandlerURL(CFSTR("https"), firefoxURL);
 | |
| 
 | |
|   if (aClaimAllTypes) {
 | |
|     ::_LSSetDefaultSchemeHandlerURL(CFSTR("ftp"), firefoxURL);
 | |
| 
 | |
|     FSRef firefoxFSRef;
 | |
|     // CFURLGetFSRef returns true if the conversion was successful 
 | |
|     if (::CFURLGetFSRef(firefoxURL, &firefoxFSRef)); {
 | |
|       // Set the default opener for html/htm files
 | |
|       ::_LSSetWeakBindingForType(0, 0, CFSTR("html"), kLSRolesAll, &firefoxFSRef);
 | |
|       ::_LSSetWeakBindingForType(0, 0, CFSTR("htm"), kLSRolesAll, &firefoxFSRef);
 | |
|     }
 | |
|   }
 | |
|   ::_LSSaveAndRefresh();
 | |
| 
 | |
|   ::CFRelease(firefoxURL);
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::GetShouldCheckDefaultBrowser(PRBool* aResult)
 | |
| {
 | |
|   // If we've already checked, the browser has been started and this is a 
 | |
|   // new window open, and we don't want to check again.
 | |
|   if (mCheckedThisSession) {
 | |
|     *aResult = PR_FALSE;
 | |
|     return NS_OK;
 | |
|   }
 | |
| 
 | |
|   nsCOMPtr<nsIPrefBranch> prefs;
 | |
|   nsCOMPtr<nsIPrefService> pserve(do_GetService(NS_PREFSERVICE_CONTRACTID));
 | |
|   if (pserve)
 | |
|     pserve->GetBranch("", getter_AddRefs(prefs));
 | |
| 
 | |
|   prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult);
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::SetShouldCheckDefaultBrowser(PRBool aShouldCheck)
 | |
| {
 | |
|   nsCOMPtr<nsIPrefBranch> prefs;
 | |
|   nsCOMPtr<nsIPrefService> pserve(do_GetService(NS_PREFSERVICE_CONTRACTID));
 | |
|   if (pserve)
 | |
|     pserve->GetBranch("", getter_AddRefs(prefs));
 | |
| 
 | |
|   prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck);
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::SetDesktopBackground(nsIDOMElement* aElement, 
 | |
|                                         PRInt32 aPosition)
 | |
| {
 | |
|   // Note: We don't support aPosition on OS X.
 | |
| 
 | |
|   // Get the image URI:
 | |
|   nsresult rv;
 | |
|   nsCOMPtr<nsIImageLoadingContent> imageContent = do_QueryInterface(aElement,
 | |
|                                                                     &rv);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
|   nsCOMPtr<nsIURI> imageURI;
 | |
|   rv = imageContent->GetCurrentURI(getter_AddRefs(imageURI));
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   // We need the referer URI for nsIWebBrowserPersist::saveURI
 | |
|   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
|   nsCOMPtr<nsIDocument> doc;
 | |
|   doc = content->GetOwnerDoc();
 | |
|   if (!doc)
 | |
|     return NS_ERROR_FAILURE;
 | |
| 
 | |
|   nsIURI *docURI = doc->GetDocumentURI();
 | |
|   if (!docURI)
 | |
|     return NS_ERROR_FAILURE;
 | |
| 
 | |
|   // Get the desired image file name
 | |
|   nsCOMPtr<nsIURL> imageURL(do_QueryInterface(imageURI));
 | |
|   if (!imageURL) {
 | |
|     // XXXmano (bug 300293): Non-URL images (e.g. the data: protocol) are not
 | |
|     // yet supported. What filename should we take here?
 | |
|     return NS_ERROR_NOT_IMPLEMENTED;
 | |
|   }
 | |
| 
 | |
|   nsCAutoString fileName;
 | |
|   imageURL->GetFileName(fileName);
 | |
|   nsCOMPtr<nsIProperties> fileLocator
 | |
|     (do_GetService("@mozilla.org/file/directory_service;1", &rv));
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   // Get the current user's "Pictures" folder (That's ~/Pictures):
 | |
|   fileLocator->Get(NS_OSX_PICTURE_DOCUMENTS_DIR, NS_GET_IID(nsILocalFile),
 | |
|                    getter_AddRefs(mBackgroundFile));
 | |
|   if (!mBackgroundFile)
 | |
|     return NS_ERROR_OUT_OF_MEMORY;
 | |
| 
 | |
|   nsAutoString fileNameUnicode;
 | |
|   CopyUTF8toUTF16(fileName, fileNameUnicode);
 | |
| 
 | |
|   // and add the imgage file name itself:
 | |
|   mBackgroundFile->Append(fileNameUnicode);
 | |
| 
 | |
|   // Download the image; the desktop background will be set in OnStateChange()
 | |
|   nsCOMPtr<nsIWebBrowserPersist> wbp
 | |
|     (do_CreateInstance("@mozilla.org/embedding/browser/nsWebBrowserPersist;1", &rv));
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   PRUint32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION | 
 | |
|                    nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES |
 | |
|                    nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
 | |
| 
 | |
|   wbp->SetPersistFlags(flags);
 | |
|   wbp->SetProgressListener(this);
 | |
| 
 | |
|   return wbp->SaveURI(imageURI, nsnull, docURI, nsnull, nsnull,
 | |
|                       mBackgroundFile);
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::OnProgressChange(nsIWebProgress* aWebProgress,
 | |
|                                     nsIRequest* aRequest,
 | |
|                                     PRInt32 aCurSelfProgress,
 | |
|                                     PRInt32 aMaxSelfProgress,
 | |
|                                     PRInt32 aCurTotalProgress,
 | |
|                                     PRInt32 aMaxTotalProgress)
 | |
| {
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::OnLocationChange(nsIWebProgress* aWebProgress,
 | |
|                                     nsIRequest* aRequest,
 | |
|                                     nsIURI* aLocation)
 | |
| {
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::OnStatusChange(nsIWebProgress* aWebProgress,
 | |
|                                   nsIRequest* aRequest,
 | |
|                                   nsresult aStatus,
 | |
|                                   const PRUnichar* aMessage)
 | |
| {
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::OnSecurityChange(nsIWebProgress* aWebProgress,
 | |
|                                     nsIRequest* aRequest,
 | |
|                                     PRUint32 aState)
 | |
| {
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::OnStateChange(nsIWebProgress* aWebProgress,
 | |
|                                  nsIRequest* aRequest,
 | |
|                                  PRUint32 aStateFlags,
 | |
|                                  nsresult aStatus)
 | |
| {
 | |
|   if (aStateFlags & STATE_STOP) {
 | |
|     nsCOMPtr<nsIObserverService> os(do_GetService("@mozilla.org/observer-service;1"));
 | |
|     if (os)
 | |
|       os->NotifyObservers(nsnull, "shell:desktop-background-changed", nsnull);
 | |
| 
 | |
|     PRBool exists = PR_FALSE;
 | |
|     mBackgroundFile->Exists(&exists);
 | |
|     if (!exists)
 | |
|       return NS_OK;
 | |
| 
 | |
|     nsCAutoString nativePath;
 | |
|     mBackgroundFile->GetNativePath(nativePath);
 | |
| 
 | |
|     AEDesc tAEDesc = { typeNull, nil };
 | |
|     OSErr err = noErr;
 | |
|     AliasHandle aliasHandle = nil;
 | |
|     FSRef pictureRef;
 | |
|     OSStatus status;
 | |
| 
 | |
|     // Convert the path into a FSRef
 | |
|     status = ::FSPathMakeRef((const UInt8*)nativePath.get(), &pictureRef, NULL);
 | |
|     if (status == noErr) {
 | |
|       err = ::FSNewAlias(nil, &pictureRef, &aliasHandle);
 | |
|       if (err == noErr && aliasHandle == nil)
 | |
|         err = paramErr;
 | |
| 
 | |
|       if (err == noErr) {
 | |
|         // We need the descriptor (based on the picture file reference)
 | |
|         // for the 'Set Desktop Picture' apple event.
 | |
|         char handleState = ::HGetState((Handle)aliasHandle);
 | |
|         ::HLock((Handle)aliasHandle);
 | |
|         err = ::AECreateDesc(typeAlias, *aliasHandle,
 | |
|                              GetHandleSize((Handle)aliasHandle), &tAEDesc);
 | |
|         // unlock the alias handler
 | |
|         ::HSetState((Handle)aliasHandle, handleState);
 | |
|         ::DisposeHandle((Handle)aliasHandle);
 | |
|       }
 | |
|       if (err == noErr) {
 | |
|         AppleEvent tAppleEvent;
 | |
|         OSType sig = 'MACS';
 | |
|         AEBuildError tAEBuildError;
 | |
|         // Create a 'Set Desktop Pictue' Apple Event
 | |
|         err = ::AEBuildAppleEvent(kAECoreSuite, kAESetData, typeApplSignature,
 | |
|                                   &sig, sizeof(OSType), kAutoGenerateReturnID,
 | |
|                                   kAnyTransactionID, &tAppleEvent, &tAEBuildError,
 | |
|                                   "'----':'obj '{want:type (prop),form:prop" \
 | |
|                                   ",seld:type('dpic'),from:'null'()},data:(@)",
 | |
|                                   &tAEDesc);
 | |
|         if (err == noErr) {
 | |
|           AppleEvent reply = { typeNull, nil };
 | |
|           // Sent the event we built, the reply event isn't necessary
 | |
|           err = ::AESend(&tAppleEvent, &reply, kAENoReply, kAENormalPriority,
 | |
|                          kNoTimeOut, nil, nil);
 | |
|           ::AEDisposeDesc(&tAppleEvent);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::OpenApplication(PRInt32 aApplication)
 | |
| {
 | |
|   nsresult rv = NS_OK;
 | |
|   CFURLRef appURL = nil;
 | |
|   OSStatus err = noErr;
 | |
| 
 | |
|   switch (aApplication) {
 | |
|   case nsIShellService::APPLICATION_MAIL:
 | |
|     {
 | |
|       CFURLRef tempURL = ::CFURLCreateWithString(kCFAllocatorDefault,
 | |
|                                                  CFSTR("mailto:"), NULL);
 | |
|       err = ::LSGetApplicationForURL(tempURL, kLSRolesAll, NULL, &appURL);
 | |
|       ::CFRelease(tempURL);
 | |
|     }
 | |
|     break;
 | |
|   case nsIShellService::APPLICATION_NEWS:
 | |
|     {
 | |
|       CFURLRef tempURL = ::CFURLCreateWithString(kCFAllocatorDefault,
 | |
|                                                  CFSTR("news:"), NULL);
 | |
|       err = ::LSGetApplicationForURL(tempURL, kLSRolesAll, NULL, &appURL);
 | |
|       ::CFRelease(tempURL);
 | |
|     }
 | |
|     break;
 | |
|   case nsIMacShellService::APPLICATION_KEYCHAIN_ACCESS:
 | |
|     err = ::LSGetApplicationForInfo('APPL', 'kcmr', NULL, kLSRolesAll, NULL,
 | |
|                                     &appURL);
 | |
|     break;
 | |
|   case nsIMacShellService::APPLICATION_NETWORK:
 | |
|     {
 | |
|       nsCOMPtr<nsILocalFile> lf;
 | |
|       rv = NS_NewNativeLocalFile(NETWORK_PREFPANE, PR_TRUE, getter_AddRefs(lf));
 | |
|       NS_ENSURE_SUCCESS(rv, rv);
 | |
|       PRBool exists;
 | |
|       lf->Exists(&exists);
 | |
|       if (!exists)
 | |
|         return NS_ERROR_FILE_NOT_FOUND;
 | |
|       return lf->Launch();
 | |
|     }  
 | |
|     break;
 | |
|   case nsIMacShellService::APPLICATION_DESKTOP:
 | |
|     {
 | |
|       nsCOMPtr<nsILocalFile> lf;
 | |
|       rv = NS_NewNativeLocalFile(DESKTOP_PREFPANE, PR_TRUE, getter_AddRefs(lf));
 | |
|       NS_ENSURE_SUCCESS(rv, rv);
 | |
|       PRBool exists;
 | |
|       lf->Exists(&exists);
 | |
|       if (!exists)
 | |
|         return NS_ERROR_FILE_NOT_FOUND;
 | |
|       return lf->Launch();
 | |
|     }  
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   if (appURL && err == noErr) {
 | |
|     err = ::LSOpenCFURLRef(appURL, NULL);
 | |
|     rv = err != noErr ? NS_ERROR_FAILURE : NS_OK;
 | |
| 
 | |
|     ::CFRelease(appURL);
 | |
|   }
 | |
| 
 | |
|   return rv;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::GetDesktopBackgroundColor(PRUint32 *aColor)
 | |
| {
 | |
|   // This method and |SetDesktopBackgroundColor| has no meaning on Mac OS X.
 | |
|   // The mac desktop preferences UI uses pictures for the few solid colors it
 | |
|   // supports.
 | |
|   return NS_ERROR_NOT_IMPLEMENTED;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::SetDesktopBackgroundColor(PRUint32 aColor)
 | |
| {
 | |
|   // This method and |GetDesktopBackgroundColor| has no meaning on Mac OS X.
 | |
|   // The mac desktop preferences UI uses pictures for the few solid colors it
 | |
|   // supports.
 | |
|   return NS_ERROR_NOT_IMPLEMENTED;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::OpenApplicationWithURI(nsILocalFile* aApplication, const nsACString& aURI)
 | |
| {
 | |
|   nsCOMPtr<nsILocalFileMac> lfm(do_QueryInterface(aApplication));
 | |
|   CFURLRef appURL;
 | |
|   nsresult rv = lfm->GetCFURL(&appURL);
 | |
|   if (NS_FAILED(rv))
 | |
|     return rv;
 | |
|   
 | |
|   const nsCString spec(aURI);
 | |
|   const UInt8* uriString = (const UInt8*)spec.get();
 | |
|   CFURLRef uri = ::CFURLCreateWithBytes(NULL, uriString, aURI.Length(),
 | |
|                                         kCFStringEncodingUTF8, NULL);
 | |
|   if (!uri) 
 | |
|     return NS_ERROR_OUT_OF_MEMORY;
 | |
|   
 | |
|   CFArrayRef uris = ::CFArrayCreate(NULL, (const void**)&uri, 1, NULL);
 | |
|   if (!uris) {
 | |
|     ::CFRelease(uri);
 | |
|     return NS_ERROR_OUT_OF_MEMORY;
 | |
|   }
 | |
|   
 | |
|   LSLaunchURLSpec launchSpec;
 | |
|   launchSpec.appURL = appURL;
 | |
|   launchSpec.itemURLs = uris;
 | |
|   launchSpec.passThruParams = NULL;
 | |
|   launchSpec.launchFlags = kLSLaunchDefaults;
 | |
|   launchSpec.asyncRefCon = NULL;
 | |
|   
 | |
|   OSErr err = ::LSOpenFromURLSpec(&launchSpec, NULL);
 | |
|   
 | |
|   ::CFRelease(uris);
 | |
|   ::CFRelease(uri);
 | |
|   
 | |
|   return err != noErr ? NS_ERROR_FAILURE : NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsMacShellService::GetDefaultFeedReader(nsILocalFile** _retval)
 | |
| {
 | |
|   nsresult rv = NS_ERROR_FAILURE;
 | |
|   *_retval = nsnull;
 | |
| 
 | |
|   CFURLRef defaultHandlerURL;
 | |
|   OSStatus err = ::_LSCopyDefaultSchemeHandlerURL(CFSTR("feed"),
 | |
|                                                   &defaultHandlerURL);
 | |
|   if (defaultHandlerURL) {
 | |
|     nsCOMPtr<nsILocalFileMac> defaultReader =
 | |
|       do_CreateInstance("@mozilla.org/file/local;1", &rv);
 | |
|     if (NS_SUCCEEDED(rv)) {
 | |
|       rv = defaultReader->InitWithCFURL(defaultHandlerURL);
 | |
|       if (NS_SUCCEEDED(rv)) {
 | |
|         // ASSERT("Safari Is Not a Feed Reader");
 | |
|         nsCAutoString bundleIdentifier;
 | |
| 
 | |
|         // don't throw if the bundle has no identifier
 | |
|         rv = NS_ERROR_FAILURE;
 | |
|         if (NS_FAILED(defaultReader->GetBundleIdentifier(bundleIdentifier)) ||
 | |
|             !bundleIdentifier.Equals(SAFARI_BUNDLE_IDENTIFIER)) {
 | |
|           NS_ADDREF(*_retval = defaultReader);
 | |
|           rv = NS_OK;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     ::CFRelease(defaultHandlerURL);
 | |
|   }
 | |
| 
 | |
|   return rv;
 | |
| }
 | 
