Bug 756308. Implement MacWebAppUtils to allow callers to locate and manipulate native webapps on Mac. r=josh
authorDan Walkowski <dwalkowski@mozilla.com>
Wed, 20 Jun 2012 17:19:13 -0700
changeset 99936 50cd7af728914f5b52299a3332d8e70dcbe0b191
parent 99935 d047caf12f049233ef030514367839c7209e5b91
child 99937 99038d3c6360cc893fa613cf9c26706f9cd53400
push id1729
push userlsblakk@mozilla.com
push dateMon, 16 Jul 2012 20:02:43 +0000
treeherdermozilla-aurora@f4e75e148951 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjosh
bugs756308
milestone16.0a1
Bug 756308. Implement MacWebAppUtils to allow callers to locate and manipulate native webapps on Mac. r=josh
widget/Makefile.in
widget/cocoa/Makefile.in
widget/cocoa/nsMacWebAppUtils.h
widget/cocoa/nsMacWebAppUtils.mm
widget/cocoa/nsWidgetFactory.mm
widget/nsIMacWebAppUtils.idl
widget/nsWidgetsCID.h
widget/tests/unit/test_macwebapputils.js
widget/tests/unit/xpcshell.ini
--- a/widget/Makefile.in
+++ b/widget/Makefile.in
@@ -138,16 +138,17 @@ XPIDLSRCS	+= nsIPrintSettingsWin.idl \
 		nsIJumpListBuilder.idl \
 		nsIJumpListItem.idl \
 		$(NULL)
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
 XPIDLSRCS +=	nsIMacDockSupport.idl \
 		nsIStandaloneNativeMenu.idl \
+		nsIMacWebAppUtils.idl \
 		$(NULL)
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
 XPIDLSRCS	+= nsIRwsService.idl
 endif
 
 EXPORTS		:= $(addprefix $(srcdir)/, $(EXPORTS))
--- a/widget/cocoa/Makefile.in
+++ b/widget/cocoa/Makefile.in
@@ -57,16 +57,17 @@ CMMSRCS = \
   nsDeviceContextSpecX.mm \
   nsPrintDialogX.mm \
   nsPrintOptionsX.mm \
   nsPrintSettingsX.mm \
   nsIdleServiceX.mm \
   TextInputHandler.mm \
   nsMacDockSupport.mm \
   nsStandaloneNativeMenu.mm \
+  nsMacWebAppUtils.mm \
   GfxInfo.mm \
   WidgetTraceEvent.mm \
   $(NULL)
 
 ifeq (x86_64,$(TARGET_CPU))
 CMMSRCS += ComplexTextInputPanel.mm
 endif
 
new file mode 100644
--- /dev/null
+++ b/widget/cocoa/nsMacWebAppUtils.h
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef _MAC_WEB_APP_UTILS_H_
+#define _MAC_WEB_APP_UTILS_H_
+
+#include "nsIMacWebAppUtils.h"
+
+#define NS_MACWEBAPPUTILS_CONTRACTID "@mozilla.org/widget/mac-web-app-utils;1"
+#define NS_MACWEBAPPUTILS_COMPONENT_CLASSNAME "Mac Web Application Utils"
+
+class nsMacWebAppUtils : public nsIMacWebAppUtils {
+public:
+  nsMacWebAppUtils() {}
+  virtual ~nsMacWebAppUtils() {}
+  
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIMACWEBAPPUTILS
+};
+
+#endif //_MAC_WEB_APP_UTILS_H_
new file mode 100644
--- /dev/null
+++ b/widget/cocoa/nsMacWebAppUtils.mm
@@ -0,0 +1,39 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#import <Cocoa/Cocoa.h>
+
+#include "nsMacWebAppUtils.h"
+#include "nsObjCExceptions.h"
+#include "nsCOMPtr.h"
+#include "nsCocoaUtils.h"
+#include "nsString.h"
+
+// Find the path to the app with the given bundleIdentifier, if any.
+// Note that the OS will return the path to the newest binary, if there is more than one.
+// The determination of 'newest' is complex and beyond the scope of this comment.
+
+NS_IMPL_ISUPPORTS1(nsMacWebAppUtils, nsIMacWebAppUtils)
+
+NS_IMETHODIMP nsMacWebAppUtils::PathForAppWithIdentifier(const nsAString& bundleIdentifier, nsAString& outPath) {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+  outPath.Truncate();
+
+  NSAutoreleasePool* ap = [[NSAutoreleasePool alloc] init];
+
+  //note that the result of this expression might be nil, meaning no matching app was found. 
+  NSString* temp = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:
+                        [NSString stringWithCharacters:((nsString)bundleIdentifier).get() length:((nsString)bundleIdentifier).Length()]];
+
+  if (temp) {
+    // Copy out the resultant absolute path into outPath if non-nil.
+    nsCocoaUtils::GetStringForNSString(temp, outPath);
+  }
+
+  [ap release];
+  return NS_OK;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
--- a/widget/cocoa/nsWidgetFactory.mm
+++ b/widget/cocoa/nsWidgetFactory.mm
@@ -57,16 +57,19 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsNativeM
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard)
 
 #include "nsNativeThemeCocoa.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsNativeThemeCocoa)
 
 #include "nsMacDockSupport.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacDockSupport)
 
