1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#import <CoreFoundation/CoreFoundation.h>
6#import <ApplicationServices/ApplicationServices.h>
7
8#include "nsObjCExceptions.h"
9#include "nsLocalHandlerAppMac.h"
10#include "nsILocalFileMac.h"
11#include "nsIURI.h"
12
13// We override this to make sure app bundles display their pretty name (without .app suffix)
14NS_IMETHODIMP nsLocalHandlerAppMac::GetName(nsAString& aName)
15{
16  if (mExecutable) {
17    nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(mExecutable);
18    if (macFile) {
19      bool isPackage;
20      (void)macFile->IsPackage(&isPackage);
21      if (isPackage)
22        return macFile->GetBundleDisplayName(aName);
23    }
24  }
25
26  return nsLocalHandlerApp::GetName(aName);
27}
28
29/**
30 * mostly copy/pasted from nsMacShellService.cpp (which is in browser/,
31 * so we can't depend on it here).  This code probably really wants to live
32 * somewhere more central (see bug 389922).
33 */
34NS_IMETHODIMP
35nsLocalHandlerAppMac::LaunchWithURI(nsIURI *aURI,
36                                    nsIInterfaceRequestor *aWindowContext)
37{
38  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
39
40  nsresult rv;
41  nsCOMPtr<nsILocalFileMac> lfm(do_QueryInterface(mExecutable, &rv));
42  NS_ENSURE_SUCCESS(rv, rv);
43
44  CFURLRef appURL;
45  rv = lfm->GetCFURL(&appURL);
46  if (NS_FAILED(rv))
47    return rv;
48
49  nsAutoCString uriSpec;
50  aURI->GetAsciiSpec(uriSpec);
51
52  const UInt8* uriString = reinterpret_cast<const UInt8*>(uriSpec.get());
53  CFURLRef uri = ::CFURLCreateWithBytes(NULL, uriString, uriSpec.Length(),
54                                        kCFStringEncodingUTF8, NULL);
55  if (!uri) {
56    ::CFRelease(appURL);
57    return NS_ERROR_OUT_OF_MEMORY;
58  }
59
60  CFArrayRef uris = ::CFArrayCreate(NULL, reinterpret_cast<const void**>(&uri),
61                                    1, NULL);
62  if (!uris) {
63    ::CFRelease(uri);
64    ::CFRelease(appURL);
65    return NS_ERROR_OUT_OF_MEMORY;
66  }
67
68  LSLaunchURLSpec launchSpec;
69  launchSpec.appURL = appURL;
70  launchSpec.itemURLs = uris;
71  launchSpec.passThruParams = NULL;
72  launchSpec.launchFlags = kLSLaunchDefaults;
73  launchSpec.asyncRefCon = NULL;
74
75  OSErr err = ::LSOpenFromURLSpec(&launchSpec, NULL);
76
77  ::CFRelease(uris);
78  ::CFRelease(uri);
79  ::CFRelease(appURL);
80
81  return err != noErr ? NS_ERROR_FAILURE : NS_OK;
82
83  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
84}
85