Bug 117233 - Implement nsIPrinterEnumeratorX r=jwatt
authorErik Nordin <nordzilla@mozilla.com>
Thu, 28 May 2020 15:36:44 +0000
changeset 596603 faf8e8097d2351b57063ad15b75d54c6ce32b24d
parent 596602 0f1e35bee5748fc5d8c5f2043d32c16ed261c99b
child 596604 adb3e43858403fab834a714418784e11c1c1b6e0
push id13186
push userffxbld-merge
push dateMon, 01 Jun 2020 09:52:46 +0000
treeherdermozilla-beta@3e7c70a1e4a1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs117233
milestone78.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 117233 - Implement nsIPrinterEnumeratorX r=jwatt - Implement the nsPrinterEnumeratorX - Enable the contract @mozilla.org/gfx/printerenumerator;1 for macOS - Add test for default printer name. - Remove restrictions preventing some tests from running on macOS Differential Revision: https://phabricator.services.mozilla.com/D76356
layout/base/tests/chrome/chrome.ini
layout/base/tests/chrome/printpreview_bug396024_helper.xhtml
layout/base/tests/chrome/printpreview_bug482976_helper.xhtml
layout/base/tests/chrome/printpreview_helper.xhtml
layout/base/tests/chrome/test_default_printer_name.html
widget/cocoa/nsDeviceContextSpecX.h
widget/cocoa/nsDeviceContextSpecX.mm
widget/cocoa/nsWidgetFactory.mm
--- a/layout/base/tests/chrome/chrome.ini
+++ b/layout/base/tests/chrome/chrome.ini
@@ -51,16 +51,17 @@ support-files =
   bug1041200_frame.html
   bug1041200_window.html
 [test_chrome_content_integration.xhtml]
 [test_chrome_over_plugin.xhtml]
 support-files =
   chrome_over_plugin_window.xhtml
   chrome_over_plugin_window_frame.html
 [test_default_background.xhtml]
+[test_default_printer_name.html]
 [test_dialog_with_positioning.html]
 tags = openwindow
 [test_fixed_bg_scrolling_repaints.html]
 [test_leaf_layers_partition_browser_window.xhtml]
 skip-if = true # Bug 992311
 [test_prerendered_transforms.html]
 [test_printpreview.xhtml]
 skip-if = (os == "linux" && bits == 32) || (verify && (os == 'win')) # Disabled on Linux32 for bug 1278957
