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  if (mExecutable) {
16    nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(mExecutable);
17    if (macFile) {
18      bool isPackage;
19      (void)macFile->IsPackage(&isPackage);
20      if (isPackage) return macFile->GetBundleDisplayName(aName);
21    }
22  }
23
24  return nsLocalHandlerApp::GetName(aName);
25}
26
27/**
28 * mostly copy/pasted from nsMacShellService.cpp (which is in browser/,
29 * so we can't depend on it here).  This code probably really wants to live
30 * somewhere more central (see bug 389922).
31 */
32NS_IMETHODIMP
33nsLocalHandlerAppMac::LaunchWithURI(nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) {
34  NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
35
36  nsresult rv;
37  nsCOMPtr<nsILocalFileMac> lfm(do_QueryInterface(mExecutable, &rv));
38  NS_ENSURE_SUCCESS(rv, rv);
39
40  CFURLRef appURL;
41  rv = lfm->GetCFURL(&appURL);
42  if (NS_FAILED(rv)) return rv;
43
44  nsAutoCString uriSpec;
45  aURI->GetAsciiSpec(uriSpec);
46
47  const UInt8* uriString = reinterpret_cast<const UInt8*>(uriSpec.get());
48  CFURLRef uri =
49      ::CFURLCreateWithBytes(NULL, uriString, uriSpec.Length(), kCFStringEncodingUTF8, NULL);
50  if (!uri) {
51    ::CFRelease(appURL);
52    return NS_ERROR_OUT_OF_MEMORY;
53  }
54
55  CFArrayRef uris = ::CFArrayCreate(NULL, reinterpret_cast<const void**>(&uri), 1, NULL);
56  if (!uris) {
57    ::CFRelease(uri);
58    ::CFRelease(appURL);
59    return NS_ERROR_OUT_OF_MEMORY;
60  }
61
62  LSLaunchURLSpec launchSpec;
63  launchSpec.appURL = appURL;
64  launchSpec.itemURLs = uris;
65  launchSpec.passThruParams = NULL;
66  launchSpec.launchFlags = kLSLaunchDefaults;
67  launchSpec.asyncRefCon = NULL;
68
69  OSErr err = ::LSOpenFromURLSpec(&launchSpec, NULL);
70
71  ::CFRelease(uris);
72  ::CFRelease(uri);
73  ::CFRelease(appURL);
74
75  return err != noErr ? NS_ERROR_FAILURE : NS_OK;
76
77  NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
78}
79