changeset 14445:d648900019b6

8241829: Cleanup the code for PrinterJob on windows Reviewed-by: prr, aivanov
author serb
date Wed, 08 Apr 2020 02:03:56 -0700
parents d2eea93d8c65
children 172c73eb036d
files src/windows/classes/sun/print/PrintServiceLookupProvider.java src/windows/native/sun/windows/WPrinterJob.cpp test/java/awt/print/PrintServicesSecurityManager.java
diffstat 3 files changed, 80 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/src/windows/classes/sun/print/PrintServiceLookupProvider.java	Tue Dec 29 19:02:56 2020 +0000
+++ b/src/windows/classes/sun/print/PrintServiceLookupProvider.java	Wed Apr 08 02:03:56 2020 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,10 @@
 
 package sun.print;
 
-import java.security.AccessController;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
+
 import javax.print.DocFlavor;
 import javax.print.MultiDocPrintService;
 import javax.print.PrintService;
@@ -120,13 +120,6 @@
         if (win32PrintLUS == null) {
             win32PrintLUS = this;
 
-            String osName = AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction("os.name"));
-            // There's no capability for Win98 to refresh printers.
-            // See "OpenPrinter" for more info.
-            if (osName != null && osName.startsWith("Windows 98")) {
-                return;
-            }
             // start the local printer listener thread
             Thread thr = new PrinterChangeListener();
             thr.setDaemon(true);
@@ -353,28 +346,9 @@
         return defaultPrintService;
     }
 
-    class PrinterChangeListener extends Thread {
-        long chgObj;
-        PrinterChangeListener() {
-            chgObj = notifyFirstPrinterChange(null);
-        }
-
+    private final class PrinterChangeListener extends Thread {
         public void run() {
-            if (chgObj != -1) {
-                while (true) {
-                    // wait for configuration to change
-                    if (notifyPrinterChange(chgObj) != 0) {
-                        try {
-                            refreshServices();
-                        } catch (SecurityException se) {
-                            break;
-                        }
-                    } else {
-                        notifyClosePrinterChange(chgObj);
-                        break;
-                    }
-                }
-            }
+            notifyLocalPrinterChange(); // busy loop in the native code
         }
     }
 
@@ -441,8 +415,6 @@
 
     private native String getDefaultPrinterName();
     private native String[] getAllPrinterNames();
-    private native long notifyFirstPrinterChange(String printer);
-    private native void notifyClosePrinterChange(long chgObj);
-    private native int notifyPrinterChange(long chgObj);
+    private native void notifyLocalPrinterChange();
     private native String[] getRemotePrintersNames();
 }
--- a/src/windows/native/sun/windows/WPrinterJob.cpp	Tue Dec 29 19:02:56 2020 +0000
+++ b/src/windows/native/sun/windows/WPrinterJob.cpp	Wed Apr 08 02:03:56 2020 -0700
@@ -185,28 +185,20 @@
     return getPrinterNames(env, PRINTER_ENUM_CONNECTIONS);
 }
 
-
-JNIEXPORT jlong JNICALL
-Java_sun_print_PrintServiceLookupProvider_notifyFirstPrinterChange(JNIEnv *env,
-                                                                jobject peer,
-                                                                jstring printer) {
-    HANDLE hPrinter;
+JNIEXPORT void JNICALL
+Java_sun_print_PrintServiceLookupProvider_notifyLocalPrinterChange(JNIEnv *env,
+                                                                   jobject peer)
+{
+    jclass cls = env->GetObjectClass(peer);
+    CHECK_NULL(cls);
+    jmethodID refresh = env->GetMethodID(cls, "refreshServices", "()V");
+    CHECK_NULL(refresh);
 
-    LPTSTR printerName = NULL;
-    if (printer != NULL) {
-        printerName = (LPTSTR)JNU_GetStringPlatformChars(env,
-                                                         printer,
-                                                         NULL);
-        JNU_ReleaseStringPlatformChars(env, printer, printerName);
+    HANDLE hPrinter;
+    LPTSTR printerName = NULL; // NULL indicates the local printer server
+    if (!::OpenPrinter(printerName, &hPrinter, NULL)) {
+        return;
     }
-
-    // printerName - "Win NT/2K/XP: If NULL, it indicates the local printer
-    // server" - MSDN.   Win9x : OpenPrinter returns 0.
-    BOOL ret = OpenPrinter(printerName, &hPrinter, NULL);
-    if (!ret) {
-      return (jlong)-1;
-    }
-
     // PRINTER_CHANGE_PRINTER = PRINTER_CHANGE_ADD_PRINTER |
     //                          PRINTER_CHANGE_SET_PRINTER |
     //                          PRINTER_CHANGE_DELETE_PRINTER |
@@ -215,32 +207,23 @@
                                                        PRINTER_CHANGE_PRINTER,
                                                        0,
                                                        NULL);
-    return (chgObj == INVALID_HANDLE_VALUE) ? (jlong)-1 : (jlong)chgObj;
-}
-
-
-
-JNIEXPORT void JNICALL
-Java_sun_print_PrintServiceLookupProvider_notifyClosePrinterChange(JNIEnv *env,
-                                                                jobject peer,
-                                                                jlong chgObject) {
-    FindClosePrinterChangeNotification((HANDLE)chgObject);
-}
-
+    if (chgObj != INVALID_HANDLE_VALUE) {
+        BOOL keepMonitoring;
+        do {
+            keepMonitoring = FALSE;
+            if (WaitForSingleObject(chgObj, INFINITE) == WAIT_OBJECT_0) {
+                DWORD dwChange;
+                keepMonitoring = FindNextPrinterChangeNotification(
+                                                 chgObj, &dwChange, NULL, NULL);
+            }
+            if (keepMonitoring) {
+                env->CallVoidMethod(peer, refresh);
+            }
+        } while (keepMonitoring && !env->ExceptionCheck());
 
-JNIEXPORT jint JNICALL
-Java_sun_print_PrintServiceLookupProvider_notifyPrinterChange(JNIEnv *env,
-                                                           jobject peer,
-                                                           jlong chgObject) {
-    DWORD dwChange;
-
-    DWORD ret = WaitForSingleObject((HANDLE)chgObject, INFINITE);
-    if (ret == WAIT_OBJECT_0) {
-        return(FindNextPrinterChangeNotification((HANDLE)chgObject,
-                                                  &dwChange, NULL, NULL));
-    } else {
-        return 0;
+        FindClosePrinterChangeNotification(chgObj);
     }
+    ::ClosePrinter(hPrinter);
 }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/print/PrintServicesSecurityManager.java	Wed Apr 08 02:03:56 2020 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Arrays;
+
+import javax.print.PrintServiceLookup;
+
+/*
+ * @test
+ * @bug 8241829
+ */
+public final class PrintServicesSecurityManager {
+
+    public static void main(String[] args) throws InterruptedException {
+        System.setSecurityManager(new SecurityManager());
+        test();
+        Thread.sleep(3000); // to be sure the pooling thread started
+        test();
+    }
+
+    private static void test() {
+        Object[] services = PrintServiceLookup.lookupPrintServices(null, null);
+        if (services.length != 0) {
+            System.err.println("services = " + Arrays.toString(services));
+            throw new RuntimeException("The array of Services must be empty");
+        }
+    }
+}