+#include "nsMacWebAppUtils.h"
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacWebAppUtils)
+
 #include "nsStandaloneNativeMenu.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsStandaloneNativeMenu)
 
 #include "GfxInfo.h"
 namespace mozilla {
 namespace widget {
 // This constructor should really be shared with all platforms.
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(GfxInfo, Init)
@@ -90,16 +93,17 @@ NS_DEFINE_NAMED_CID(NS_THEMERENDERER_CID
 NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID);
 NS_DEFINE_NAMED_CID(NS_DEVICE_CONTEXT_SPEC_CID);
 NS_DEFINE_NAMED_CID(NS_PRINTSESSION_CID);
 NS_DEFINE_NAMED_CID(NS_PRINTSETTINGSSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_PRINTDIALOGSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_IDLE_SERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_NATIVEMENUSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_MACDOCKSUPPORT_CID);
+NS_DEFINE_NAMED_CID(NS_MACWEBAPPUTILS_CID);
 NS_DEFINE_NAMED_CID(NS_STANDALONENATIVEMENU_CID);
 NS_DEFINE_NAMED_CID(NS_GFXINFO_CID);
 
 
 static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
   { &kNS_WINDOW_CID, false, NULL, nsCocoaWindowConstructor },
   { &kNS_POPUP_CID, false, NULL, nsCocoaWindowConstructor },
   { &kNS_CHILD_CID, false, NULL, nsChildViewConstructor },
@@ -116,16 +120,17 @@ static const mozilla::Module::CIDEntry k
   { &kNS_SCREENMANAGER_CID, false, NULL, nsScreenManagerCocoaConstructor },
   { &kNS_DEVICE_CONTEXT_SPEC_CID, false, NULL, nsDeviceContextSpecXConstructor },
   { &kNS_PRINTSESSION_CID, false, NULL, nsPrintSessionConstructor },
   { &kNS_PRINTSETTINGSSERVICE_CID, false, NULL, nsPrintOptionsXConstructor },
   { &kNS_PRINTDIALOGSERVICE_CID, false, NULL, nsPrintDialogServiceXConstructor },
   { &kNS_IDLE_SERVICE_CID, false, NULL, nsIdleServiceXConstructor },
   { &kNS_NATIVEMENUSERVICE_CID, false, NULL, nsNativeMenuServiceXConstructor },
   { &kNS_MACDOCKSUPPORT_CID, false, NULL, nsMacDockSupportConstructor },
+  { &kNS_MACWEBAPPUTILS_CID, false, NULL, nsMacWebAppUtilsConstructor },
   { &kNS_STANDALONENATIVEMENU_CID, false, NULL, nsStandaloneNativeMenuConstructor },
   { &kNS_GFXINFO_CID, false, NULL, mozilla::widget::GfxInfoConstructor },
   { NULL }
 };
 
 static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
   { "@mozilla.org/widgets/window/mac;1", &kNS_WINDOW_CID },
   { "@mozilla.org/widgets/popup/mac;1", &kNS_POPUP_CID },
@@ -143,16 +148,17 @@ static const mozilla::Module::ContractID
   { "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID },
   { "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID },
   { "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID },
   { "@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID },
   { NS_PRINTDIALOGSERVICE_CONTRACTID, &kNS_PRINTDIALOGSERVICE_CID },
   { "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID },
   { "@mozilla.org/widget/nativemenuservice;1", &kNS_NATIVEMENUSERVICE_CID },
   { "@mozilla.org/widget/macdocksupport;1", &kNS_MACDOCKSUPPORT_CID },
+  { "@mozilla.org/widget/mac-web-app-utils;1", &kNS_MACWEBAPPUTILS_CID },
   { "@mozilla.org/widget/standalonenativemenu;1", &kNS_STANDALONENATIVEMENU_CID },
   { "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },
   { NULL }
 };
 
 static void
 nsWidgetCocoaModuleDtor()
 {
new file mode 100644
--- /dev/null
+++ b/widget/nsIMacWebAppUtils.idl
@@ -0,0 +1,20 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsIMacWebAppUtils;
+
+/**
+ * Allow MozApps API to locate and manipulate natively installed apps
+ */
+
+[scriptable, uuid(e9096367-ddd9-45e4-b762-49c0c18b7119)]
+interface nsIMacWebAppUtils : nsISupports {
+  /**
+   * Find the path for an app with the given signature.
+   */
+  AString pathForAppWithIdentifier(in AString bundleIdentifier);
+
+};
--- a/widget/nsWidgetsCID.h
+++ b/widget/nsWidgetsCID.h
@@ -124,16 +124,20 @@
 // {F72C5DC4-5A12-47be-BE28-AB105F33B08F}
 #define NS_WIN_JUMPLISTLINK_CID \
 { 0xf72c5dc4, 0x5a12, 0x47be, { 0xbe, 0x28, 0xab, 0x10, 0x5f, 0x33, 0xb0, 0x8f } }
 
 // {B16656B2-5187-498f-ABF4-56346126BFDB}
 #define NS_WIN_JUMPLISTSHORTCUT_CID \
 { 0xb16656b2, 0x5187, 0x498f, { 0xab, 0xf4, 0x56, 0x34, 0x61, 0x26, 0xbf, 0xdb } }
 
+// {e9096367-ddd9-45e4-b762-49c0c18b7119}
+#define NS_MACWEBAPPUTILS_CID \
+{ 0xe9096367, 0xddd9, 0x45e4, { 0xb7, 0x62, 0x49, 0xc0, 0xc1, 0x8b, 0x71, 0x19 } }
+
 //-----------------------------------------------------------
 //Printing
 //-----------------------------------------------------------
 #define NS_DEVICE_CONTEXT_SPEC_CID \
 { 0xd3f69889, 0xe13a, 0x4321, \
 { 0x98, 0x0c, 0xa3, 0x93, 0x32, 0xe2, 0x1f, 0x34 } }
 
 #define NS_PRINTSETTINGSSERVICE_CID \
new file mode 100644
--- /dev/null
+++ b/widget/tests/unit/test_macwebapputils.js
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+//Basic tests to verify that MacWebAppUtils works
+
+let Ci = Components.interfaces;
+let Cc = Components.classes;
+let Cu = Components.utils;
+let Cr = Components.results;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function test_find_app()
+{
+  var mwaUtils = Cc["@mozilla.org/widget/mac-web-app-utils;1"].
+  createInstance(Ci.nsIMacWebAppUtils);
+  let sig = "com.apple.TextEdit";
+
+  let path;
+  path = mwaUtils.pathForAppWithIdentifier(sig);
+  do_print("TextEdit path: " + path + "\n");
+  do_check_neq(path, "");
+}
+
+function test_dont_find_fake_app()
+{
+  var mwaUtils = Cc["@mozilla.org/widget/mac-web-app-utils;1"].
+  createInstance(Ci.nsIMacWebAppUtils);
+  let sig = "calliope.penitentiary.dramamine";
+
+  let path;
+  path = mwaUtils.pathForAppWithIdentifier(sig);
+  do_check_eq(path, "");
+}
+
+
+function run_test()
+{
+  test_find_app();
+  test_dont_find_fake_app();
+}
--- a/widget/tests/unit/xpcshell.ini
+++ b/widget/tests/unit/xpcshell.ini
@@ -1,5 +1,7 @@
 [DEFAULT]
 head = 
 tail = 
 
 [test_taskbar_jumplistitems.js]
+[test_macwebapputils.js]
+skip-if = os != "mac"