--- a/layout/base/tests/chrome/printpreview_bug396024_helper.xhtml
+++ b/layout/base/tests/chrome/printpreview_bug396024_helper.xhtml
@@ -57,25 +57,16 @@ function finish() {
 }
 
 function run()
 {
 /** Test for Bug 396024 **/
   var printService = Cc["@mozilla.org/gfx/printsettings-service;1"]
                        .getService(Ci.nsIPrintSettingsService);
 
-  try {
-    Cc["@mozilla.org/gfx/printerenumerator;1"]
-      .getService(Ci.nsIPrinterEnumerator);
-  } catch(e) {
-    todo(false, "Test skipped on MacOSX, as the print preview code doesn't work there");
-    finish();
-    return;
-  }
-
   if (printService.defaultPrinterName != '') {
     printpreview();
     ok(gWbp.doingPrintPreview, "Should be doing print preview");
     exitprintpreview();
     ok(!gWbp.doingPrintPreview, "Should not be doing print preview anymore1");
     printpreview();
     setTimeout(run2, 0)
   } else {
--- a/layout/base/tests/chrome/printpreview_bug482976_helper.xhtml
+++ b/layout/base/tests/chrome/printpreview_bug482976_helper.xhtml
@@ -19,17 +19,17 @@ var is = window.arguments[0].is;
 var ok = window.arguments[0].ok;
 var todo = window.arguments[0].todo;
 var SimpleTest = window.arguments[0].SimpleTest;
 var gWbp;
 function printpreview() {
   gWbp = frameElts[1].contentWindow.docShell.initOrReusePrintPreviewViewer();
   var listener = {
     onLocationChange: function(webProgress, request, location, flags) { },
-    onProgressChange: function(webProgress, request, curSelfProgress, 
+    onProgressChange: function(webProgress, request, curSelfProgress,
                                maxSelfProgress, curTotalProgress,
                                maxTotalProgress) { },
     onSecurityChange: function(webProgress, request, state) { },
     onStateChange: function(webProgress, request, stateFlags, status) { },
     onStatusChange: function(webProgress, request, status, message) { },
     onContentBlockingEvent: function(webProgress, request, event) { },
     QueryInterface: function(iid) {
       if (iid.equals(Ci.nsIWebProgessListener) ||
@@ -57,25 +57,16 @@ function finish() {
 }
 
 function run1()
 {
 /** Test for Bug 482976 **/
   var printService = Cc["@mozilla.org/gfx/printsettings-service;1"]
                        .getService(Ci.nsIPrintSettingsService);
 
-  try {
-    Cc["@mozilla.org/gfx/printerenumerator;1"]
-      .getService(Ci.nsIPrinterEnumerator);
-  } catch(e) {
-    todo(false, "Test skipped on MacOSX, as the print preview code doesn't work there");
-    finish();
-    return;
-  }
-
   if (printService.defaultPrinterName != '') {
     printpreview();
     ok(gWbp.doingPrintPreview, "Should be doing print preview");
     exitprintpreview();
     ok(!gWbp.doingPrintPreview, "Should not be doing print preview anymore");
   } else {
     todo(false, "No printer seems installed on this machine, that is necessary for this test");
   }
--- a/layout/base/tests/chrome/printpreview_helper.xhtml
+++ b/layout/base/tests/chrome/printpreview_helper.xhtml
@@ -77,25 +77,16 @@ function finish() {
   window.close();
 }
 
 function runTests()
 {
   var printService = Cc["@mozilla.org/gfx/printsettings-service;1"]
                        .getService(Ci.nsIPrintSettingsService);
 
-  try {
-    Cc["@mozilla.org/gfx/printerenumerator;1"]
-      .getService(Ci.nsIPrinterEnumerator);
-  } catch(e) {
-    todo(false, "Test skipped on MacOSX, as the print preview code doesn't work there");
-    finish();
-    return;
-  }
-
   if (printService.defaultPrinterName != '') {
     startTest1();
   } else {
     todo(false, "No printer seems installed on this machine, that is necessary for this test");
     finish();
   }
 }
 
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/chrome/test_default_printer_name.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+</head>
+<body onload="run()">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+function getDefaultPrinterName() {
+  try {
+      let PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(
+        Ci.nsIPrintSettingsService
+      );
+
+      return PSSVC.defaultPrinterName;
+    } catch (e) {
+      Cu.reportError(e);
+    }
+
+    return null;
+}
+
+function run() {
+  isnot(getDefaultPrinterName(), null);
+  SimpleTest.finish();
+}
+
+</script>
+</body>
+</html>
--- a/widget/cocoa/nsDeviceContextSpecX.h
+++ b/widget/cocoa/nsDeviceContextSpecX.h
@@ -2,16 +2,17 @@
 /* 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 nsDeviceContextSpecX_h_
 #define nsDeviceContextSpecX_h_
 
 #include "nsIDeviceContextSpec.h"
+#include "nsIPrinterEnumerator.h"
 
 #include "nsCOMPtr.h"
 
 #include <ApplicationServices/ApplicationServices.h>
 
 class nsDeviceContextSpecX : public nsIDeviceContextSpec {
  public:
   NS_DECL_ISUPPORTS
@@ -40,9 +41,22 @@ class nsDeviceContextSpecX : public nsID
   PMPrintSettings mPrintSettings;  // print settings.
 #ifdef MOZ_ENABLE_SKIA_PDF
   nsCOMPtr<nsIFile>
       mTempFile;  // file "print" output is generated to if printing via PDF
   bool mPrintViaSkPDF;
 #endif
 };
 
+//----------------------------------------------------------------------
+// nsPrinterErnumeratorX
+
+class nsPrinterEnumeratorX final : public nsIPrinterEnumerator {
+ public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIPRINTERENUMERATOR
+  nsPrinterEnumeratorX() = default;
+
+ private:
+  ~nsPrinterEnumeratorX() = default;
+};
+
 #endif  // nsDeviceContextSpecX_h_
--- a/widget/cocoa/nsDeviceContextSpecX.mm
+++ b/widget/cocoa/nsDeviceContextSpecX.mm
@@ -1,41 +1,139 @@
 /* -*- Mode: C++; tab-width: 4; 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/. */
 
 #include "nsDeviceContextSpecX.h"
 
-#include "mozilla/gfx/PrintTargetCG.h"
+#import <Cocoa/Cocoa.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <unistd.h>
+
 #ifdef MOZ_ENABLE_SKIA_PDF
 #  include "mozilla/gfx/PrintTargetSkPDF.h"
 #endif
+#include "mozilla/gfx/PrintTargetCG.h"
+#include "mozilla/Logging.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/RefPtr.h"
+
+#include "nsCocoaUtils.h"
 #include "nsCRT.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsILocalFileMac.h"
-#include <unistd.h>
-
+#include "nsPrintSettingsX.h"
 #include "nsQueryObject.h"
-#include "nsPrintSettingsX.h"
+#include "nsStringEnumerator.h"
+#include "prenv.h"
 
 // This must be the last include:
 #include "nsObjCExceptions.h"
 
 using namespace mozilla;
 using mozilla::gfx::IntSize;
 using mozilla::gfx::PrintTarget;
 using mozilla::gfx::PrintTargetCG;
 #ifdef MOZ_ENABLE_SKIA_PDF
 using mozilla::gfx::PrintTargetSkPDF;
 #endif
 using mozilla::gfx::SurfaceFormat;
 
+static LazyLogModule sDeviceContextSpecXLog("DeviceContextSpecX");
+// Macro to make lines shorter
+#define DO_PR_DEBUG_LOG(x) MOZ_LOG(sDeviceContextSpecXLog, mozilla::LogLevel::Debug, x)
+
+//----------------------------------------------------------------------
+// nsPrinterErnumeratorX
+
+NS_IMPL_ISUPPORTS(nsPrinterEnumeratorX, nsIPrinterEnumerator);
+
+NS_IMETHODIMP nsPrinterEnumeratorX::GetPrinterNameList(nsIStringEnumerator** aPrinterNameList) {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+  NS_ENSURE_ARG_POINTER(aPrinterNameList);
+  *aPrinterNameList = nullptr;
+
+  NSArray<NSString*>* printerNames = [NSPrinter printerNames];
+  size_t nameCount = [printerNames count];
+  nsTArray<nsString>* printerNameList = new nsTArray<nsString>(nameCount);
+
+  for (size_t i = 0; i < nameCount; ++i) {
+    NSString* name = [printerNames objectAtIndex:i];
+    nsAutoString nsName;
+    nsCocoaUtils::GetStringForNSString(name, nsName);
+    printerNameList->AppendElement(nsName);
+  }
+
+  // If there are no printers available after all checks, return an error
+  if (printerNameList->IsEmpty()) {
+    delete printerNameList;
+    return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
+  }
+
+  return NS_NewAdoptingStringEnumerator(aPrinterNameList, printerNameList);
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+NS_IMETHODIMP nsPrinterEnumeratorX::GetDefaultPrinterName(nsAString& aDefaultPrinterName) {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+  DO_PR_DEBUG_LOG(("nsPrinterEnumeratorX::GetDefaultPrinterName()\n"));
+
+  aDefaultPrinterName.Truncate();
+  NSArray<NSString*>* printerNames = [NSPrinter printerNames];
+  if ([printerNames count] > 0) {
+    NSString* name = [printerNames objectAtIndex:0];
+    nsCocoaUtils::GetStringForNSString(name, aDefaultPrinterName);
+  }
+
+  DO_PR_DEBUG_LOG(("GetDefaultPrinterName(): default printer='%s'.\n",
+                   NS_ConvertUTF16toUTF8(aDefaultPrinterName).get()));
+  return NS_OK;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+NS_IMETHODIMP
+nsPrinterEnumeratorX::InitPrintSettingsFromPrinter(const nsAString& aPrinterName,
+                                                   nsIPrintSettings* aPrintSettings) {
+  DO_PR_DEBUG_LOG(("nsPrinterEnumeratorX::InitPrintSettingsFromPrinter()"));
+
+  NS_ENSURE_ARG_POINTER(aPrintSettings);
+
+  // Set a default file name.
+  nsAutoString filename;
+  nsresult rv = aPrintSettings->GetToFileName(filename);
+  if (NS_FAILED(rv) || filename.IsEmpty()) {
+    const char* path = PR_GetEnv("PWD");
+    if (!path) {
+      path = PR_GetEnv("HOME");
+    }
+
+    if (path) {
+      CopyUTF8toUTF16(MakeStringSpan(path), filename);
+      filename.AppendLiteral("/mozilla.pdf");
+    } else {
+      filename.AssignLiteral("mozilla.pdf");
+    }
+
+    DO_PR_DEBUG_LOG(("Setting default filename to '%s'\n", NS_ConvertUTF16toUTF8(filename).get()));
+    aPrintSettings->SetToFileName(filename);
+  }
+
+  aPrintSettings->SetIsInitializedFromPrinter(true);
+
+  return NS_OK;
+}
+
+//----------------------------------------------------------------------
+// nsDeviceContentSpecX
+
 nsDeviceContextSpecX::nsDeviceContextSpecX()
     : mPrintSession(NULL),
       mPageFormat(kPMNoPageFormat),
       mPrintSettings(kPMNoPrintSettings)
 #ifdef MOZ_ENABLE_SKIA_PDF
       ,
       mPrintViaSkPDF(false)
 #endif
--- a/widget/cocoa/nsWidgetFactory.mm
+++ b/widget/cocoa/nsWidgetFactory.mm
@@ -62,16 +62,17 @@ static nsresult nsClipboardConstructor(n
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePicker)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsColorPicker)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDragService)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceContextSpecX)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsPrinterEnumeratorX)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSettingsServiceX, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintDialogServiceX, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSession, Init)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIdleServiceX, nsIdleServiceX::GetInstance)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ScreenManager, ScreenManager::GetAddRefedSingleton)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(OSXNotificationCenter, Init)
 
 #include "nsMenuBarX.h"
@@ -112,16 +113,17 @@ NS_DEFINE_NAMED_CID(NS_APPSHELL_CID);
 NS_DEFINE_NAMED_CID(NS_SOUND_CID);
 NS_DEFINE_NAMED_CID(NS_TRANSFERABLE_CID);
 NS_DEFINE_NAMED_CID(NS_HTMLFORMATCONVERTER_CID);
 NS_DEFINE_NAMED_CID(NS_CLIPBOARD_CID);
 NS_DEFINE_NAMED_CID(NS_CLIPBOARDHELPER_CID);
 NS_DEFINE_NAMED_CID(NS_DRAGSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID);
 NS_DEFINE_NAMED_CID(NS_DEVICE_CONTEXT_SPEC_CID);
+NS_DEFINE_NAMED_CID(NS_PRINTER_ENUMERATOR_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_SYSTEMALERTSSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_NATIVEMENUSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_MACDOCKSUPPORT_CID);
 NS_DEFINE_NAMED_CID(NS_MACFINDERPROGRESS_CID);
@@ -143,16 +145,17 @@ static const mozilla::Module::CIDEntry k
     {&kNS_HTMLFORMATCONVERTER_CID, false, NULL, nsHTMLFormatConverterConstructor},
     {&kNS_CLIPBOARD_CID, false, NULL, nsClipboardConstructor, mozilla::Module::MAIN_PROCESS_ONLY},
     {&kNS_CLIPBOARDHELPER_CID, false, NULL, nsClipboardHelperConstructor},
     {&kNS_DRAGSERVICE_CID, false, NULL, nsDragServiceConstructor,
      mozilla::Module::MAIN_PROCESS_ONLY},
     {&kNS_SCREENMANAGER_CID, false, NULL, ScreenManagerConstructor,
      mozilla::Module::MAIN_PROCESS_ONLY},
     {&kNS_DEVICE_CONTEXT_SPEC_CID, false, NULL, nsDeviceContextSpecXConstructor},
+    {&kNS_PRINTER_ENUMERATOR_CID, false, NULL, nsPrinterEnumeratorXConstructor},
     {&kNS_PRINTSESSION_CID, false, NULL, nsPrintSessionConstructor},
     {&kNS_PRINTSETTINGSSERVICE_CID, false, NULL, nsPrintSettingsServiceXConstructor},
     {&kNS_PRINTDIALOGSERVICE_CID, false, NULL, nsPrintDialogServiceXConstructor},
     {&kNS_IDLE_SERVICE_CID, false, NULL, nsIdleServiceXConstructor},
     {&kNS_SYSTEMALERTSSERVICE_CID, false, NULL, OSXNotificationCenterConstructor},
     {&kNS_NATIVEMENUSERVICE_CID, false, NULL, nsNativeMenuServiceXConstructor},
     {&kNS_MACDOCKSUPPORT_CID, false, NULL, nsMacDockSupportConstructor},
     {&kNS_MACFINDERPROGRESS_CID, false, NULL, nsMacFinderProgressConstructor},
@@ -173,16 +176,17 @@ static const mozilla::Module::ContractID
     {"@mozilla.org/widget/transferable;1", &kNS_TRANSFERABLE_CID},
     {"@mozilla.org/widget/htmlformatconverter;1", &kNS_HTMLFORMATCONVERTER_CID},
     {"@mozilla.org/widget/clipboard;1", &kNS_CLIPBOARD_CID, mozilla::Module::MAIN_PROCESS_ONLY},
     {"@mozilla.org/widget/clipboardhelper;1", &kNS_CLIPBOARDHELPER_CID},
     {"@mozilla.org/widget/dragservice;1", &kNS_DRAGSERVICE_CID, mozilla::Module::MAIN_PROCESS_ONLY},
     {"@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID,
      mozilla::Module::MAIN_PROCESS_ONLY},
     {"@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID},
+    {"@mozilla.org/gfx/printerenumerator;1", &kNS_PRINTER_ENUMERATOR_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/system-alerts-service;1", &kNS_SYSTEMALERTSSERVICE_CID},
     {"@mozilla.org/widget/nativemenuservice;1", &kNS_NATIVEMENUSERVICE_CID},
     {"@mozilla.org/widget/macdocksupport;1", &kNS_MACDOCKSUPPORT_CID},
     {"@mozilla.org/widget/macfinderprogress;1", &kNS_MACFINDERPROGRESS_CID},